Compare commits

...

285 Commits

Author SHA1 Message Date
f00ac79c91 Bump version / misc
Fix regenallroads
Add schematic y_offset
Change visit/list for multi-owner plots
Fix updater (pre-1.7.10)
2016-03-02 17:42:04 +11:00
109715e0d7 Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2016-03-02 06:59:05 +11:00
8bf3ceac6f Changes
Plot auto clear confirmation
Add timediff to keep flag
Add expired parameter to list cmd
Fixes some compatibility issues
2016-03-02 06:56:50 +11:00
106c3c5cb4 Temporary fix for 1.9 2016-03-01 14:17:29 +11:00
0bbfd0f49a Begin 1.9 NMS updates 2016-02-29 20:44:58 -05:00
9596544f97 Cleanup Code
I also updated the build.gradle and pom to 1.9 bukkit
2016-02-29 20:13:18 -05:00
5079361fbf Fix negation issue. 2016-02-29 11:50:04 -05:00
b0a3f70cbd Updater now uses GitHub Releases and API 2016-02-29 11:15:51 -05:00
841809b93d Various
Closes #906
Add command confirmation for setowner
Require confirmation delayed by 1 tick
2016-03-01 02:01:52 +11:00
43b7a7aba8 Fixes #910 2016-02-29 15:12:20 +11:00
8906577699 Merge pull request #909 from zombachu/master
Implements the ice-melt flag
2016-02-29 14:08:31 +11:00
224caee56e Implements the ice-melt flag 2016-02-28 15:41:32 -10:00
5c4178b1dd Fixes
Fixes #905
Fixes auto claim limit
2016-02-29 04:09:09 +11:00
911bef974a Stop spectating before being kicked when denied.
Fixes #886
2016-02-27 20:11:18 -05:00
7d340b58b4 Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2016-02-27 15:49:45 -05:00
ce8775414a Fix some logic 2016-02-28 07:04:57 +11:00
5da8700f7f Force Core to use Java 7 2016-02-27 13:41:49 -05:00
01710e3ddb Fixes
Notify core of all world loading regardless of generator
Optimize plot area fetching
Fix plot delete not deleting the plot until restart
Fix plot unclaim not removing the owner on any cached plots
Change gradle output directory
Fix plotme conversion sometimes not copying over the floor/main blocks
2016-02-27 21:07:42 +11:00
7d8893b5d7 Fixes #900 2016-02-27 17:07:15 +11:00
7a97c69d4f Fix bed explosion in hell biome when flag not present 2016-02-27 16:44:29 +11:00
1a80b344b9 replace jar with one that's less broken 2016-02-27 16:09:55 +11:00
afe6c5fd69 Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2016-02-27 16:05:56 +11:00
f68042bc11 Fixes
Fixes unlink failing if a parameter is provided
Fix plot unlinking not resetting the road biome
Fixes #888
2016-02-27 16:05:21 +11:00
ac77c755d0 Add plot middle permission to plugin.yml 2016-02-26 19:10:59 -05:00
c7870b617c Gradle / maven
Fix archive names (includes project/module name + version)
Generate MD5 hash alongside jar
Improve build time
- asynchronous building
- enable daemon
- change scope of a few statements
- skip building of 3 jars
Add filtering to the plugin.yml (maven/gradle)
Bump version to 3.3.0 in pom
2016-02-26 23:55:21 +11:00
f921db937a Fix plot music duplication when moving between plots in a merged plot 2016-02-26 17:43:49 +11:00
4669f31658 Fixes
Fixes hybridplotworld rotation for stairs
Fixes hybridplotworld skipping non-rotatable blocks on swapped sideroad
schem
Fixes schematic generation using wrong height
Fixes debug spam printed when using download cmd
Fixes pagination having page number instead of total list items
Fixes plot area list page being off by 1
Remove compatibility for a spigot 1.8.0 bug where getting the world name
during initialization crashes the server.
Fixes type 1,2 plot worlds not being fetchable if there are more than 8
plot worlds loaded.
2016-02-26 17:29:31 +11:00
c8ddcd7f54 Fixes
Fix plot cluster command NPE
Fix path iterator (for Plot.getAllCorners()) being off by 1
2016-02-26 04:17:23 +11:00
fb2e949711 Fix rotation for stairs metadata (range:8-15) 2016-02-26 01:21:30 +11:00
7659884e73 Fixes
Fixes #868
Fixes #778
Fixes attributes passing wrong key to persistent meta
Fixes blob compatibility with JDBC driver for persistent meta
Fix stackoverflow from countEntities under certain circumstances
Minor cleanup
2016-02-26 01:17:07 +11:00
efae2c2e63 Finished several core parts of the sponge port
Mass block changes / chunk packet sending
AsyncWorldEdit (buggy)
Fixed world ground cover layers being generated
Fixed tab completion
Fixed plot title color
Fixed worlds unloading when no players are present
Fixed falling blocks not falling where they should
Fixed console color
Fixed chunk regeneration on full plot worlds
Other stuff
2016-02-25 20:13:07 +11:00
d3465b7bde Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2016-02-24 05:12:20 +11:00
f73a542b04 Tab completion, fix SpongeUtil.getWorld 2016-02-24 05:12:07 +11:00
6f3485c87d Hard-code version into plugin.yml 2016-02-23 13:08:20 -05:00
bf85ba5833 No they aren't 2016-02-24 04:20:40 +11:00
8a2c44759f Chunk regeneration 2016-02-24 04:04:23 +11:00
882394987b Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2016-02-24 03:08:12 +11:00
7a217b2f08 a wild pom appears
fork/pr if you don't like how I've done it
2016-02-24 03:07:49 +11:00
b94e816c55 Sponge changes. 2016-02-23 09:55:40 -05:00
87ee693a49 Fix small Gradle things. 2016-02-22 23:30:49 -05:00
1768651782 Merge pull request #874 from IntellectualSites/gradle
Move from Maven to Gradle
2016-02-22 23:16:03 -05:00
b69e31129d Updated Gradle 2016-02-22 23:11:40 -05:00
7b15d50674 Add PS.get().isPlotWorld() and MainUtil.getPlotID( Location );
@_Cory_
2016-02-23 05:46:57 +11:00
f996b1d95d Using ReflectionUtils simplifies stuff? 2016-02-23 05:38:28 +11:00
14eb3279c0 Revert version 2016-02-23 05:31:35 +11:00
ced342f14e Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2016-02-22 17:24:30 +11:00
f5ff82c8cc Sponge / Other
Fix area teleportation for type 0,1 worlds
Add blockstate<>id/data resolving for sponge
Finish world generation for sponge
Add chat color for sponge
Fix economy support for sponge
Fix sponge event system
Other stuff
2016-02-22 17:20:22 +11:00
b255c5db47 Cleanup and Fixes
Fixed StackOverflowError caused by c83378a
2016-02-21 23:29:33 -05:00
ca5e7f4564 Cleanup 2016-02-20 23:07:04 -05:00
ef5846f688 Cleanup 2016-02-20 16:50:10 -05:00
36ebd1983d Use UTF-8 2016-02-19 15:51:04 -05:00
eabb5f3180 Fix remaining compile errors
Note: Sponge version needs a number of things implemented before it will
actually run
2016-02-20 06:55:49 +11:00
92b3ddb0ac Finish debugpaste for sponge 2016-02-20 06:13:41 +11:00
6caa7ee757 Merge remote-tracking branch 'origin/master' 2016-02-20 06:05:47 +11:00
de1328e78c Update some sponge classes
Update world generator
Replace some broken code with TODO
FIxed a few errors
Started on block placement
Other sponge stuff
2016-02-20 05:52:26 +11:00
60629db042 Feature / Fix
Add trim regen argument @manuelgu /plot trim <world> true
Add grant check other + console usage
Finish abstracting world generation to prepare for sponge port
Fix economy hook
Add ban as alias for deny
Remove some redundant code
2016-02-20 05:42:06 +11:00
a055a90979 Add target folder 2016-02-20 05:16:20 +11:00
302fe0c2c8 Fix SpongeEventUtil 2016-02-19 12:50:38 -05:00
660cd1b870 Fix more Sponge Classes 2016-02-19 12:45:43 -05:00
63cd7c8b97 Fix SpongeEconHandler 2016-02-19 12:18:15 -05:00
c719d548d0 Fix SpongePlayer 2016-02-19 12:07:09 -05:00
536b011ea0 Fix SpongePlayer 2016-02-19 12:01:24 -05:00
2a2c85a642 Fix Typos and Various little things. 2016-02-19 11:55:00 -05:00
c592790f68 Merge pull request #881 from manuelgu/patch-3
Update Issue Template
2016-02-18 16:35:13 -05:00
81f57b5675 Update Issue Template
More proper description
2016-02-18 22:19:50 +01:00
3fadbf3358 Lol okay this is better 2016-02-18 22:05:09 +01:00
26e73af35c Rename CONTRIBUTING.md to .github/CONTRIBUTING.md 2016-02-18 21:59:55 +01:00
4a9d063576 Create ISSUE_TEMPLATE.md 2016-02-18 21:58:48 +01:00
411a74eefa Fix compatibility with old type 2 plotworld cluster data 2016-02-17 23:38:36 +11:00
11064ec814 Fixes #878 2016-02-17 14:49:10 +11:00
af9f5b5f44 Fixes
Fix #879 stackoverflow in PlotHandler (from
fde845e1d8)
Fix getCorners returning last value twice
Fix getConnectedPlots only returning adjacent connections (from
c83378a91b)
other tweaks
2016-02-17 14:46:25 +11:00
3b58e19b25 Merge pull request #869 from manuelgu/patch-2
Fix mismatch of brackets
2016-02-15 20:11:51 +11:00
eda4575dd6 Tweaks / Fixes
Fixed id being renamed to type in
fde845e1d8
Fixes #870
2016-02-15 16:25:37 +11:00
87d4ecb1f1 Fix TextualCompontent Class that broke in last commit 2016-02-13 20:05:30 -05:00
fde845e1d8 Refractoring and Cleanup
Optimized some of the code where possible and removed some magic numbers as well.
2016-02-13 20:01:18 -05:00
0a4e42e1a7 Fix mismatch of brackets
This could potentially cause problems because the permission check is not correct
2016-02-13 18:45:35 +01:00
a1eec4eb0c Fixes #853 2016-02-13 22:19:07 +11:00
e2ba9fb8e9 Fixes / Additions / Tweaks
Fixed #867
Fixes some issues with partial plot areas
Added /plot area regen
2016-02-13 22:01:22 +11:00
03aec43f5d Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/main/java/com/intellectualcrafters/plot/commands/Condense.java
#	src/main/java/com/intellectualcrafters/plot/commands/Deny.java
#	src/main/java/com/intellectualcrafters/plot/commands/Save.java
#	src/main/java/com/intellectualcrafters/plot/commands/list.java
#	src/main/java/com/intellectualcrafters/plot/database/SQLManager.java
2016-02-13 04:32:43 +11:00
b87a886345 Additions / Fixes
Added `/plot area` command for area info and management
Fixed typo for player meta table preventing the plugin from starting /
cleanup
Moved pagination from list to subcommand
Removed default PlotArea values
Added pair and tuple RunnableVal classes
Tweak pom so that it actually compiles
More command categories
Removed unclaim and limit command
Fixed a few issues with the 2d mapping of plot areas
2016-02-13 03:25:04 +11:00
ccbd4f60c2 Refractoring and Cleanup 2016-02-10 20:37:21 -05:00
ca73addc88 Updated this via browser, sorry if something broke xD 2016-02-10 22:23:49 +01:00
893c2b3088 Remove bukkit classes from core 2016-02-11 06:43:47 +11:00
50f891a974 this 2016-02-11 06:02:54 +11:00
c83378a91b Refactor / Cleanup / Optimizations 2016-02-11 05:59:51 +11:00
085f621f0f Merge pull request #856 from MattBDev/spelling
Spelling Corrections
2016-02-07 16:37:40 +01:00
8d6b412dc8 Spelling Corrections 2016-02-04 18:45:50 -05:00
692ad5db81 Update README.md 2016-01-24 10:50:53 +01:00
a69f7162f1 Merge pull request #839 from manuelgu/patch-1
Update README.md
2016-01-23 23:19:54 +01:00
ee6d9d2d5c Merge pull request #840 from aaomidi/master
Make plugin compatible with DeluxeChat
2016-01-23 23:13:48 +01:00
7cc8e8bfb5 Merge pull request #1 from aaomidi/aaomidi-patch-1
Update PlayerEvents.java
2016-01-24 00:33:50 +03:30
5f74aa8ab8 Update PlayerEvents.java
Allow other plugins to manage chat.

Makes plugin work with DeluxeChat plugin.
2016-01-24 00:32:43 +03:30
df27b1ddd8 Update README.md 2016-01-23 20:18:48 +01:00
d8998ac715 Yeah, no. This needs fixing. 2016-01-23 19:21:17 +01:00
948b5c5789 Merge pull request #837 from manuelgu/patch-2
Push target folder as it is needed for /p update
2016-01-21 12:07:47 +01:00
8a34276eb5 Push target folder as it is needed for /p update 2016-01-21 11:23:48 +01:00
e8d2e9fd12 Merge pull request #830 from sgdc3/master
Clean the project [WIP]
2016-01-20 20:11:27 +01:00
e3b5ca14be Disable spongeapi dependency 2016-01-20 13:34:33 +01:00
a872bd0f61 Shade libs 2016-01-20 13:30:03 +01:00
efeecd423e Merge pull request #1 from IntellectualSites/master
Up
2016-01-20 12:44:33 +01:00
51d2e37853 Clean the project 2016-01-20 12:40:04 +01:00
ddfa4fe6af Merge pull request #831 from manuelgu/patch-1
Fix notify-enter message being sent to wrong person
2016-01-19 15:53:32 +01:00
165d9b6258 Fix #829 2016-01-19 14:12:42 +01:00
0f3d6b63f5 I was tired, okay. 2016-01-18 23:07:10 +01:00
adfd0e6674 Should fix #824 2016-01-17 13:19:14 +01:00
faa9c10364 Add fixes to shizzle 2016-01-16 18:32:00 +01:00
830a5111f4 Add plot grants for /plot auto 2016-01-16 17:48:49 +01:00
cf6ca67ce7 Add persistent meta, and added plot grants 2016-01-16 17:07:42 +01:00
dc22514809 Implements #752 and gives credits to manuelgu :) 2016-01-16 13:14:18 +01:00
c6f087fd50 Fixes #774 and allows for similar features in the future 2016-01-16 13:03:51 +01:00
ad1272b0e5 Minor fixes
Fixes #797
Fixes #794
2016-01-12 23:13:47 +11:00
af79100f7d Update README / pom / merge with 8629c4a6f5
closes #809
2016-01-11 07:00:56 +11:00
00b6158181 Use plot metadata to track tasks 2015-12-20 06:40:42 +11:00
f70e2248e7 Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2015-12-20 06:30:16 +11:00
cf517d5be0 Cleanup 2015-12-20 06:30:06 +11:00
9b990faa47 Merge pull request #792 from manuelgu/master
fix typo
2015-12-20 06:15:46 +11:00
2aab349c4b Merge pull request #796 from MattBDev/spongeFix
Fix Sponge Generator
2015-12-20 06:15:33 +11:00
dc799ecc26 Merge pull request #795 from MattBDev/cleanup
Fixes javadoc errors
2015-12-20 06:15:28 +11:00
d65bd7a704 Fixes javadoc errors
It does not improve upon the existing documentation but instead removes all broken documentation and has minor changes to some existing. More work will need to be done later to documentation.
2015-12-19 12:23:32 -05:00
8ddecce75b Fix Sponge Generator 2015-12-19 12:05:00 -05:00
5e33c175ab Typo in "ice-melt" flag
The flag doesnt seem to be used anyways, so not much of a deal.
2015-12-17 18:11:50 +01:00
abc2681f97 fix typo 2015-12-17 18:07:57 +01:00
ce387333d2 Plot deny / kick bypass
Fixes #777
2015-12-17 17:51:12 +11:00
c32cfc62fa Various
Fix sethome/home for mega plots
Minor tweaks
2015-12-16 16:38:53 +11:00
dd4a1faede Fixes #772 2015-12-15 03:32:59 +11:00
163ccc9eae Fixes
Fixes #783
Fixes #780
2015-12-15 03:15:30 +11:00
35589dcc5f Fixe
Fixes #753
2015-12-04 20:00:30 +11:00
c72edc40f0 Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2015-12-03 02:43:05 +11:00
f102b2b448 Fixes
Fixes #768 (Plot clearing with given plot id)
2015-12-03 02:42:50 +11:00
2cdb279528 Merge pull request #769 from XxCoolGamesxX/patch-1
Added Spanish Translation
2015-12-03 02:42:21 +11:00
08e3876b01 Added Spanish Translation
We translation in Spanish so the people can read it.

Thank to my team of Mega Planet (www.megaplanet.net).
2015-12-02 00:09:22 +01:00
1b7a58b720 Merge pull request #766 from swan201/master
Update Korean Translation File
2015-11-30 13:55:33 +11:00
b71b0aa46e Update Korean Translation 2015-11-30 05:59:14 +09:00
dcefa95278 Merge pull request #1 from IntellectualSites/master
Merge
2015-11-30 05:56:40 +09:00
60406812ee Merge pull request #764 from manuelgu/patch-3
remove website link
2015-11-29 21:42:20 +01:00
82ccca8f63 . 2015-11-30 02:24:01 +11:00
1fcb4ea705 remove website link 2015-11-29 12:49:20 +01:00
9118f111e4 Fixes
fixes #763
2015-11-29 19:21:32 +11:00
c2b781da98 Deny negative ratings 2015-11-28 23:27:36 +11:00
1ee13ff96c Fix commands being case sensitive. 2015-11-28 22:56:12 +11:00
d1ac355e58 Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared
# Conflicts:
#	src/main/java/com/intellectualcrafters/plot/config/C.java
2015-11-28 22:49:42 +11:00
94b0fbb266 Stuff
Fixes #748
Fixes #759
2015-11-28 22:46:10 +11:00
ef327434cd Merge pull request #751 from Aaron1011/update-spongeapi
git@github.com:Aaron1011/PlotSquared.gitUpdate for SpongeAPI changes
2015-11-26 14:45:39 +11:00
e0e2756b95 Update for SpongeAPI changes 2015-11-25 22:40:22 -05:00
7d494fef16 Merge pull request #749 from manuelgu/patch-1
fixed importing
2015-11-25 23:12:00 +01:00
7bbf549221 fixed importing
related to #733
2015-11-25 23:05:08 +01:00
a0c93bb3e7 Merge pull request #747 from manuelgu/patch-2
formatting in german file
2015-11-25 22:51:18 +01:00
46989faee6 Merge pull request #746 from manuelgu/patch-1
formatting
2015-11-25 22:51:06 +01:00
f80a833689 formatting in german file 2015-11-25 22:30:35 +01:00
eba75363c8 formatting 2015-11-25 22:29:20 +01:00
cc10c52230 Update README.md 2015-11-25 22:04:16 +01:00
8a1dfe46c9 Merge pull request #733 from manuelgu/patch-1
fix color formatting
2015-11-22 22:01:28 +01:00
d56b4da7c2 fix color formatting 2015-11-22 12:04:24 +01:00
7db30590c6 Fixes
Fixes #701
Fixes set components for other plots
Add setowner uuid.
Probably some other stuff
2015-11-20 17:28:33 +11:00
7ed693dfc8 Fix populator random seed / algorithm differing from chunk generator 2015-11-18 16:42:19 +11:00
1e1259b81d Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2015-11-18 10:39:52 +11:00
452efc4b08 Fix
Fixes #724
Fixes flag remove for non list based flags when player lacks permission.
2015-11-18 10:39:44 +11:00
9adb256ff6 Merge pull request #719 from manuelgu/patch-2
remove not needed message
2015-11-16 12:31:36 +11:00
c34f41b150 remove not needed message
Since calculating the TPS Values has been removed, the message is no longer in use
2015-11-15 18:58:12 +01:00
a8140f8cb0 Check if no metadata is set. 2015-11-15 20:52:32 +11:00
27d1ba810b Default, default flags 2015-11-15 19:56:32 +11:00
9218147aa0 Whoops. 2015-11-15 13:51:28 +11:00
ab5e826fe8 Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2015-11-15 13:31:01 +11:00
93a7b2cace Potential fixes
Fixes #712
Fixes #711
Fixes #707
Fixes #705
Fixes #702
Fixes #698
Fixes #697
Fixes #694
Fixes #717
2015-11-15 13:30:52 +11:00
8a9f4d2598 Merge pull request #706 from swan201/master
Add Korean Translate File
2015-11-07 12:48:40 +11:00
ebf0fee3ac Add Korean Translate File
First Korean Translate
2015-11-07 10:44:31 +09:00
c32edfe0ee . 2015-11-04 04:52:44 +11:00
008e35d307 Fixes #700 2015-11-04 02:39:42 +11:00
215ed04754 Minor tweaks 2015-10-29 23:13:10 +11:00
95feaed870 Changes
ratings api
misc-cap
other tweakes
2015-10-27 10:57:34 +11:00
2e79f3d0f8 Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared 2015-10-26 18:21:35 +11:00
2afc16de7a Schematics / tweak message 2015-10-26 18:18:31 +11:00
bc836201d5 Merge pull request #687 from manuelgu/patch-1
Update german.yml
2015-10-26 18:05:49 +11:00
24406a250b Update german.yml
tweaked some german translations and also added untranslated things
2015-10-24 22:52:50 +02:00
e20e4a8650 Fixes
Closes #683
Potential fix for sign issue
Potential fix for templates not working
Incremented version number.
2015-10-24 21:55:34 +11:00
6650ea2a4c Fixes #681 2015-10-21 18:31:14 +11:00
a6dad4fb7b Fixes #682 2015-10-21 16:34:15 +11:00
fa442f5903 Fixes
closes #679
closes #676
2015-10-19 17:27:51 +11:00
f509252646 Fix plot cluster command from console. 2015-10-18 23:31:35 +11:00
f75822f56c Fixed no argument feedback for move/copy/swap 2015-10-18 23:18:45 +11:00
26c0e3fa85 Fixes
- Fix sign lines on claim not updating
- Fix plot tier removing for merged plots
- Fix stair rotation for id=24
- Fix interaction to have a lower priority than chestshop (why doesn't
chestshop use monitor priority?)
2015-10-18 22:20:12 +11:00
c595b69c3a fixed world loading. 2015-10-18 01:25:17 +11:00
54655c1a72 Fixes
closes #673
closes #668
closes #672
closes #664 (hopefully)
2015-10-17 22:50:52 +11:00
50c6753bf4 Fixes
close #659
close #662
close #665
close #638
2015-10-10 18:07:26 +11:00
8e874ddeb0 Fix PlotMe conversion 2015-10-07 18:42:50 +11:00
0c4b703510 Fix for sponge 2015-10-07 17:33:33 +11:00
74a967b535 Fixes container contents spillage on plot clear
TODO: fix component setting for ^
2015-10-05 01:40:46 +11:00
f2431c869f fixes
Fixes #657
Fixes #656
Fixes #653
Fixes #652
Fixes #585
2015-10-05 00:59:43 +11:00
9d77b422df Fixes #651 #618 2015-09-30 16:11:44 +10:00
3bd4895676 Fix structure growth on roads (from big trees on plot edges)
Possible unresolved issue (TODO)
- big tree growth on plot edges with 0 road width
2015-09-29 19:50:05 +10:00
b9bb9f5674 Fixes #646 2015-09-29 16:29:28 +10:00
c3eb44f51c un-cache base plot on merge 2015-09-27 19:42:22 +10:00
0273a4614b Load plots with no settings. 2015-09-27 18:37:33 +10:00
bb32507841 Fix plot unclaiming for non hybrid classic generators. 2015-09-27 17:20:59 +10:00
3336d302ac Potential fixes 2015-09-27 16:43:11 +10:00
a93e8fac38 Some fixes
Fixes #641
Closes #640 (need to also update Plot2Dynmap)
Fixes #637 (duplicate)
Fixes #636
Fixes #634
2015-09-26 18:05:27 +10:00
d42ef3cf63 restructure a couple things. 2015-09-22 23:23:28 +10:00
c948b18239 Forward plot home to plot visit 2015-09-15 14:56:23 +10:00
9682e2914c Recover from world gen error. 2015-09-15 00:35:28 +10:00
b524d5fcfe minor conversion tweaks + fix plot sorting with empty worlds. 2015-09-15 00:24:25 +10:00
4002ed4de1 Fixes #613 2015-09-14 20:43:51 +10:00
064a555ba1 Fix cluster create with non ascending coords 2015-09-14 18:39:07 +10:00
91bfcd0deb Fixes #620 2015-09-14 18:20:25 +10:00
5137b23357 Hows this? 2015-09-13 14:04:31 +10:00
1cccdd9d4d Merge branch 'master' of https://github.com/IntellectualSites/PlotSquared
Conflicts:
	src/main/java/com/intellectualcrafters/plot/IPlotMain.java
	src/main/java/com/intellectualcrafters/plot/commands/Trim.java
	src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java
	src/main/java/com/plotsquared/bukkit/BukkitMain.java
	src/main/java/com/plotsquared/bukkit/util/BukkitChunkManager.java
	src/main/java/com/plotsquared/sponge/SpongeMain.java
	src/main/java/com/plotsquared/sponge/util/SpongeChunkManager.java
2015-09-13 13:46:45 +10:00
c163446f7e Fix plot clear event not being called. 2015-09-13 13:33:18 +10:00
052019bb35 default to offline-mode uuid if owner isn't valid. 2015-09-13 13:30:28 +10:00
a6535d3b7b Forward plot set flag to the flag command. 2015-09-13 01:26:35 +10:00
1c28a72f9c WE unregistration + home/visit sorting + format
- WorldEdit listener unregistration for external masking/extent/async
worldedit management. (wink)
- Use the same listing for home and visit as previous behavior was
confusing.
2015-09-13 01:19:39 +10:00
c386f33df8 cleanup 2015-09-11 20:09:22 +10:00
063a369d8d Merge pull request #615 from MinelinkNetwork/fix-trimming
Fix trimming for worlds in non-standard directories
2015-09-11 08:52:30 +10:00
629ff443f3 Fix trimming for worlds in non-standard directories 2015-09-09 22:34:41 -07:00
37a8861fa0 Temporary fix for sponge toggles. 2015-09-07 22:31:48 +10:00
66730794d6 Fixes for sponge + minor tweaks for spigot
- Updated to sponge 591
- Added optional WorldEdit restriction
- several fixes (including greeting/farewell flag)
2015-09-07 22:17:48 +10:00
2b3b947143 Fix plot entry/leave for sponge. 2015-09-06 11:53:56 +10:00
ea146dcf91 Fix plot chat, chatspy + add comment spying 2015-09-06 10:33:11 +10:00
e704784570 Try this version, otherwise maybe downgrade? 2015-09-05 20:45:31 +10:00
1e386d274e add jars 2015-09-05 20:21:29 +10:00
a71d5a134b Fix rating when no categories are configured 2015-09-05 20:17:39 +10:00
e3cb59f362 Lazy UUID conversion 2015-09-05 20:07:59 +10:00
8606319340 Fix world caching + block interaction
Fixes #608
2015-09-05 11:35:43 +10:00
4cc4196487 jars 2015-09-03 23:37:19 +10:00
c707a7baa2 Remove spectator from flag pack 2015-09-03 23:34:52 +10:00
4e321d2b27 Here you go. 2015-09-03 22:40:36 +10:00
dfc32741fa Export negative coord blocks with BO3 if not part of normal plot component 2015-09-03 15:57:12 +10:00
574ca7a180 Call plot leave on quit 2015-09-03 15:48:36 +10:00
afef79ea66 Some changes
Fixes #605
Possibly #604
Other minor tweaks
2015-09-03 15:45:25 +10:00
3a29022d19 Add command queue option + fix nearest target 2015-09-01 21:33:45 +10:00
fcb7c23380 Latest jars 2015-09-01 15:46:56 +10:00
ea6d5778c8 Added chat spy toggle 2015-09-01 15:09:46 +10:00
6006b0e011 Add world parameter to EconHandler permission checks
Fixes #595
2015-09-01 14:02:37 +10:00
f22874970f Fix side location + fix brushtool mask 2015-09-01 10:23:46 +10:00
6671fd7e6d Fixes #582 2015-09-01 09:55:14 +10:00
29da0da8bb Fixes #577 2015-09-01 08:51:51 +10:00
9accbd5ea7 Decrease intensity of fastmode clearing 2015-09-01 07:31:53 +10:00
80b2c6b792 Merge pull request #589 from Maescool/master
Fixing plotme converter for some installations
2015-08-31 07:05:25 +10:00
a63110f303 Fixing plotme converter for some installations
-Making sure the uuid is checked when it's ownerId
-Checking if there are uuid's for denied/allowed, then use them if those are not in the cache
2015-08-30 16:23:05 +02:00
4027e84a0a Fixed boat interaction 2015-08-30 16:24:53 +10:00
0ba838b16b Minor tweaks
- SBQ unsanitized input
- plotme conversion tweaks
- schematic default output directory
- increment version number
2015-08-30 16:19:35 +10:00
3662b05da8 Fixes #584 2015-08-29 18:47:56 +10:00
fb0b50218d Ignore invalid tool 2015-08-29 12:25:13 +10:00
75fbf67dca Fix async worldedit masks 2015-08-29 06:56:02 +10:00
0dbb1887d5 Prevent teleporting to invalid coordinates 2015-08-28 16:36:26 +10:00
1e8bdb17f8 Per player plot cluster limits 2015-08-28 16:28:55 +10:00
22997ac089 Some work on plot clusters 2015-08-28 12:37:01 +10:00
ad94637c2a Fix inbox deletion perm 2015-08-28 09:53:35 +10:00
552ace359a Feedback for failed uploads + fix plot list done 2015-08-28 09:51:59 +10:00
ac27a7f37a Fix automerge.js 2015-08-28 09:51:05 +10:00
fcf2400798 Fix lighting updates for chunks not sent to players 2015-08-28 09:50:57 +10:00
5acd9c5143 Download requires done 2015-08-28 09:50:44 +10:00
56d50bd9e1 Fix masking extent + process non plot worlds 2015-08-28 08:33:32 +10:00
5b44e39bec documentation + fix toggles for admins 2015-08-26 16:44:50 +10:00
3229705012 Offline uuid from flat file. 2015-08-26 14:21:48 +10:00
1872e147cb WE delayed command execution + fix SBQ notify 2015-08-26 12:02:00 +10:00
dc37465c8a Forgot to push this 2015-08-26 08:35:32 +10:00
b2f8238f5d fix undo 2015-08-25 12:23:10 +10:00
2b187f2066 3.1.6 2015-08-25 10:51:33 +10:00
ee17457403 v3.1.5 2015-08-25 09:13:13 +10:00
6ca6880917 New features + fixes
Fixed a very specific case of IC world not loading with multiverse every
second startup
Fixed chunks not being sent for plot clearing (although it was being
sent for other thing) Fixes #554
Added fast experimental sudo-async worldedit processor
2015-08-25 09:01:45 +10:00
0e8ae9e6e4 WE tweak / Fix teleport event 2015-08-25 05:56:22 +10:00
3164838e05 Experimental allow plot clearing on mega plots 2015-08-25 03:07:09 +10:00
c7f5e3061d Retain trusted / helpers / denied when merging
fixes #533
2015-08-25 02:52:02 +10:00
8c245b4f21 Optional bo3 tags 2015-08-25 02:33:28 +10:00
68df5b1930 Fixed interactive chat colors + added interactive pages to sponge. 2015-08-25 02:28:32 +10:00
83d0b8cebb Revert some plot chat changes.
- Having chat for that plotworld will force it on all players without
the bypass permission
- Not having it will require the player to opt into plot chat
2015-08-25 00:35:37 +10:00
3bc3b51a27 Fix plot automerging 2015-08-25 00:19:50 +10:00
f2d56ec231 Plot merge limits 2015-08-25 00:00:29 +10:00
66f73374ac Tweak block interaction flags 2015-08-24 04:31:33 +10:00
d427ba3152 Fix auto-trim 2015-08-24 04:09:57 +10:00
79b16b8040 ChunkProcessor auto trim and chunk unloading
- The auto trim drastically reduces the cost of players exploring on
speed 10, as it prevents chunks of unowned plots from saving to disk
when the chunk is unloaded
- It is recommended to disable world auto saving, or also enable the
chunk processor GC, as otherwise minecraft will also save chunks as they
are loaded.
2015-08-24 03:29:59 +10:00
e228c00d87 Increment version 2015-08-24 00:18:31 +10:00
bd86caa818 Fixed fallback plotme conversion 2015-08-24 00:17:17 +10:00
d52e9b4c8c Minor fixes 2015-08-23 22:04:52 +10:00
dbdd207390 Merge pull request #576 from confuser/master
Fixed bukkit plot chat
2015-08-23 22:01:35 +10:00
316a4e0484 Fixed plot chat using meta instead of attributes
Pass message into setFormat and setMessage correctly
this avoids % symbols in player messages causing exceptions

Fixed #571
2015-08-23 12:00:52 +01:00
b5fbc6629f Fixed compiliation issue 2015-08-23 11:36:41 +01:00
a1be218580 Merge pull request #568 from LaxWasHere/patch-1
cannot into spelling
2015-08-22 17:47:08 +10:00
Lax
373044c928 cannot into spelling 2015-08-21 21:12:16 -07:00
83b1be8944 revert this 2015-08-21 19:24:20 +10:00
2185384746 . 2015-08-21 14:53:53 +10:00
b063494955 Redstone, chunk sending, reload fix, chunk unloader,
- Added redstone disabler when no players are in the plot
- Fixed chunk sending leaving ghost blocks
- Fixed reloading not populating new values
- Added chunk unloader to chunk processor (decreases memory usage)
2015-08-21 04:54:42 +10:00
ae7eed8a5b . 2015-08-20 21:54:04 +10:00
5f8505e698 Fix permission checking 2015-08-20 21:51:26 +10:00
75f189aae8 Fix auto updating. 2015-08-20 20:48:48 +10:00
d0605b9b55 Fixes
Fixes #556
Fixes #540
Fixed plot analysis being slow
Fixed auto updating
2015-08-20 14:56:25 +10:00
535 changed files with 47718 additions and 42767 deletions

2
.github/CONTRIBUTING.md vendored Normal file
View File

@ -0,0 +1,2 @@
### Bugs
Please provide a `/plot debugpaste` if you are reporting a bug.

12
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,12 @@
# Bug report template (clear for feature request)
**Debug paste link**:
**Description of the problem:**
**How to replicate**:
Make sure you've completed the following steps (put X inside of brackets):
- [ ] Include `/plot debugpaste`
- [ ] Made sure there aren't duplicates of this report [(Use Search)](https://github.com/IntellectualSites/PlotSquared/issues)
- [ ] Made sure you're using an updated version of PlotSquared
- [ ] Made sure the bug/error isn't caused by any other plugin

72
.gitignore vendored
View File

@ -1,9 +1,17 @@
### Ignore script files
*.sh
### Others ###
*.bat
*.cmd
*.sh
*.prefs
Sponge/build
Core/build
Bukkit/build
### Maven template
target/
### Maven ###
/target/lib
/target/maven-archiver
/target/classes
/target/maven-status
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
@ -14,8 +22,23 @@ buildNumber.properties
.mvn/timing.properties
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
*.iml
@ -27,6 +50,7 @@ buildNumber.properties
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# .idea/shelf
# Sensitive or high-churn files:
# .idea/dataSources.ids
@ -38,6 +62,7 @@ buildNumber.properties
# Gradle:
# .idea/gradle.xml
# .idea/libraries
.gradle
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
@ -61,23 +86,12 @@ atlassian-ide-plugin.xml
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### NetBeans template
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml
.nb-gradle/
### Eclipse template
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
@ -115,20 +129,6 @@ local.properties
# TeXlipse plugin
.texlipse
### Java template
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
*.zip
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# STS (Spring Tool Suite)
.springBeans
/target/

35
Bukkit/build.gradle Normal file
View File

@ -0,0 +1,35 @@
dependencies {
compile project(':Core')
compile 'org.bukkit:bukkit:1.9-R0.1-SNAPSHOT'
compile 'net.milkbowl.vault:VaultAPI:1.5'
}
sourceCompatibility = 1.7
targetCompatibility = 1.7
processResources {
from('src/main/resources') {
include 'plugin.yml'
expand(
name: project.parent.name,
version: project.parent.version
)
}
}
apply plugin: 'com.github.johnrengelman.shadow'
// We only want the shadow jar produced
jar.enabled = false
shadowJar {
dependencies {
include(dependency(':Core'))
}
archiveName = "${parent.name}-${project.name}-${parent.version}.jar"
destinationDir = file '../target'
}
shadowJar.doLast {
task ->
ant.checksum file: task.archivePath
}
build.dependsOn(shadowJar);

View File

@ -21,17 +21,6 @@
package com.intellectualcrafters.plot.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import com.intellectualcrafters.configuration.file.YamlConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.commands.MainCommand;
@ -40,26 +29,34 @@ import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.flag.AbstractFlag;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotManager;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.PlotWorld;
import com.intellectualcrafters.plot.util.BlockManager;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.ClusterManager;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import com.plotsquared.bukkit.util.BukkitSetBlockManager;
import com.plotsquared.bukkit.util.BukkitUtil;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* PlotSquared API
*
* @author Citymonstret
* @author Empire92
* @version API 2.0
*
*/
@ -78,27 +75,27 @@ public class PlotAPI {
* @deprecated Use new PlotAPI() instead
*/
@Deprecated
public PlotAPI(final JavaPlugin plugin) {
}
public PlotAPI(final JavaPlugin plugin) {}
/**
* @param plugin Plugin used to access this method
* @see PS
*
* @deprecated Use this class if you just want to do a few simple things.<br>
* - It will remain stable for future versions of the plugin
* - The PlotPlayer and Plot class should be considered relatively safe
* - For more advanced/intensive tasks you should consider using other classes
*
* @throws com.intellectualcrafters.plot.util.PlotSquaredException if the program fails to fetch the PlotSquared
* instance
* @see com.intellectualcrafters.plot.PS
*
* @deprecated Use new PlotAPI() instead
*/
public PlotAPI() {
}
@Deprecated
public PlotAPI() {}
/**
* Get all plots
*
* @return all plots
*
* @see com.intellectualcrafters.plot.PS#getPlots()
* @see PS#getPlots()
*/
public Set<Plot> getAllPlots() {
return PS.get().getPlots();
@ -118,21 +115,17 @@ public class PlotAPI {
/**
* Add a plot world
*
* @param world World Name
* @param plotWorld Plot World Object
* @param manager World Manager
*
* @see com.intellectualcrafters.plot.PS#addPlotWorld(String, com.intellectualcrafters.plot.object.PlotWorld,
* com.intellectualcrafters.plot.object.PlotManager)
* @param plotArea Plot World Object
* @see PS#addPlotArea(PlotArea)
*/
public void addPlotWorld(final String world, final PlotWorld plotWorld, final PlotManager manager) {
PS.get().addPlotWorld(world, plotWorld, manager);
public void addPlotArea(final PlotArea plotArea) {
PS.get().addPlotArea(plotArea);
}
/**
* @return main configuration
*
* @see com.intellectualcrafters.plot.PS#config
* @see PS#config
*/
public YamlConfiguration getConfig() {
return PS.get().config;
@ -141,7 +134,7 @@ public class PlotAPI {
/**
* @return storage configuration
*
* @see com.intellectualcrafters.plot.PS#storage
* @see PS#storage
*/
public YamlConfiguration getStorage() {
return PS.get().storage;
@ -153,7 +146,7 @@ public class PlotAPI {
*
* @return PlotSquared PlotSquared Main Class
*
* @see com.intellectualcrafters.plot.PS
* @see PS
*/
public PS getMain() {
return PS.get();
@ -176,25 +169,11 @@ public class PlotAPI {
}
/**
* BlockManager class contains useful methods relating to blocks.
*
* @return BlockManager
*
* @see com.intellectualcrafters.plot.util.BlockManager
* Get the block/biome set queue
* @return SetQueue.IMP
*/
public BlockManager getBlockManager() {
return BlockManager.manager;
}
/**
* BukkitSetBlockManager class contains useful methods relating to bukkit blocks.
*
* @return BukkitSetBlockManager
*
* @see com.plotsquared.bukkit.util.BukkitSetBlockManager
*/
public BukkitSetBlockManager getBukkitBlockManager() {
return BukkitSetBlockManager.setBlockManager;
public SetQueue getSetQueue() {
return SetQueue.IMP;
}
/**
@ -221,26 +200,13 @@ public class PlotAPI {
return new FlagManager();
}
/**
* Do not use this. Instead use ClusterManager.[method] in your code.
* - Plot cluster related stuff
*
* @return ClusterManager
*
* @see com.intellectualcrafters.plot.util.ClusterManager
*/
@Deprecated
public ClusterManager getClusterManager() {
return new ClusterManager();
}
/**
* Do not use this. Instead use MainUtil.[method] in your code.
* - Basic plot management stuff
*
* @return MainUtil
*
* @see com.intellectualcrafters.plot.util.MainUtil
* @see MainUtil
*/
@Deprecated
public MainUtil getMainUtil() {
@ -257,13 +223,13 @@ public class PlotAPI {
*/
@Deprecated
public String[] getPermissions() {
ArrayList<String> perms = new ArrayList<>();
for (C c : C.values()) {
if (c.getCat().equals("static.permissions")) {
final ArrayList<String> perms = new ArrayList<>();
for (final C c : C.values()) {
if ("static.permissions".equals(c.getCat())) {
perms.add(c.s());
}
}
return perms.toArray(new String[0]);
return perms.toArray(new String[perms.size()]);
}
/**
@ -297,10 +263,21 @@ public class PlotAPI {
* @return PlotManager
*
* @see com.intellectualcrafters.plot.object.PlotManager
* @see PS#getPlotManager(String)
* @see PS#getPlotManager(Plot)
*/
@Deprecated
public PlotManager getPlotManager(final World world) {
return PS.get().getPlotManager(world.getName());
if (world == null) {
return null;
}
return getPlotManager(world.getName());
}
public Set<PlotArea> getPlotAreas(World world) {
if (world == null) {
return new HashSet<>();
}
return PS.get().getPlotAreas(world.getName());
}
/**
@ -311,40 +288,67 @@ public class PlotAPI {
*
* @return PlotManager
*
* @see PS#getPlotManager(String)
* @see PS#getPlotManager(Plot)
* @see com.intellectualcrafters.plot.object.PlotManager
*/
@Deprecated
public PlotManager getPlotManager(final String world) {
return PS.get().getPlotManager(world);
Set<PlotArea> areas = PS.get().getPlotAreas(world);
switch (areas.size()) {
case 0:
return null;
case 1:
return areas.iterator().next().manager;
default:
PS.debug("PlotAPI#getPlotManager(org.bukkit.World) is deprecated and doesn't support multi plot area worlds.");
return null;
}
}
/**
* Get the settings for a world (settings bundled in PlotWorld class) - You will need to downcast for the specific
* settings a Generator has. e.g. DefaultPlotWorld class implements PlotWorld
* Get the settings for a world (settings bundled in PlotArea class) - You will need to downcast for the specific
* settings a Generator has. e.g. DefaultPlotWorld class implements PlotArea
*
* @param world (to get settings of)
*
* @return PlotWorld class for that world ! will return null if not a plot world world
* @return PlotArea class for that world ! will return null if not a plot world world
*
* @see PS#getPlotWorld(String)
* @see com.intellectualcrafters.plot.object.PlotWorld
* @see #getPlotAreas(World)
* @see com.intellectualcrafters.plot.object.PlotArea
*/
public PlotWorld getWorldSettings(final World world) {
return PS.get().getPlotWorld(world.getName());
@Deprecated
public PlotArea getWorldSettings(final World world) {
if (world == null) {
return null;
}
return getWorldSettings(world.getName());
}
/**
* Get the settings for a world (settings bundled in PlotWorld class)
* Get the settings for a world (settings bundled in PlotArea class)
*
* @param world (to get settings of)
*
* @return PlotWorld class for that world ! will return null if not a plot world world
* @return PlotArea class for that world ! will return null if not a plot world world
*
* @see PS#getPlotWorld(String)
* @see com.intellectualcrafters.plot.object.PlotWorld
* @see PS#getPlotArea(String, String)
* @see com.intellectualcrafters.plot.object.PlotArea
*/
public PlotWorld getWorldSettings(final String world) {
return PS.get().getPlotWorld(world);
@Deprecated
public PlotArea getWorldSettings(final String world) {
if (world == null) {
return null;
}
Set<PlotArea> areas = PS.get().getPlotAreas(world);
switch (areas.size()) {
case 0:
return null;
case 1:
return areas.iterator().next();
default:
PS.debug("PlotAPI#getWorldSettings(org.bukkit.World) is deprecated and doesn't support multi plot area worlds.");
return null;
}
}
/**
@ -353,7 +357,7 @@ public class PlotAPI {
* @param player Player that will receive the message
* @param c (Caption)
*
* @see com.intellectualcrafters.plot.util.MainUtil#sendMessage(PlotPlayer, C, String...)
* @see MainUtil#sendMessage(PlotPlayer, C, String...)
* com.intellectualcrafters.plot.config.C, String...)
*/
public void sendMessage(final Player player, final C c) {
@ -366,7 +370,7 @@ public class PlotAPI {
* @param player Player that will receive the message
* @param string The message
*
* @see com.intellectualcrafters.plot.util.MainUtil#sendMessage(PlotPlayer, String)
* @see MainUtil#sendMessage(PlotPlayer, String)
*/
public void sendMessage(final Player player, final String string) {
MainUtil.sendMessage(BukkitUtil.getPlayer(player), string);
@ -377,10 +381,10 @@ public class PlotAPI {
*
* @param msg Message that should be sent to the console
*
* @see MainUtil#sendConsoleMessage(String)
* @see MainUtil#sendConsoleMessage(C, String...)
*/
public void sendConsoleMessage(final String msg) {
MainUtil.sendConsoleMessage(msg);
PS.log(msg);
}
/**
@ -428,11 +432,18 @@ public class PlotAPI {
*
* @return plot, null if ID is wrong
*
* @see MainUtil#getPlot(String, com.intellectualcrafters.plot.object.PlotId)
* @see com.intellectualcrafters.plot.object.Plot
* @see PlotArea#getPlot(PlotId)
*/
@Deprecated
public Plot getPlot(final World world, final int x, final int z) {
return MainUtil.getPlot(world.getName(), new PlotId(x, z));
if (world == null) {
return null;
}
PlotArea area = getWorldSettings(world);
if (area == null) {
return null;
}
return area.getPlot(new PlotId(x, z));
}
/**
@ -442,11 +453,13 @@ public class PlotAPI {
*
* @return plot if found, otherwise it creates a temporary plot-
*
* @see MainUtil#getPlot(com.intellectualcrafters.plot.object.Location)
* @see com.intellectualcrafters.plot.object.Plot
* @see Plot
*/
public Plot getPlot(final Location l) {
return MainUtil.getPlot(BukkitUtil.getLocation(l));
if (l == null) {
return null;
}
return BukkitUtil.getLocation(l).getPlot();
}
/**
@ -457,7 +470,7 @@ public class PlotAPI {
* @return plot if found, otherwise it creates a temporary plot
*
* @see #getPlot(org.bukkit.Location)
* @see com.intellectualcrafters.plot.object.Plot
* @see Plot
*/
public Plot getPlot(final Player player) {
return this.getPlot(player.getLocation());
@ -472,8 +485,9 @@ public class PlotAPI {
*
* @see #getPlots(World, Player, boolean)
*/
@Deprecated
public boolean hasPlot(final World world, final Player player) {
return (getPlots(world, player, true) != null) && (getPlots(world, player, true).length > 0);
return getPlots(world, player, true) != null && getPlots(world, player, true).length > 0;
}
/**
@ -481,18 +495,18 @@ public class PlotAPI {
*
* @param plr to search for
* @param just_owner should we just search for owner? Or with rights?
*
* @see com.intellectualcrafters.plot.object.Plot
*/
@Deprecated
public Plot[] getPlots(final World world, final Player plr, final boolean just_owner) {
final ArrayList<Plot> pPlots = new ArrayList<>();
for (final Plot plot : PS.get().getPlotsInWorld(world.getName())) {
UUID uuid = BukkitUtil.getPlayer(plr).getUUID();
for (final Plot plot : PS.get().getPlots(world.getName())) {
if (just_owner) {
if ((plot.owner != null) && (plot.owner.equals(UUIDHandler.getUUID(BukkitUtil.getPlayer(plr))))) {
if (plot.hasOwner() && plot.isOwner(uuid)) {
pPlots.add(plot);
}
} else {
if (plot.isAdded(UUIDHandler.getUUID(BukkitUtil.getPlayer(plr)))) {
if (plot.isAdded(uuid)) {
pPlots.add(plot);
}
}
@ -508,10 +522,14 @@ public class PlotAPI {
* @return Plot[] - array of plot objects in world
*
* @see PS#getPlots(String)
* @see com.intellectualcrafters.plot.object.Plot
* @see Plot
*/
@Deprecated
public Plot[] getPlots(final World world) {
Collection<Plot> plots = PS.get().getPlotsInWorld(world.getName());
if (world == null) {
return new Plot[0];
}
Collection<Plot> plots = PS.get().getPlots(world.getName());
return plots.toArray(new Plot[plots.size()]);
}
@ -520,11 +538,11 @@ public class PlotAPI {
*
* @return World[] - array of plot worlds
*
* @see com.intellectualcrafters.plot.PS#getPlotWorlds()
*/
@Deprecated
public String[] getPlotWorlds() {
Set<String> worlds = PS.get().getPlotWorlds();
return worlds.toArray(new String[worlds.size()]);
Set<String> plotWorldStrings = PS.get().getPlotWorldStrings();
return plotWorldStrings.toArray(new String[plotWorldStrings.size()]);
}
/**
@ -534,10 +552,11 @@ public class PlotAPI {
*
* @return boolean (if plot world or not)
*
* @see com.intellectualcrafters.plot.PS#isPlotWorld(String)
* @see PS#hasPlotArea(String)
*/
@Deprecated
public boolean isPlotWorld(final World world) {
return PS.get().isPlotWorld(world.getName());
return PS.get().hasPlotArea(world.getName());
}
/**
@ -547,16 +566,13 @@ public class PlotAPI {
*
* @return [0] = bottomLc, [1] = topLoc, [2] = home
*
* @see com.intellectualcrafters.plot.util.MainUtil#getPlotBottomLoc(String,
* com.intellectualcrafters.plot.object.PlotId)
* @see com.intellectualcrafters.plot.util.MainUtil#getPlotTopLoc(String,
* com.intellectualcrafters.plot.object.PlotId)
* @see com.intellectualcrafters.plot.util.MainUtil#getPlotHome(String,
* com.intellectualcrafters.plot.object.Plot)
* @see com.intellectualcrafters.plot.object.Plot
* @deprecated As merged plots may not have a rectangular shape
*
* @see Plot
*/
@Deprecated
public Location[] getLocations(final Plot p) {
return new Location[]{BukkitUtil.getLocation(MainUtil.getPlotBottomLoc(p.world, p.id)), BukkitUtil.getLocation(MainUtil.getPlotTopLoc(p.world, p.id)), BukkitUtil.getLocation(MainUtil.getPlotHome(p.world, p.id))};
return new Location[] { BukkitUtil.getLocation(p.getBottom()), BukkitUtil.getLocation(p.getTop()), BukkitUtil.getLocation(p.getHome()) };
}
/**
@ -566,12 +582,10 @@ public class PlotAPI {
*
* @return plot bottom location
*
* @see com.intellectualcrafters.plot.util.MainUtil#getPlotHome(String,
* com.intellectualcrafters.plot.object.Plot)
* @see com.intellectualcrafters.plot.object.Plot
* @see Plot
*/
public Location getHomeLocation(final Plot p) {
return BukkitUtil.getLocation(MainUtil.getPlotHome(p.world, p.id));
return BukkitUtil.getLocation(p.getHome());
}
/**
@ -581,12 +595,13 @@ public class PlotAPI {
*
* @return plot bottom location
*
* @see com.intellectualcrafters.plot.util.MainUtil#getPlotBottomLoc(String,
* com.intellectualcrafters.plot.object.PlotId)
* @see com.intellectualcrafters.plot.object.Plot
* @deprecated As merged plots may not have a rectangular shape
*
* @see Plot
*/
@Deprecated
public Location getBottomLocation(final Plot p) {
return BukkitUtil.getLocation(MainUtil.getPlotBottomLoc(p.world, p.id));
return BukkitUtil.getLocation(p.getBottom());
}
/**
@ -596,11 +611,13 @@ public class PlotAPI {
*
* @return plot top location
*
* @see MainUtil#getPlotTopLoc(String, com.intellectualcrafters.plot.object.PlotId)
* @see com.intellectualcrafters.plot.object.Plot
* @deprecated As merged plots may not have a rectangular shape
*
* @see Plot
*/
@Deprecated
public Location getTopLocation(final Plot p) {
return BukkitUtil.getLocation(MainUtil.getPlotTopLoc(p.world, p.id));
return BukkitUtil.getLocation(p.getTop());
}
/**
@ -610,10 +627,9 @@ public class PlotAPI {
*
* @return true if the player is in a plot, false if not-
*
* @see com.intellectualcrafters.plot.util.MainUtil#getPlot(com.intellectualcrafters.plot.object.Location)
*/
public boolean isInPlot(final Player player) {
return MainUtil.getPlot(BukkitUtil.getLocation(player)) != null;
return getPlot(player) != null;
}
/**
@ -636,7 +652,7 @@ public class PlotAPI {
*
* @return PlotSquared Class
*
* @see com.intellectualcrafters.plot.PS
* @see PS
*/
public PS getPlotSquared() {
return PS.get();
@ -650,10 +666,12 @@ public class PlotAPI {
*
* @return the number of plots the player has
*
* @see com.intellectualcrafters.plot.util.MainUtil#getPlayerPlotCount(String, PlotPlayer)
*/
public int getPlayerPlotCount(final World world, final Player player) {
return MainUtil.getPlayerPlotCount(world.getName(), BukkitUtil.getPlayer(player));
if (world == null) {
return 0;
}
return BukkitUtil.getPlayer(player).getPlotCount(world.getName());
}
/**
@ -664,12 +682,15 @@ public class PlotAPI {
*
* @return a set containing the players plots
*
* @see com.intellectualcrafters.plot.PS#getPlots(String, PlotPlayer)
* org.bukkit.entity.Player)
* @see com.intellectualcrafters.plot.object.Plot
* @see PS#getPlots(String, PlotPlayer)
*
* @see Plot
*/
public Set<Plot> getPlayerPlots(final World world, final Player player) {
return PS.get().getPlots(world.getName(), BukkitUtil.getPlayer(player));
if (world == null) {
return new HashSet<>();
}
return BukkitUtil.getPlayer(player).getPlots(world.getName());
}
/**
@ -681,44 +702,44 @@ public class PlotAPI {
*
*/
public int getAllowedPlots(final Player player) {
PlotPlayer pp = BukkitUtil.getPlayer(player);
return MainUtil.getAllowedPlots(pp);
final PlotPlayer pp = BukkitUtil.getPlayer(player);
return pp.getAllowedPlots();
}
/**
* Get the PlotPlayer for a player<br>
* - The PlotPlayer is usually cached and will provide useful functions relating to players
*
* @see PlotPlayer.wrap(Player|OfflinePlayer|String|UUID)
* @see PlotPlayer#wrap(Object)
*
* @param player
* @return
*/
public PlotPlayer wrapPlayer(Player player) {
public PlotPlayer wrapPlayer(final Player player) {
return PlotPlayer.wrap(player);
}
/**
* Get the PlotPlayer for a UUID (Please note that PlotSquared can be configured to provide different UUIDs than bukkit)
*
* @see PlotPlayer.wrap(UUID uuid)
* @see PlotPlayer#wrap(Object)
*
* @param player
* @param uuid
* @return
*/
public PlotPlayer wrapPlayer(UUID uuid) {
public PlotPlayer wrapPlayer(final UUID uuid) {
return PlotPlayer.wrap(uuid);
}
/**
* Get the PlotPlayer for a username
*
* @see PlotPlayer.wrap(String name)
* @see PlotPlayer#wrap(Object)
*
* @param player
* @return
*/
public PlotPlayer wrapPlayer(String player) {
public PlotPlayer wrapPlayer(final String player) {
return PlotPlayer.wrap(player);
}
@ -726,12 +747,12 @@ public class PlotAPI {
* Get the PlotPlayer for an offline player<br>
* Note that this will work if the player is offline, however not all functionality will work
*
* @see PlotPlayer.wrap(OfflinePlayer op)
* @see PlotPlayer#wrap(Object)
*
* @param player
* @return
*/
public PlotPlayer wrapPlayer(OfflinePlayer player) {
public PlotPlayer wrapPlayer(final OfflinePlayer player) {
return PlotPlayer.wrap(player);
}
}

View File

@ -0,0 +1,645 @@
package com.plotsquared.bukkit;
import com.intellectualcrafters.configuration.ConfigurationSection;
import com.intellectualcrafters.plot.IPlotMain;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.commands.MainCommand;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.ConfigurationNode;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
import com.intellectualcrafters.plot.generator.HybridGen;
import com.intellectualcrafters.plot.generator.HybridUtils;
import com.intellectualcrafters.plot.generator.IndependentPlotGenerator;
import com.intellectualcrafters.plot.object.*;
import com.intellectualcrafters.plot.util.*;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import com.plotsquared.bukkit.commands.DebugUUID;
import com.plotsquared.bukkit.database.plotme.ClassicPlotMeConnector;
import com.plotsquared.bukkit.database.plotme.LikePlotMeConverter;
import com.plotsquared.bukkit.database.plotme.PlotMeConnector_017;
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
import com.plotsquared.bukkit.listeners.*;
import com.plotsquared.bukkit.listeners.worldedit.WEListener;
import com.plotsquared.bukkit.titles.DefaultTitle;
import com.plotsquared.bukkit.util.*;
import com.plotsquared.bukkit.util.block.FastQueue_1_7;
import com.plotsquared.bukkit.util.block.FastQueue_1_8;
import com.plotsquared.bukkit.util.block.FastQueue_1_8_3;
import com.plotsquared.bukkit.util.block.SlowQueue;
import com.plotsquared.bukkit.uuid.*;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import org.bukkit.*;
import org.bukkit.Location;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
public class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
public static BukkitMain THIS;
public static WorldEditPlugin worldEdit;
private int[] version;
@Override
public int[] getServerVersion() {
if (version == null) {
try {
version = new int[3];
final String[] split = Bukkit.getBukkitVersion().split("-")[0].split("\\.");
version[0] = Integer.parseInt(split[0]);
version[1] = Integer.parseInt(split[1]);
if (split.length == 3) {
version[2] = Integer.parseInt(split[2]);
}
} catch (NumberFormatException e) {
e.printStackTrace();
PS.debug(StringMan.getString(Bukkit.getBukkitVersion()));
PS.debug(StringMan.getString(Bukkit.getBukkitVersion().split("-")[0].split("\\.")));
return new int[]{Integer.MAX_VALUE, 0, 0};
}
}
return version;
}
@Override
public void onEnable() {
THIS = this;
new PS(this, "Bukkit");
}
@Override
public void onDisable() {
PS.get().disable();
Bukkit.getScheduler().cancelTasks(this);
THIS = null;
}
@Override
public void log(String message) {
if (message == null) {
return;
}
if ((THIS != null) && (Bukkit.getServer().getConsoleSender() != null)) {
try {
message = C.color(message);
if (!Settings.CONSOLE_COLOR) {
message = ChatColor.stripColor(message);
}
Bukkit.getServer().getConsoleSender().sendMessage(message);
return;
} catch (final Throwable e) {}
}
System.out.println(ConsoleColors.fromString(message));
}
@Override
public void disable() {
if (THIS != null) {
onDisable();
}
}
@Override
public int[] getPluginVersion() {
final String[] split = getDescription().getVersion().split("\\.");
return new int[] { Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]) };
}
@Override
public void registerCommands() {
final BukkitCommand bcmd = new BukkitCommand();
final PluginCommand plotCommand = getCommand("plots");
plotCommand.setExecutor(bcmd);
plotCommand.setAliases(Arrays.asList("p", "ps", "plotme", "plot"));
plotCommand.setTabCompleter(bcmd);
MainCommand.getInstance().addCommand(new DebugUUID());
}
@Override
public File getDirectory() {
return getDataFolder();
}
@Override
public File getWorldContainer() {
return Bukkit.getWorldContainer();
}
@Override
public TaskManager getTaskManager() {
return new BukkitTaskManager();
}
@Override
public void runEntityTask() {
log(C.PREFIX.s() + "KillAllEntities started.");
TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
PS.get().foreachPlotArea(new RunnableVal<PlotArea>() {
@Override
public void run(PlotArea pw) {
World world = Bukkit.getWorld(pw.worldname);
try {
if (world == null) {
return;
}
List<Entity> entities = world.getEntities();
Iterator<Entity> iter = entities.iterator();
while (iter.hasNext()) {
Entity entity = iter.next();
switch (entity.getType()) {
case EGG:
case ENDER_CRYSTAL:
case COMPLEX_PART:
case FISHING_HOOK:
case ENDER_SIGNAL:
case EXPERIENCE_ORB:
case LEASH_HITCH:
case FIREWORK:
case WEATHER:
case LIGHTNING:
case WITHER_SKULL:
case UNKNOWN:
case PLAYER: {
// non moving / unremovable
continue;
}
case THROWN_EXP_BOTTLE:
case SPLASH_POTION:
case SNOWBALL:
case ENDER_PEARL:
case ARROW: {
// managed elsewhere | projectile
continue;
}
case ARMOR_STAND:
case ITEM_FRAME:
case PAINTING: {
// TEMPORARILY CLASSIFY AS VEHICLE
}
case MINECART:
case MINECART_CHEST:
case MINECART_COMMAND:
case MINECART_FURNACE:
case MINECART_HOPPER:
case MINECART_MOB_SPAWNER:
case MINECART_TNT:
case BOAT: {
if (!Settings.KILL_ROAD_VEHICLES) {
continue;
}
com.intellectualcrafters.plot.object.Location loc = BukkitUtil.getLocation(entity.getLocation());
Plot plot = loc.getPlot();
if (plot == null) {
if (loc.isPlotArea()) {
iter.remove();
entity.remove();
}
continue;
}
List<MetadataValue> meta = entity.getMetadata("plot");
if (meta.isEmpty()) {
continue;
}
Plot origin = (Plot) meta.get(0).value();
if (!plot.equals(origin.getBasePlot(false))) {
iter.remove();
entity.remove();
}
continue;
}
case SMALL_FIREBALL:
case FIREBALL:
case DROPPED_ITEM: {
// dropped item
continue;
}
case PRIMED_TNT:
case FALLING_BLOCK: {
// managed elsewhere
continue;
}
case BAT:
case BLAZE:
case CAVE_SPIDER:
case CHICKEN:
case COW:
case CREEPER:
case ENDERMAN:
case ENDERMITE:
case ENDER_DRAGON:
case GHAST:
case GIANT:
case GUARDIAN:
case HORSE:
case IRON_GOLEM:
case MAGMA_CUBE:
case MUSHROOM_COW:
case OCELOT:
case PIG:
case PIG_ZOMBIE:
case RABBIT:
case SHEEP:
case SILVERFISH:
case SKELETON:
case SLIME:
case SNOWMAN:
case SPIDER:
case SQUID:
case VILLAGER:
case WITCH:
case WITHER:
case WOLF:
case ZOMBIE:
default: {
if (!Settings.KILL_ROAD_MOBS) {
continue;
}
final Location loc = entity.getLocation();
if (BukkitUtil.getLocation(loc).isPlotRoad()) {
final Entity passenger = entity.getPassenger();
if (!(passenger instanceof Player)) {
if (entity.getMetadata("keep").isEmpty()) {
iter.remove();
entity.remove();
}
}
}
}
}
}
} catch (final Throwable e) {
e.printStackTrace();
}
}
});
}
}, 20);
}
@Override
final public ChunkGenerator getDefaultWorldGenerator(final String world, final String id) {
final HybridGen result = new HybridGen();
if (!PS.get().setupPlotWorld(world, id, result)) {
return null;
}
return (ChunkGenerator) result.specify();
}
@Override
public void registerPlayerEvents() {
getServer().getPluginManager().registerEvents(new PlayerEvents(), this);
if (PS.get().checkVersion(getServerVersion(), 1, 8, 0)) {
getServer().getPluginManager().registerEvents(new PlayerEvents_1_8(), this);
}
if (PS.get().checkVersion(getServerVersion(), 1, 8, 3)) {
getServer().getPluginManager().registerEvents(new PlayerEvents_1_8_3(), this);
}
}
@Override
public void registerInventoryEvents() {
// Part of PlayerEvents - can be moved if necessary
}
@Override
public void registerPlotPlusEvents() {
PlotPlusListener.startRunnable(this);
getServer().getPluginManager().registerEvents(new PlotPlusListener(), this);
}
@Override
public void registerForceFieldEvents() {
getServer().getPluginManager().registerEvents(new ForceFieldListener(), this);
}
@Override
public boolean initWorldEdit() {
if (getServer().getPluginManager().getPlugin("WorldEdit") != null) {
BukkitMain.worldEdit = (WorldEditPlugin) getServer().getPluginManager().getPlugin("WorldEdit");
final String version = BukkitMain.worldEdit.getDescription().getVersion();
if ((version != null) && version.startsWith("5.")) {
log("&cThis version of WorldEdit does not support PlotSquared.");
log("&cPlease use WorldEdit 6+ for masking support");
log("&c - http://builds.enginehub.org/job/worldedit");
} else {
getServer().getPluginManager().registerEvents(new WEListener(), this);
return true;
}
}
return false;
}
@Override
public EconHandler getEconomyHandler() {
try {
final BukkitEconHandler econ = new BukkitEconHandler();
if (econ.init()) {
return econ;
}
} catch (final Throwable ignored) {
}
return null;
}
@Override
public PlotQueue initPlotQueue() {
try {
new SendChunk();
MainUtil.canSendChunk = true;
} catch (final Throwable e) {
e.printStackTrace();
MainUtil.canSendChunk = false;
}
if (PS.get().checkVersion(getServerVersion(), 1, 8, 0)) {
try {
return new FastQueue_1_8_3();
} catch (Throwable e) {
e.printStackTrace();
try {
return new FastQueue_1_8();
} catch (Throwable e2) {
e2.printStackTrace();
return new SlowQueue();
}
}
}
try {
return new FastQueue_1_7();
} catch (Throwable e) {
e.printStackTrace();
return new SlowQueue();
}
}
@Override
public WorldUtil initWorldUtil() {
return new BukkitUtil();
}
@Override
public boolean initPlotMeConverter() {
TaskManager.runTaskLaterAsync(new Runnable() {
@Override
public void run() {
if (new LikePlotMeConverter("PlotMe").run(new ClassicPlotMeConnector())) {
return;
}
if (new LikePlotMeConverter("PlotMe").run(new PlotMeConnector_017())) {
return;
}
if (new LikePlotMeConverter("AthionPlots").run(new ClassicPlotMeConnector())) {
return;
}
}
}, 20);
return (Bukkit.getPluginManager().getPlugin("PlotMe") != null) || (Bukkit.getPluginManager().getPlugin("AthionPlots") != null);
}
@Override
public GeneratorWrapper<?> getGenerator(final String world, final String name) {
if (name == null) {
return null;
}
final Plugin gen_plugin = Bukkit.getPluginManager().getPlugin(name);
if ((gen_plugin != null) && gen_plugin.isEnabled()) {
ChunkGenerator gen = gen_plugin.getDefaultWorldGenerator(world, "");
if (gen instanceof GeneratorWrapper<?>) {
return (GeneratorWrapper<?>) gen;
}
return new BukkitPlotGenerator(world, gen);
} else {
return new BukkitPlotGenerator(new HybridGen());
}
}
@Override
public HybridUtils initHybridUtils() {
return new BukkitHybridUtils();
}
@Override
public SetupUtils initSetupUtils() {
return new BukkitSetupUtils();
}
@Override
public UUIDHandlerImplementation initUUIDHandler() {
final boolean checkVersion = PS.get().checkVersion(getServerVersion(), 1, 7, 6);
UUIDWrapper wrapper;
if (Settings.OFFLINE_MODE) {
if (Settings.UUID_LOWERCASE) {
wrapper = (new LowerOfflineUUIDWrapper());
} else {
wrapper = (new OfflineUUIDWrapper());
}
Settings.OFFLINE_MODE = true;
} else if (checkVersion) {
wrapper = (new DefaultUUIDWrapper());
Settings.OFFLINE_MODE = false;
} else {
if (Settings.UUID_LOWERCASE) {
wrapper = (new LowerOfflineUUIDWrapper());
} else {
wrapper = (new OfflineUUIDWrapper());
}
Settings.OFFLINE_MODE = true;
}
if (!checkVersion) {
log(C.PREFIX.s() + " &c[WARN] Titles are disabled - please update your version of Bukkit to support this feature.");
Settings.TITLES = false;
FlagManager.removeFlag(FlagManager.getFlag("titles"));
} else {
AbstractTitle.TITLE_CLASS = new DefaultTitle();
if (wrapper instanceof DefaultUUIDWrapper || wrapper.getClass() == OfflineUUIDWrapper.class && !Bukkit.getOnlineMode()) {
Settings.TWIN_MODE_UUID = true;
}
}
if (Settings.OFFLINE_MODE) {
log(C.PREFIX.s() + " &6PlotSquared is using Offline Mode UUIDs either because of user preference, or because you are using an old version of Bukkit");
} else {
log(C.PREFIX.s() + " &6PlotSquared is using online UUIDs");
}
return Settings.USE_SQLUUIDHANDLER ? new SQLUUIDHandler(wrapper) : new FileUUIDHandler(wrapper);
}
@Override
public ChunkManager initChunkManager() {
return new BukkitChunkManager();
}
@Override
public EventUtil initEventUtil() {
return new BukkitEventUtil();
}
@Override
public void unregister(final PlotPlayer player) {
BukkitUtil.removePlayer(player.getName());
}
@Override
public void registerChunkProcessor() {
getServer().getPluginManager().registerEvents(new ChunkListener(), this);
}
@Override
public void registerWorldEvents() {
getServer().getPluginManager().registerEvents(new WorldEvents(), this);
}
@Override
public InventoryUtil initInventoryUtil() {
return new BukkitInventoryUtil();
}
@Override
public String getServerName() {
return Bukkit.getServerName();
}
@Override
public void startMetrics() {
try {
final Metrics metrics = new Metrics(this);
metrics.start();
log(C.PREFIX.s() + "&6Metrics enabled.");
} catch (IOException e) {
log(C.PREFIX.s() + "&cFailed to load up metrics.");
}
}
@Override
public void setGenerator(final String worldname) {
World world = BukkitUtil.getWorld(worldname);
if (world == null) {
// create world
final ConfigurationSection worldConfig = PS.get().config.getConfigurationSection("worlds." + worldname);
String manager = worldConfig.getString("generator.plugin");
if (manager == null) {
manager = "PlotSquared";
}
String generator = worldConfig.getString("generator.init");
if (generator == null) {
generator = manager;
}
final int type = worldConfig.getInt("generator.type");
final int terrain = worldConfig.getInt("generator.terrain");
final SetupObject setup = new SetupObject();
setup.plotManager = manager;
setup.setupGenerator = generator;
setup.type = type;
setup.terrain = terrain;
setup.step = new ConfigurationNode[0];
setup.world = worldname;
SetupUtils.manager.setupWorld(setup);
} else {
try {
if (!PS.get().hasPlotArea(worldname)) {
SetGenCB.setGenerator(BukkitUtil.getWorld(worldname));
}
} catch (final Exception e) {
log("Failed to reload world: " + world);
Bukkit.getServer().unloadWorld(world, false);
}
}
world = Bukkit.getWorld(worldname);
final ChunkGenerator gen = world.getGenerator();
if (gen instanceof BukkitPlotGenerator) {
PS.get().loadWorld(worldname, (BukkitPlotGenerator) gen);
} else if (gen != null) {
PS.get().loadWorld(worldname, new BukkitPlotGenerator(worldname, gen));
} else {
if (PS.get().config.contains("worlds." + worldname)) {
PS.get().loadWorld(worldname, null);
}
}
}
@Override
public SchematicHandler initSchematicHandler() {
return new BukkitSchematicHandler();
}
@Override
public AbstractTitle initTitleManager() {
// Already initialized in UUID handler
return AbstractTitle.TITLE_CLASS;
}
@Override
public PlotPlayer wrapPlayer(final Object obj) {
if (obj instanceof Player) {
return BukkitUtil.getPlayer((Player) obj);
} else if (obj instanceof OfflinePlayer) {
return BukkitUtil.getPlayer((OfflinePlayer) obj);
} else if (obj instanceof String) {
return UUIDHandler.getPlayer((String) obj);
} else if (obj instanceof UUID) {
return UUIDHandler.getPlayer((UUID) obj);
}
return null;
}
@Override
public String getNMSPackage() {
final Server server = Bukkit.getServer();
final Class<?> bukkitServerClass = server.getClass();
String[] pas = bukkitServerClass.getName().split("\\.");
if (pas.length == 5) {
return pas[3];
}
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) {
return pas[3];
}
} catch (IllegalAccessException | InvocationTargetException | SecurityException | NoSuchMethodException | IllegalArgumentException e) {
e.printStackTrace();
}
PS.debug("Unknown NMS package: " + StringMan.getString(pas));
return "1_8_R3";
}
@Override
public ChatManager<?> initChatManager() {
if (Settings.FANCY_CHAT) {
return new BukkitChatManager();
} else {
return new BukkitPlainChatManager();
}
}
@Override
public GeneratorWrapper<?> wrapPlotGenerator(IndependentPlotGenerator generator) {
return new BukkitPlotGenerator(generator);
}
@Override
public List<String> getPluginIds() {
ArrayList<String> names = new ArrayList<>();
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
names.add(plugin.getName() + ";" + plugin.getDescription().getVersion() + ":" + plugin.isEnabled());
}
return names;
}
}

View File

@ -0,0 +1,103 @@
package com.plotsquared.bukkit.chat;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import org.apache.commons.lang.Validate;
/**
* Represents a wrapper around an array class of an arbitrary reference type,
* which properly implements "value" hash code and equality functions.
* <p>
* This class is intended for use as a key to a map.
* </p>
* @author Glen Husman
* @param <E> The type of elements in the array.
* @see Arrays
*/
public final class ArrayWrapper<E> {
/**
* Creates an array wrapper with some elements.
* @param elements The elements of the array.
*/
public ArrayWrapper(final E... elements) {
setArray(elements);
}
private E[] _array;
/**
* Retrieves a reference to the wrapped array instance.
* @return The array wrapped by this instance.
*/
public E[] getArray() {
return _array;
}
/**
* Set this wrapper to wrap a new array instance.
* @param array The new wrapped array.
*/
public void setArray(final E[] array) {
Validate.notNull(array, "The array must not be null.");
_array = array;
}
/**
* Determines if this object has a value equivalent to another object.
* @see Arrays#equals(Object[], Object[])
*/
@SuppressWarnings("rawtypes")
@Override
public boolean equals(final Object other) {
if (!(other instanceof ArrayWrapper)) {
return false;
}
return Arrays.equals(_array, ((ArrayWrapper) other)._array);
}
/**
* Gets the hash code represented by this objects value.
* @see Arrays#hashCode(Object[])
* @return This object's hash code.
*/
@Override
public int hashCode() {
return Arrays.hashCode(_array);
}
/**
* Converts an iterable element collection to an array of elements.
* The iteration order of the specified object will be used as the array element order.
* @param list The iterable of objects which will be converted to an array.
* @param c The type of the elements of the array.
* @return An array of elements in the specified iterable.
*/
@SuppressWarnings("unchecked")
public static <T> T[] toArray(final Iterable<? extends T> list, final Class<T> c) {
int size = -1;
if (list instanceof Collection<?>) {
@SuppressWarnings("rawtypes")
final Collection coll = (Collection) list;
size = coll.size();
}
if (size < 0) {
size = 0;
// Ugly hack: Count it ourselves
for (@SuppressWarnings("unused")
final T element : list) {
size++;
}
}
final T[] result = (T[]) Array.newInstance(c, size);
int i = 0;
for (final T element : list) { // Assumes iteration order is consistent
result[i++] = element; // Assign array element at index THEN increment counter
}
return result;
}
}

View File

@ -0,0 +1,847 @@
package com.plotsquared.bukkit.chat;
import static com.plotsquared.bukkit.chat.TextualComponent.rawText;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonWriter;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
import org.bukkit.Achievement;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.Statistic.Type;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
/**
* Represents a formattable message. Such messages can use elements such as colors, formatting codes, hover and click data, and other features provided by the vanilla Minecraft <a href="http://minecraft.gamepedia.com/Tellraw#Raw_JSON_Text">JSON message formatter</a>.
* This class allows plugins to emulate the functionality of the vanilla Minecraft <a href="http://minecraft.gamepedia.com/Commands#tellraw">tellraw command</a>.
* <p>
* This class follows the builder pattern, allowing for method chaining.
* It is set up such that invocations of property-setting methods will affect the current editing component,
* and a call to {@link #then(String)} or {@link #text(TextualComponent)} will append a new editing component to the end of the message,
* optionally initializing it with text. Further property-setting method calls will affect that editing component.
* </p>
*/
public class FancyMessage implements JsonRepresentedObject, Cloneable, Iterable<MessagePart>, ConfigurationSerializable {
static {
ConfigurationSerialization.registerClass(FancyMessage.class);
}
private List<MessagePart> messageParts;
private String jsonString;
private boolean dirty;
private static Constructor<?> nmsPacketPlayOutChatConstructor;
@Override
public FancyMessage clone() throws CloneNotSupportedException {
final FancyMessage instance = (FancyMessage) super.clone();
instance.messageParts = new ArrayList<>(messageParts.size());
for (int i = 0; i < messageParts.size(); i++) {
instance.messageParts.add(i, messageParts.get(i).clone());
}
instance.dirty = false;
instance.jsonString = null;
return instance;
}
/**
* Creates a JSON message with text.
* @param firstPartText The existing text in the message.
*/
public FancyMessage(final String firstPartText) {
this(rawText(firstPartText));
}
public FancyMessage(final TextualComponent firstPartText) {
messageParts = new ArrayList<>();
messageParts.add(new MessagePart(firstPartText));
jsonString = null;
dirty = false;
if (nmsPacketPlayOutChatConstructor == null) {
try {
nmsPacketPlayOutChatConstructor = Reflection.getNMSClass("PacketPlayOutChat").getDeclaredConstructor(Reflection.getNMSClass("IChatBaseComponent"));
nmsPacketPlayOutChatConstructor.setAccessible(true);
} catch (final NoSuchMethodException e) {
Bukkit.getLogger().log(Level.SEVERE, "Could not find Minecraft method or constructor.", e);
} catch (final SecurityException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access constructor.", e);
}
}
}
/**
* Creates a JSON message without text.
*/
public FancyMessage() {
this((TextualComponent) null);
}
/**
* Sets the text of the current editing component to a value.
* @param text The new text of the current editing component.
* @return This builder instance.
*/
public FancyMessage text(final String text) {
final MessagePart latest = latest();
latest.text = rawText(text);
dirty = true;
return this;
}
/**
* Sets the text of the current editing component to a value.
* @param text The new text of the current editing component.
* @return This builder instance.
*/
public FancyMessage text(final TextualComponent text) {
final MessagePart latest = latest();
latest.text = text;
dirty = true;
return this;
}
/**
* Sets the color of the current editing component to a value.
* @param color The new color of the current editing component.
* @return This builder instance.
* @exception IllegalArgumentException If the specified {@code ChatColor} enumeration value is not a color (but a format value).
*/
public FancyMessage color(final ChatColor color) {
latest().color = color;
dirty = true;
return this;
}
/**
* Sets the stylization of the current editing component.
* @param styles The array of styles to apply to the editing component.
* @return This builder instance.
* @exception IllegalArgumentException If any of the enumeration values in the array do not represent formatters.
*/
public FancyMessage style(final ChatColor... styles) {
for (final ChatColor style : styles) {
if (!style.isFormat()) {
throw new IllegalArgumentException(style.name() + " is not a style");
}
}
latest().styles.addAll(Arrays.asList(styles));
dirty = true;
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to open a file on the client side filesystem when the currently edited part of the {@code FancyMessage} is clicked.
* @param path The path of the file on the client filesystem.
* @return This builder instance.
*/
public FancyMessage file(final String path) {
onClick("open_file", path);
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to open a webpage in the client's web browser when the currently edited part of the {@code FancyMessage} is clicked.
* @param url The URL of the page to open when the link is clicked.
* @return This builder instance.
*/
public FancyMessage link(final String url) {
onClick("open_url", url);
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to replace the chat input box content with the specified string when the currently edited part of the {@code FancyMessage} is clicked.
* The client will not immediately send the command to the server to be executed unless the client player submits the command/chat message, usually with the enter key.
* @param command The text to display in the chat bar of the client.
* @return This builder instance.
*/
public FancyMessage suggest(final String command) {
onClick("suggest_command", command);
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to append the chat input box content with the specified string when the currently edited part of the {@code FancyMessage} is SHIFT-CLICKED.
* The client will not immediately send the command to the server to be executed unless the client player submits the command/chat message, usually with the enter key.
* @param command The text to append to the chat bar of the client.
* @return This builder instance.
*/
public FancyMessage insert(final String command) {
latest().insertionData = command;
dirty = true;
return this;
}
/**
* Set the behavior of the current editing component to instruct the client to send the specified string to the server as a chat message when the currently edited part of the {@code FancyMessage} is clicked.
* The client <b>will</b> immediately send the command to the server to be executed when the editing component is clicked.
* @param command The text to display in the chat bar of the client.
* @return This builder instance.
*/
public FancyMessage command(final String command) {
onClick("run_command", command);
return this;
}
/**
* Set the behavior of the current editing component to display information about an achievement when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param name The name of the achievement to display, excluding the "achievement." prefix.
* @return This builder instance.
*/
public FancyMessage achievementTooltip(final String name) {
onHover("show_achievement", new JsonString("achievement." + name));
return this;
}
/**
* Set the behavior of the current editing component to display information about an achievement when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param which The achievement to display.
* @return This builder instance.
*/
public FancyMessage achievementTooltip(final Achievement which) {
try {
final Object achievement = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getNMSAchievement", Achievement.class).invoke(null, which);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Achievement"), "name").get(achievement));
} catch (final IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (final IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (final InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occurred during invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about a parameterless statistic when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param which The statistic to display.
* @return This builder instance.
* @exception IllegalArgumentException If the statistic requires a parameter which was not supplied.
*/
public FancyMessage statisticTooltip(final Statistic which) {
final Type type = which.getType();
if (type != Type.UNTYPED) {
throw new IllegalArgumentException("That statistic requires an additional " + type + " parameter!");
}
try {
final Object statistic = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getNMSStatistic", Statistic.class).invoke(null, which);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name").get(statistic));
} catch (final IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (final IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (final InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occurred during invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about a statistic parameter with a material when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param which The statistic to display.
* @param item The sole material parameter to the statistic.
* @return This builder instance.
* @exception IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required.
*/
public FancyMessage statisticTooltip(final Statistic which, final Material item) {
final Type type = which.getType();
if (type == Type.UNTYPED) {
throw new IllegalArgumentException("That statistic needs no additional parameter!");
}
if (((type == Type.BLOCK) && item.isBlock()) || (type == Type.ENTITY)) {
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
}
try {
final Object statistic = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getMaterialStatistic", Statistic.class, Material.class).invoke(null, which, item);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name").get(statistic));
} catch (final IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (final IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (final InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occurred during invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about a statistic parameter with an entity type when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param which The statistic to display.
* @param entity The sole entity type parameter to the statistic.
* @return This builder instance.
* @exception IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required.
*/
public FancyMessage statisticTooltip(final Statistic which, final EntityType entity) {
final Type type = which.getType();
if (type == Type.UNTYPED) {
throw new IllegalArgumentException("That statistic needs no additional parameter!");
}
if (type != Type.ENTITY) {
throw new IllegalArgumentException("Wrong parameter type for that statistic - needs " + type + "!");
}
try {
final Object statistic = Reflection.getMethod(Reflection.getOBCClass("CraftStatistic"), "getEntityStatistic", Statistic.class, EntityType.class).invoke(null, which, entity);
return achievementTooltip((String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name").get(statistic));
} catch (final IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
return this;
} catch (final IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
return this;
} catch (final InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occurred during invoking of method.", e);
return this;
}
}
/**
* Set the behavior of the current editing component to display information about an item when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param itemJSON A string representing the JSON-serialized NBT data tag of an {@link ItemStack}.
* @return This builder instance.
*/
public FancyMessage itemTooltip(final String itemJSON) {
onHover("show_item", new JsonString(itemJSON)); // Seems a bit hacky, considering we have a JSON object as a parameter
return this;
}
/**
* Set the behavior of the current editing component to display information about an item when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param itemStack The stack for which to display information.
* @return This builder instance.
*/
public FancyMessage itemTooltip(final ItemStack itemStack) {
try {
final Object nmsItem = Reflection.getMethod(Reflection.getOBCClass("inventory.CraftItemStack"), "asNMSCopy", ItemStack.class).invoke(null, itemStack);
return itemTooltip(Reflection.getMethod(Reflection.getNMSClass("ItemStack"), "save", Reflection.getNMSClass("NBTTagCompound"))
.invoke(nmsItem, Reflection.getNMSClass("NBTTagCompound").newInstance()).toString());
} catch (final Exception e) {
e.printStackTrace();
return this;
}
}
/**
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param text The text, which supports newlines, which will be displayed to the client upon hovering.
* @return This builder instance.
*/
public FancyMessage tooltip(final String text) {
onHover("show_text", new JsonString(text));
return this;
}
/**
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created.
* @return This builder instance.
*/
public FancyMessage tooltip(final Iterable<String> lines) {
tooltip(ArrayWrapper.toArray(lines, String.class));
return this;
}
/**
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param lines The lines of text which will be displayed to the client upon hovering.
* @return This builder instance.
*/
public FancyMessage tooltip(final String... lines) {
final StringBuilder builder = new StringBuilder();
for (int i = 0; i < lines.length; i++) {
builder.append(lines[i]);
if (i != (lines.length - 1)) {
builder.append('\n');
}
}
tooltip(builder.toString());
return this;
}
/**
* Set the behavior of the current editing component to display formatted text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param text The formatted text which will be displayed to the client upon hovering.
* @return This builder instance.
*/
public FancyMessage formattedTooltip(final FancyMessage text) {
for (final MessagePart component : text.messageParts) {
if ((component.clickActionData != null) && (component.clickActionName != null)) {
throw new IllegalArgumentException("The tooltip text cannot have click data.");
} else if ((component.hoverActionData != null) && (component.hoverActionName != null)) {
throw new IllegalArgumentException("The tooltip text cannot have a tooltip.");
}
}
onHover("show_text", text);
return this;
}
/**
* Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param lines The lines of formatted text which will be displayed to the client upon hovering.
* @return This builder instance.
*/
public FancyMessage formattedTooltip(final FancyMessage... lines) {
if (lines.length < 1) {
onHover(null, null); // Clear tooltip
return this;
}
final FancyMessage result = new FancyMessage();
result.messageParts.clear(); // Remove the one existing text component that exists by default, which destabilizes the object
for (int i = 0; i < lines.length; i++) {
try {
for (final MessagePart component : lines[i]) {
if ((component.clickActionData != null) && (component.clickActionName != null)) {
throw new IllegalArgumentException("The tooltip text cannot have click data.");
} else if ((component.hoverActionData != null) && (component.hoverActionName != null)) {
throw new IllegalArgumentException("The tooltip text cannot have a tooltip.");
}
if (component.hasText()) {
result.messageParts.add(component.clone());
}
}
if (i != (lines.length - 1)) {
result.messageParts.add(new MessagePart(rawText("\n")));
}
} catch (final CloneNotSupportedException e) {
Bukkit.getLogger().log(Level.WARNING, "Failed to clone object", e);
return this;
}
}
return formattedTooltip(result.messageParts.isEmpty() ? null : result); // Throws NPE if size is 0, intended
}
/**
* Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text.
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
* @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created.
* @return This builder instance.
*/
public FancyMessage formattedTooltip(final Iterable<FancyMessage> lines) {
return formattedTooltip(ArrayWrapper.toArray(lines, FancyMessage.class));
}
/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/
public FancyMessage translationReplacements(final String... replacements) {
for (final String str : replacements) {
latest().translationReplacements.add(new JsonString(str));
}
dirty = true;
return this;
}
/*
/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*//* ------------
public FancyMessage translationReplacements(final Iterable<? extends CharSequence> replacements){
for(CharSequence str : replacements){
latest().translationReplacements.add(new JsonString(str));
}
return this;
}
*/
/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/
public FancyMessage translationReplacements(final FancyMessage... replacements) {
Collections.addAll(latest().translationReplacements, replacements);
dirty = true;
return this;
}
/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/
public FancyMessage translationReplacements(final Iterable<FancyMessage> replacements) {
return translationReplacements(ArrayWrapper.toArray(replacements, FancyMessage.class));
}
/**
* Terminate construction of the current editing component, and begin construction of a new message component.
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
* @param text The text which will populate the new message component.
* @return This builder instance.
*/
public FancyMessage then(final String text) {
return then(rawText(text));
}
/**
* Terminate construction of the current editing component, and begin construction of a new message component.
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
* @param text The text which will populate the new message component.
* @return This builder instance.
*/
public FancyMessage then(final TextualComponent text) {
if (!latest().hasText()) {
throw new IllegalStateException("previous message part has no text");
}
messageParts.add(new MessagePart(text));
dirty = true;
return this;
}
/**
* Terminate construction of the current editing component, and begin construction of a new message component.
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
* @return This builder instance.
*/
public FancyMessage then() {
if (!latest().hasText()) {
throw new IllegalStateException("previous message part has no text");
}
messageParts.add(new MessagePart());
dirty = true;
return this;
}
@Override
public void writeJson(final JsonWriter writer) throws IOException {
if (messageParts.size() == 1) {
latest().writeJson(writer);
} else {
writer.beginObject().name("text").value("").name("extra").beginArray();
for (final MessagePart part : this) {
part.writeJson(writer);
}
writer.endArray().endObject();
}
}
/**
* Serialize this fancy message, converting it into syntactically-valid JSON using a {@link JsonWriter}.
* This JSON should be compatible with vanilla formatter commands such as {@code /tellraw}.
* @return The JSON string representing this object.
*/
public String toJSONString() {
if (!dirty && (jsonString != null)) {
return jsonString;
}
final StringWriter string = new StringWriter();
final JsonWriter json = new JsonWriter(string);
try {
writeJson(json);
json.close();
} catch (final IOException e) {
throw new RuntimeException("invalid message");
}
jsonString = string.toString();
dirty = false;
return jsonString;
}
/**
* Sends this message to a player. The player will receive the fully-fledged formatted display of this message.
* @param player The player who will receive the message.
*/
public void send(final Player player) {
send(player, toJSONString());
}
private void send(final CommandSender sender, final String jsonString) {
if (!(sender instanceof Player)) {
sender.sendMessage(toOldMessageFormat());
return;
}
final Player player = (Player) sender;
try {
final Object handle = Reflection.getHandle(player);
final Object connection = Reflection.getField(handle.getClass(), "playerConnection").get(handle);
Reflection.getMethod(connection.getClass(), "sendPacket", Reflection.getNMSClass("Packet")).invoke(connection, createChatPacket(jsonString));
} catch (final IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
} catch (final IllegalAccessException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
} catch (final InstantiationException e) {
Bukkit.getLogger().log(Level.WARNING, "Underlying class is abstract.", e);
} catch (final InvocationTargetException e) {
Bukkit.getLogger().log(Level.WARNING, "A error has occurred during invoking of method.", e);
} catch (final NoSuchMethodException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not find method.", e);
} catch (final ClassNotFoundException e) {
Bukkit.getLogger().log(Level.WARNING, "Could not find class.", e);
}
}
// The ChatSerializer's instance of Gson
private static Object nmsChatSerializerGsonInstance;
private static Method fromJsonMethod;
private Object createChatPacket(final String json) throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException,
ClassNotFoundException {
if (nmsChatSerializerGsonInstance == null) {
// Find the field and its value, completely bypassing obfuscation
Class<?> chatSerializerClazz;
final String version = Reflection.getVersion();
final double majorVersion = Double.parseDouble(version.replace('_', '.').substring(1, 4));
final int lesserVersion = Integer.parseInt(version.substring(6, 7));
if ((majorVersion < 1.8) || ((majorVersion == 1.8) && (lesserVersion == 1))) {
chatSerializerClazz = Reflection.getNMSClass("ChatSerializer");
} else {
chatSerializerClazz = Reflection.getNMSClass("IChatBaseComponent$ChatSerializer");
}
if (chatSerializerClazz == null) {
throw new ClassNotFoundException("Can't find the ChatSerializer class");
}
for (final Field declaredField : chatSerializerClazz.getDeclaredFields()) {
if (Modifier.isFinal(declaredField.getModifiers()) && Modifier.isStatic(declaredField.getModifiers()) && declaredField.getType().getName().endsWith("Gson")) {
// We've found our field
declaredField.setAccessible(true);
nmsChatSerializerGsonInstance = declaredField.get(null);
fromJsonMethod = nmsChatSerializerGsonInstance.getClass().getMethod("fromJson", String.class, Class.class);
break;
}
}
}
/*
Since the method is so simple, and all the obfuscated methods have the same name, it's easier to reimplement 'IChatBaseComponent a(String)'
than to reflectively call it
Of course, the implementation may change, but fuzzy matches might break with signature changes
*/
final Object serializedChatComponent = fromJsonMethod.invoke(nmsChatSerializerGsonInstance, json, Reflection.getNMSClass("IChatBaseComponent"));
return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent);
}
/**
* Sends this message to a command sender.
* If the sender is a player, they will receive the fully-fledged formatted display of this message.
* Otherwise, they will receive a version of this message with less formatting.
* @param sender The command sender who will receive the message.
* @see #toOldMessageFormat()
*/
public void send(final CommandSender sender) {
send(sender, toJSONString());
}
/**
* Sends this message to multiple command senders.
* @param senders The command senders who will receive the message.
* @see #send(CommandSender)
*/
public void send(final Iterable<? extends CommandSender> senders) {
final String string = toJSONString();
for (final CommandSender sender : senders) {
send(sender, string);
}
}
/**
* Convert this message to a human-readable string with limited formatting.
* This method is used to send this message to clients without JSON formatting support.
* <p>
* Serialization of this message by using this message will include (in this order for each message part):
* <ol>
* <li>The color of each message part.</li>
* <li>The applicable stylization for each message part.</li>
* <li>The core text of the message part.</li>
* </ol>
* The primary omissions are tooltips and clickable actions. Consequently, this method should be used only as a last resort.
* </p>
* <p>
* Color and formatting can be removed from the returned string by using {@link ChatColor#stripColor(String)}.</p>
* @return A human-readable string representing limited formatting in addition to the core text of this message.
*/
public String toOldMessageFormat() {
final StringBuilder result = new StringBuilder();
for (final MessagePart part : this) {
result.append(part.color == null ? "" : part.color);
for (final ChatColor formatSpecifier : part.styles) {
result.append(formatSpecifier);
}
result.append(part.text);
}
return result.toString();
}
private MessagePart latest() {
return messageParts.get(messageParts.size() - 1);
}
private void onClick(final String name, final String data) {
final MessagePart latest = latest();
latest.clickActionName = name;
latest.clickActionData = data;
dirty = true;
}
private void onHover(final String name, final JsonRepresentedObject data) {
final MessagePart latest = latest();
latest.hoverActionName = name;
latest.hoverActionData = data;
dirty = true;
}
// Doc copied from interface
@Override
public Map<String, Object> serialize() {
final HashMap<String, Object> map = new HashMap<>();
map.put("messageParts", messageParts);
// map.put("JSON", toJSONString());
return map;
}
/**
* Deserialize a JSON-represented message from a mapping of key-value pairs.
* This is called by the Bukkit serialization API.
* It is not intended for direct public API consumption.
* @param serialized The key-value mapping which represents a fancy message.
*/
@SuppressWarnings("unchecked")
public static FancyMessage deserialize(final Map<String, Object> serialized) {
final FancyMessage msg = new FancyMessage();
msg.messageParts = (List<MessagePart>) serialized.get("messageParts");
msg.jsonString = serialized.containsKey("JSON") ? serialized.get("JSON").toString() : null;
msg.dirty = !serialized.containsKey("JSON");
return msg;
}
/**
* <b>Internally called method. Not for API consumption.</b>
*/
@Override
public Iterator<MessagePart> iterator() {
return messageParts.iterator();
}
private static JsonParser _stringParser = new JsonParser();
/**
* Deserialize a fancy message from its JSON representation. This JSON representation is of the format of
* that returned by {@link #toJSONString()}, and is compatible with vanilla inputs.
* @param json The JSON string which represents a fancy message.
* @return A {@code FancyMessage} representing the parametrized JSON message.
*/
public static FancyMessage deserialize(final String json) {
final JsonObject serialized = _stringParser.parse(json).getAsJsonObject();
final JsonArray extra = serialized.getAsJsonArray("extra"); // Get the extra component
final FancyMessage returnVal = new FancyMessage();
returnVal.messageParts.clear();
for (final JsonElement mPrt : extra) {
final MessagePart component = new MessagePart();
final JsonObject messagePart = mPrt.getAsJsonObject();
for (final Map.Entry<String, JsonElement> entry : messagePart.entrySet()) {
// Deserialize text
if (TextualComponent.isTextKey(entry.getKey())) {
// The map mimics the YAML serialization, which has a "key" field and one or more "value" fields
final Map<String, Object> serializedMapForm = new HashMap<>(); // Must be object due to Bukkit serializer API compliance
serializedMapForm.put("key", entry.getKey());
if (entry.getValue().isJsonPrimitive()) {
// Assume string
serializedMapForm.put("value", entry.getValue().getAsString());
} else {
// Composite object, but we assume each element is a string
for (final Map.Entry<String, JsonElement> compositeNestedElement : entry.getValue().getAsJsonObject().entrySet()) {
serializedMapForm.put("value." + compositeNestedElement.getKey(), compositeNestedElement.getValue().getAsString());
}
}
component.text = TextualComponent.deserialize(serializedMapForm);
} else if (MessagePart.stylesToNames.inverse().containsKey(entry.getKey())) {
if (entry.getValue().getAsBoolean()) {
component.styles.add(MessagePart.stylesToNames.inverse().get(entry.getKey()));
}
} else if (entry.getKey().equals("color")) {
component.color = ChatColor.valueOf(entry.getValue().getAsString().toUpperCase());
} else if (entry.getKey().equals("clickEvent")) {
final JsonObject object = entry.getValue().getAsJsonObject();
component.clickActionName = object.get("action").getAsString();
component.clickActionData = object.get("value").getAsString();
} else if (entry.getKey().equals("hoverEvent")) {
final JsonObject object = entry.getValue().getAsJsonObject();
component.hoverActionName = object.get("action").getAsString();
if (object.get("value").isJsonPrimitive()) {
// Assume string
component.hoverActionData = new JsonString(object.get("value").getAsString());
} else {
// Assume composite type
// The only composite type we currently store is another FancyMessage
// Therefore, recursion time!
component.hoverActionData = deserialize(object.get("value").toString() /* This should properly serialize the JSON object as a JSON string */);
}
} else if (entry.getKey().equals("insertion")) {
component.insertionData = entry.getValue().getAsString();
} else if (entry.getKey().equals("with")) {
for (final JsonElement object : entry.getValue().getAsJsonArray()) {
if (object.isJsonPrimitive()) {
component.translationReplacements.add(new JsonString(object.getAsString()));
} else {
// Only composite type stored in this array is - again - FancyMessages
// Recurse within this function to parse this as a translation replacement
component.translationReplacements.add(deserialize(object.toString()));
}
}
}
}
returnVal.messageParts.add(component);
}
return returnVal;
}
}

View File

@ -0,0 +1,19 @@
package com.plotsquared.bukkit.chat;
import java.io.IOException;
import com.google.gson.stream.JsonWriter;
/**
* Represents an object that can be serialized to a JSON writer instance.
*/
interface JsonRepresentedObject {
/**
* Writes the JSON representation of this object to the specified writer.
* @param writer The JSON writer which will receive the object.
* @throws IOException If an error occurs writing to the stream.
*/
void writeJson(final JsonWriter writer) throws IOException;
}

View File

@ -0,0 +1,47 @@
package com.plotsquared.bukkit.chat;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.stream.JsonWriter;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
/**
* Represents a JSON string value.
* Writes by this object will not write name values nor begin/end objects in the JSON stream.
* All writes merely write the represented string value.
*/
final class JsonString implements JsonRepresentedObject, ConfigurationSerializable {
private final String _value;
public JsonString(final CharSequence value) {
_value = value == null ? null : value.toString();
}
@Override
public void writeJson(final JsonWriter writer) throws IOException {
writer.value(getValue());
}
public String getValue() {
return _value;
}
@Override
public Map<String, Object> serialize() {
final HashMap<String, Object> theSingleValue = new HashMap<String, Object>();
theSingleValue.put("stringValue", _value);
return theSingleValue;
}
public static JsonString deserialize(final Map<String, Object> map) {
return new JsonString(map.get("stringValue").toString());
}
@Override
public String toString() {
return _value;
}
}

View File

@ -0,0 +1,150 @@
package com.plotsquared.bukkit.chat;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.gson.stream.JsonWriter;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
/**
* Internal class: Represents a component of a JSON-serializable {@link FancyMessage}.
*/
final class MessagePart implements JsonRepresentedObject, ConfigurationSerializable, Cloneable {
static final BiMap<ChatColor, String> stylesToNames;
static {
final ImmutableBiMap.Builder<ChatColor, String> builder = ImmutableBiMap.builder();
for (final ChatColor style : ChatColor.values()) {
if (!style.isFormat()) {
continue;
}
String styleName;
switch (style) {
case MAGIC:
styleName = "obfuscated";
break;
case UNDERLINE:
styleName = "underlined";
break;
default:
styleName = style.name().toLowerCase();
break;
}
builder.put(style, styleName);
}
stylesToNames = builder.build();
}
static {
ConfigurationSerialization.registerClass(MessagePart.class);
}
ChatColor color = ChatColor.WHITE;
ArrayList<ChatColor> styles = new ArrayList<ChatColor>();
String clickActionName = null, clickActionData = null, hoverActionName = null;
JsonRepresentedObject hoverActionData = null;
TextualComponent text = null;
String insertionData = null;
ArrayList<JsonRepresentedObject> translationReplacements = new ArrayList<JsonRepresentedObject>();
MessagePart(final TextualComponent text) {
this.text = text;
}
MessagePart() {
text = null;
}
@SuppressWarnings("unchecked")
public static MessagePart deserialize(final Map<String, Object> serialized) {
final MessagePart part = new MessagePart((TextualComponent) serialized.get("text"));
part.styles = (ArrayList<ChatColor>) serialized.get("styles");
part.color = ChatColor.getByChar(serialized.get("color").toString());
part.hoverActionName = (String) serialized.get("hoverActionName");
part.hoverActionData = (JsonRepresentedObject) serialized.get("hoverActionData");
part.clickActionName = (String) serialized.get("clickActionName");
part.clickActionData = (String) serialized.get("clickActionData");
part.insertionData = (String) serialized.get("insertion");
part.translationReplacements = (ArrayList<JsonRepresentedObject>) serialized.get("translationReplacements");
return part;
}
boolean hasText() {
return text != null;
}
@Override
@SuppressWarnings("unchecked")
public MessagePart clone() throws CloneNotSupportedException {
final MessagePart obj = (MessagePart) super.clone();
obj.styles = (ArrayList<ChatColor>) styles.clone();
if (hoverActionData instanceof JsonString) {
obj.hoverActionData = new JsonString(((JsonString) hoverActionData).getValue());
} else if (hoverActionData instanceof FancyMessage) {
obj.hoverActionData = ((FancyMessage) hoverActionData).clone();
}
obj.translationReplacements = (ArrayList<JsonRepresentedObject>) translationReplacements.clone();
return obj;
}
@Override
public void writeJson(final JsonWriter json) {
try {
json.beginObject();
text.writeJson(json);
json.name("color").value(color.name().toLowerCase());
for (final ChatColor style : styles) {
json.name(stylesToNames.get(style)).value(true);
}
if ((clickActionName != null) && (clickActionData != null)) {
json.name("clickEvent").beginObject().name("action").value(clickActionName).name("value").value(clickActionData).endObject();
}
if ((hoverActionName != null) && (hoverActionData != null)) {
json.name("hoverEvent").beginObject().name("action").value(hoverActionName).name("value");
hoverActionData.writeJson(json);
json.endObject();
}
if (insertionData != null) {
json.name("insertion").value(insertionData);
}
if ((!translationReplacements.isEmpty()) && (text != null) && TextualComponent.isTranslatableText(text)) {
json.name("with").beginArray();
for (final JsonRepresentedObject obj : translationReplacements) {
obj.writeJson(json);
}
json.endArray();
}
json.endObject();
} catch (final IOException e) {
Bukkit.getLogger().log(Level.WARNING, "A problem occurred during writing of JSON string", e);
}
}
@Override
public Map<String, Object> serialize() {
final HashMap<String, Object> map = new HashMap<String, Object>();
map.put("text", text);
map.put("styles", styles);
map.put("color", color.getChar());
map.put("hoverActionName", hoverActionName);
map.put("hoverActionData", hoverActionData);
map.put("clickActionName", clickActionName);
map.put("clickActionData", clickActionData);
map.put("insertion", insertionData);
map.put("translationReplacements", translationReplacements);
return map;
}
}

View File

@ -0,0 +1,227 @@
package com.plotsquared.bukkit.chat;
import org.bukkit.Bukkit;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* A class containing static utility methods and caches which are intended as reflective conveniences.
* Unless otherwise noted, upon failure methods will return {@code null}.
*/
public final class Reflection {
/**
* Stores loaded classes from the {@code net.minecraft.server} package.
*/
private static final Map<String, Class<?>> _loadedNMSClasses = new HashMap<>();
/**
* Stores loaded classes from the {@code org.bukkit.craftbukkit} package (and subpackages).
*/
private static final Map<String, Class<?>> _loadedOBCClasses = new HashMap<>();
private static final Map<Class<?>, Map<String, Field>> _loadedFields = new HashMap<>();
/**
* Contains loaded methods in a cache.
* The map maps [types to maps of [method names to maps of [parameter types to method instances]]].
*/
private static final Map<Class<?>, Map<String, Map<ArrayWrapper<Class<?>>, Method>>> _loadedMethods = new HashMap<>();
private static String _versionString;
private Reflection() {
}
/**
* Gets the version string from the package name of the CraftBukkit server implementation.
* This is needed to bypass the JAR package name changing on each update.
* @return The version string of the OBC and NMS packages, <em>including the trailing dot</em>.
*/
public synchronized static String getVersion() {
if (_versionString == null) {
if (Bukkit.getServer() == null) {
// The server hasn't started, static initializer call?
return null;
}
final String name = Bukkit.getServer().getClass().getPackage().getName();
_versionString = name.substring(name.lastIndexOf('.') + 1) + ".";
}
return _versionString;
}
/**
* Gets a {@link Class} object representing a type contained within the {@code net.minecraft.server} versioned package.
* The class instances returned by this method are cached, such that no lookup will be done twice (unless multiple threads are accessing this method simultaneously).
* @param className The name of the class, excluding the package, within NMS.
* @return The class instance representing the specified NMS class, or {@code null} if it could not be loaded.
*/
public synchronized static Class<?> getNMSClass(final String className) {
if (_loadedNMSClasses.containsKey(className)) {
return _loadedNMSClasses.get(className);
}
final String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz;
try {
clazz = Class.forName(fullName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
_loadedNMSClasses.put(className, null);
return null;
}
_loadedNMSClasses.put(className, clazz);
return clazz;
}
/**
* Gets a {@link Class} object representing a type contained within the {@code org.bukkit.craftbukkit} versioned package.
* The class instances returned by this method are cached, such that no lookup will be done twice (unless multiple threads are accessing this
* method simultaneously).
* @param className The name of the class, excluding the package, within OBC. This name may contain a subpackage name, such as {@code inventory
* .CraftItemStack}.
* @return The class instance representing the specified OBC class, or {@code null} if it could not be loaded.
*/
public synchronized static Class<?> getOBCClass(final String className) {
if (_loadedOBCClasses.containsKey(className)) {
return _loadedOBCClasses.get(className);
}
final String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
Class<?> clazz;
try {
clazz = Class.forName(fullName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
_loadedOBCClasses.put(className, null);
return null;
}
_loadedOBCClasses.put(className, clazz);
return clazz;
}
/**
* Attempts to get the NMS handle of a CraftBukkit object.
* <p>
* The only match currently attempted by this method is a retrieval by using a parameterless {@code getHandle()} method implemented by the
* runtime type of the specified object.
* </p>
* @param obj The object for which to retrieve an NMS handle.
* @return The NMS handle of the specified object, or {@code null} if it could not be retrieved using {@code getHandle()}.
*/
public synchronized static Object getHandle(final Object obj) {
try {
return getMethod(obj.getClass(), "getHandle").invoke(obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
} catch (InvocationTargetException e) {
e.printStackTrace();
return null;
}
}
/**
* Retrieves a {@link Field} instance declared by the specified class with the specified name.
* Java access modifiers are ignored during this retrieval. No guarantee is made as to whether the field
* returned will be an instance or static field.
* <p>
* A global caching mechanism within this class is used to store fields. Combined with synchronization, this guarantees that
* no field will be reflectively looked up twice.
* </p>
* <p>
* If a field is deemed suitable for return,
* {@link Field#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned.
* This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance.
* </p>
* @param clazz The class which contains the field to retrieve.
* @param name The declared name of the field in the class.
* @return A field object with the specified name declared by the specified class.
* @see Class#getDeclaredField(String)
*/
public synchronized static Field getField(final Class<?> clazz, final String name) {
Map<String, Field> loaded;
if (!_loadedFields.containsKey(clazz)) {
loaded = new HashMap<>();
_loadedFields.put(clazz, loaded);
} else {
loaded = _loadedFields.get(clazz);
}
if (loaded.containsKey(name)) {
// If the field is loaded (or cached as not existing), return the relevant value, which might be null
return loaded.get(name);
}
try {
final Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
loaded.put(name, field);
return field;
} catch (NoSuchFieldException e) {
// Error loading
e.printStackTrace();
// Cache field as not existing
loaded.put(name, null);
return null;
} catch (SecurityException e) {
// Error loading
e.printStackTrace();
// Cache field as not existing
loaded.put(name, null);
return null;
}
}
/**
* Retrieves a {@link Method} instance declared by the specified class with the specified name and argument types.
* Java access modifiers are ignored during this retrieval. No guarantee is made as to whether the field
* returned will be an instance or static field.
* <p>
* A global caching mechanism within this class is used to store method. Combined with synchronization, this guarantees that
* no method will be reflectively looked up twice.
* </p>
* <p>
* If a method is deemed suitable for return, {@link Method#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned.
* This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance.
* </p>
* <p>
* This method does <em>not</em> search superclasses of the specified type for methods with the specified signature.
* Callers wishing this behavior should use {@link Class#getDeclaredMethod(String, Class...)}.
* @param clazz The class which contains the method to retrieve.
* @param name The declared name of the method in the class.
* @param args The formal argument types of the method.
* @return A method object with the specified name declared by the specified class.
*/
public synchronized static Method getMethod(final Class<?> clazz, final String name, final Class<?>... args) {
if (!_loadedMethods.containsKey(clazz)) {
_loadedMethods.put(clazz, new HashMap<String, Map<ArrayWrapper<Class<?>>, Method>>());
}
final Map<String, Map<ArrayWrapper<Class<?>>, Method>> loadedMethodNames = _loadedMethods.get(clazz);
if (!loadedMethodNames.containsKey(name)) {
loadedMethodNames.put(name, new HashMap<ArrayWrapper<Class<?>>, Method>());
}
final Map<ArrayWrapper<Class<?>>, Method> loadedSignatures = loadedMethodNames.get(name);
final ArrayWrapper<Class<?>> wrappedArg = new ArrayWrapper<>(args);
if (loadedSignatures.containsKey(wrappedArg)) {
return loadedSignatures.get(wrappedArg);
}
for (final Method m : clazz.getMethods()) {
if (m.getName().equals(name) && Arrays.equals(args, m.getParameterTypes())) {
m.setAccessible(true);
loadedSignatures.put(wrappedArg, m);
return m;
}
}
loadedSignatures.put(wrappedArg, null);
return null;
}
}

View File

@ -0,0 +1,293 @@
package com.plotsquared.bukkit.chat;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.gson.stream.JsonWriter;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerializable;
import com.intellectualcrafters.configuration.serialization.ConfigurationSerialization;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a textual component of a message part.
* This can be used to not only represent string literals in a JSON message,
* but also to represent localized strings and other text values.
* <p>Different instances of this class can be created with static constructor methods.</p>
*/
public abstract class TextualComponent implements Cloneable {
static {
ConfigurationSerialization.registerClass(TextualComponent.ArbitraryTextTypeComponent.class);
ConfigurationSerialization.registerClass(TextualComponent.ComplexTextTypeComponent.class);
}
@Override
public String toString() {
return getReadableString();
}
/**
* @return The JSON key used to represent text components of this type.
*/
public abstract String getKey();
/**
* @return A readable String
*/
public abstract String getReadableString();
/**
* Clones a textual component instance.
* The returned object should not reference this textual component instance, but should maintain the same key and value.
*/
@Override
public abstract TextualComponent clone() throws CloneNotSupportedException;
/**
* Writes the text data represented by this textual component to the specified JSON writer object.
* A new object within the writer is not started.
* @param writer The object to which to write the JSON data.
* @throws IOException If an error occurs while writing to the stream.
*/
public abstract void writeJson(final JsonWriter writer) throws IOException;
static TextualComponent deserialize(final Map<String, Object> map) {
if (map.containsKey("key") && (map.size() == 2) && map.containsKey("value")) {
// Arbitrary text component
return ArbitraryTextTypeComponent.deserialize(map);
} else if ((map.size() >= 2) && map.containsKey("key") && !map.containsKey("value") /* It contains keys that START WITH value */) {
// Complex JSON object
return ComplexTextTypeComponent.deserialize(map);
}
return null;
}
static boolean isTextKey(final String key) {
return key.equals("translate") || key.equals("text") || key.equals("score") || key.equals("selector");
}
static boolean isTranslatableText(final TextualComponent component) {
return (component instanceof ComplexTextTypeComponent) && ((ComplexTextTypeComponent) component).getKey().equals("translate");
}
/**
* Internal class used to represent all types of text components.
* Exception validating done is on keys and values.
*/
private static final class ArbitraryTextTypeComponent extends TextualComponent implements ConfigurationSerializable {
public ArbitraryTextTypeComponent(final String key, final String value) {
setKey(key);
setValue(value);
}
@Override
public String getKey() {
return _key;
}
public void setKey(final String key) {
Preconditions.checkArgument((key != null) && !key.isEmpty(), "The key must be specified.");
_key = key;
}
public String getValue() {
return _value;
}
public void setValue(final String value) {
Preconditions.checkArgument(value != null, "The value must be specified.");
_value = value;
}
private String _key;
private String _value;
@Override
public TextualComponent clone() throws CloneNotSupportedException {
// Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone
return new ArbitraryTextTypeComponent(getKey(), getValue());
}
@Override
public void writeJson(final JsonWriter writer) throws IOException {
writer.name(getKey()).value(getValue());
}
@Override
@SuppressWarnings("serial")
public Map<String, Object> serialize() {
return new HashMap<String, Object>() {
{
put("key", getKey());
put("value", getValue());
}
};
}
public static ArbitraryTextTypeComponent deserialize(final Map<String, Object> map) {
return new ArbitraryTextTypeComponent(map.get("key").toString(), map.get("value").toString());
}
@Override
public String getReadableString() {
return getValue();
}
}
/**
* Internal class used to represent a text component with a nested JSON value.
* Exception validating done is on keys and values.
*/
private static final class ComplexTextTypeComponent extends TextualComponent implements ConfigurationSerializable {
public ComplexTextTypeComponent(final String key, final Map<String, String> values) {
setKey(key);
setValue(values);
}
@Override
public String getKey() {
return _key;
}
public void setKey(final String key) {
Preconditions.checkArgument((key != null) && !key.isEmpty(), "The key must be specified.");
_key = key;
}
public Map<String, String> getValue() {
return _value;
}
public void setValue(final Map<String, String> value) {
Preconditions.checkArgument(value != null, "The value must be specified.");
_value = value;
}
private String _key;
private Map<String, String> _value;
@Override
public TextualComponent clone() throws CloneNotSupportedException {
// Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone
return new ComplexTextTypeComponent(getKey(), getValue());
}
@Override
public void writeJson(final JsonWriter writer) throws IOException {
writer.name(getKey());
writer.beginObject();
for (final Map.Entry<String, String> jsonPair : _value.entrySet()) {
writer.name(jsonPair.getKey()).value(jsonPair.getValue());
}
writer.endObject();
}
@Override
@SuppressWarnings("serial")
public Map<String, Object> serialize() {
return new java.util.HashMap<String, Object>() {
{
put("key", getKey());
for (final Map.Entry<String, String> valEntry : getValue().entrySet()) {
put("value." + valEntry.getKey(), valEntry.getValue());
}
}
};
}
public static ComplexTextTypeComponent deserialize(final Map<String, Object> map) {
String key = null;
final Map<String, String> value = new HashMap<String, String>();
for (final Map.Entry<String, Object> valEntry : map.entrySet()) {
if (valEntry.getKey().equals("key")) {
key = (String) valEntry.getValue();
} else if (valEntry.getKey().startsWith("value.")) {
value.put(valEntry.getKey().substring(6) /* Strips out the value prefix */, valEntry.getValue().toString());
}
}
return new ComplexTextTypeComponent(key, value);
}
@Override
public String getReadableString() {
return getKey();
}
}
/**
* Create a textual component representing a string literal.
* This is the default type of textual component when a single string literal is given to a method.
* @param textValue The text which will be represented.
* @return The text component representing the specified literal text.
*/
public static TextualComponent rawText(final String textValue) {
return new ArbitraryTextTypeComponent("text", textValue);
}
/**
* Create a textual component representing a localized string.
* The client will see this text component as their localized version of the specified string <em>key</em>, which can be overridden by a resource pack.
* <p>
* If the specified translation key is not present on the client resource pack, the translation key will be displayed as a string literal to the client.
* </p>
* @param translateKey The string key which maps to localized text.
* @return The text component representing the specified localized text.
*/
public static TextualComponent localizedText(final String translateKey) {
return new ArbitraryTextTypeComponent("translate", translateKey);
}
private static void throwUnsupportedSnapshot() {
throw new UnsupportedOperationException("This feature is only supported in snapshot releases.");
}
/**
* Create a textual component representing a scoreboard value.
* The client will see their own score for the specified objective as the text represented by this component.
* <p>
* <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b>
* </p>
* @param scoreboardObjective The name of the objective for which to display the score.
* @return The text component representing the specified scoreboard score (for the viewing player), or {@code null} if an error occurs during JSON serialization.
*/
public static TextualComponent objectiveScore(final String scoreboardObjective) {
return objectiveScore("*", scoreboardObjective);
}
/**
* Create a textual component representing a scoreboard value.
* The client will see the score of the specified player for the specified objective as the text represented by this component.
* <p>
* <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b>
* </p>
* @param playerName The name of the player whos score will be shown. If this string represents the single-character sequence "*", the viewing player's score will be displayed.
* Standard minecraft selectors (@a, @p, etc) are <em>not</em> supported.
* @param scoreboardObjective The name of the objective for which to display the score.
* @return The text component representing the specified scoreboard score for the specified player, or {@code null} if an error occurs during JSON serialization.
*/
public static TextualComponent objectiveScore(final String playerName, final String scoreboardObjective) {
throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE OVERLOADS documentation accordingly
return new ComplexTextTypeComponent("score", ImmutableMap.<String, String> builder().put("name", playerName).put("objective", scoreboardObjective).build());
}
/**
* Create a textual component representing a player name, retrievable by using a standard minecraft selector.
* The client will see the players or entities captured by the specified selector as the text represented by this component.
* <p>
* <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b>
* </p>
* @param selector The minecraft player or entity selector which will capture the entities whose string representations will be displayed in the place of this text component.
* @return The text component representing the name of the entities captured by the selector.
*/
public static TextualComponent selector(final String selector) {
throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE OVERLOADS documentation accordingly
return new ArbitraryTextTypeComponent("selector", selector);
}
}

View File

@ -0,0 +1,332 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.commands;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.commands.CommandCategory;
import com.intellectualcrafters.plot.commands.RequiredType;
import com.intellectualcrafters.plot.commands.SubCommand;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.database.AbstractDB;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.StringMan;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.WorldUtil;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import com.plotsquared.bukkit.uuid.DefaultUUIDWrapper;
import com.plotsquared.bukkit.uuid.LowerOfflineUUIDWrapper;
import com.plotsquared.bukkit.uuid.OfflineUUIDWrapper;
import com.plotsquared.general.commands.Argument;
import com.plotsquared.general.commands.CommandDeclaration;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
@CommandDeclaration(
command = "uuidconvert",
permission = "plots.admin",
description = "Debug UUID conversion",
usage = "/plot uuidconvert <lower|offline|online>",
requiredType = RequiredType.CONSOLE,
category = CommandCategory.DEBUG)
public class DebugUUID extends SubCommand {
public DebugUUID() {
requiredArguments = new Argument[] { Argument.String };
}
@Override
public boolean onCommand(final PlotPlayer player, final String[] args) {
final UUIDWrapper currentUUIDWrapper = UUIDHandler.getUUIDWrapper();
final UUIDWrapper newWrapper;
switch (args[0].toLowerCase()) {
case "lower":
newWrapper = new LowerOfflineUUIDWrapper();
break;
case "offline":
newWrapper = new OfflineUUIDWrapper();
break;
case "online":
newWrapper = new DefaultUUIDWrapper();
break;
default:
try {
final Class<?> clazz = Class.forName(args[0]);
newWrapper = (UUIDWrapper) clazz.newInstance();
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot uuidconvert <lower|offline|online>");
return false;
}
}
if (args.length != 2 || !"-o".equals(args[1])) {
MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot uuidconvert " + args[0] + " - o");
MainUtil.sendMessage(player, "&cBe aware of the following!");
MainUtil.sendMessage(player, "&8 - &cUse the database command or another method to backup your plots beforehand");
MainUtil.sendMessage(player, "&8 - &cIf the process is interrupted, all plots could be deleted");
MainUtil.sendMessage(player, "&8 - &cIf an error occurs, all plots could be deleted");
MainUtil.sendMessage(player, "&8 - &cPlot settings WILL be lost upon conversion");
MainUtil.sendMessage(player, "&cTO REITERATE: BACK UP YOUR DATABASE BEFORE USING THIS!!!");
MainUtil.sendMessage(player, "&7Retype the command with the override parameter when ready :)");
return false;
}
if (currentUUIDWrapper.getClass().getCanonicalName().equals(newWrapper.getClass().getCanonicalName())) {
MainUtil.sendMessage(player, "&cUUID mode already in use!");
return false;
}
MainUtil.sendMessage(player, "&6Beginning UUID mode conversion");
MainUtil.sendMessage(player, "&7 - Disconnecting players");
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
entry.getValue().kick("PlotSquared UUID conversion has been initiated. You may reconnect when finished.");
}
MainUtil.sendMessage(player, "&7 - Initializing map");
final HashMap<UUID, UUID> uCMap = new HashMap<>();
final HashMap<UUID, UUID> uCReverse = new HashMap<>();
MainUtil.sendMessage(player, "&7 - Collecting playerdata");
final HashSet<String> worlds = new HashSet<>();
worlds.add(WorldUtil.IMP.getMainWorld());
worlds.add("world");
final HashSet<UUID> uuids = new HashSet<>();
final HashSet<String> names = new HashSet<>();
for (final String worldname : worlds) {
final File playerdataFolder = new File(worldname + File.separator + "playerdata");
String[] dat = playerdataFolder.list(new FilenameFilter() {
@Override
public boolean accept(final File f, final String s) {
return s.endsWith(".dat");
}
});
if (dat != null)
for (final String current : dat) {
final String s = current.replaceAll(".dat$", "");
try {
final UUID uuid = UUID.fromString(s);
uuids.add(uuid);
} catch (final Exception e) {
MainUtil.sendMessage(player, C.PREFIX.s() + "Invalid playerdata: " + current);
}
}
final File playersFolder = new File(worldname + File.separator + "players");
dat = playersFolder.list(new FilenameFilter() {
@Override
public boolean accept(final File f, final String s) {
return s.endsWith(".dat");
}
});
if (dat != null) {
for (final String current : dat) {
names.add(current.replaceAll(".dat$", ""));
}
}
}
MainUtil.sendMessage(player, "&7 - Populating map");
UUID uuid2;
final UUIDWrapper wrapper = new DefaultUUIDWrapper();
for (UUID uuid : uuids) {
try {
final OfflinePlotPlayer op = wrapper.getOfflinePlayer(uuid);
uuid = currentUUIDWrapper.getUUID(op);
uuid2 = newWrapper.getUUID(op);
if (!uuid.equals(uuid2) && !uCMap.containsKey(uuid) && !uCReverse.containsKey(uuid2)) {
uCMap.put(uuid, uuid2);
uCReverse.put(uuid2, uuid);
}
} catch (final Throwable e) {
MainUtil.sendMessage(player, C.PREFIX.s() + "&6Invalid playerdata: " + uuid.toString() + ".dat");
}
}
for (final String name : names) {
final UUID uuid = currentUUIDWrapper.getUUID(name);
uuid2 = newWrapper.getUUID(name);
if (!uuid.equals(uuid2)) {
uCMap.put(uuid, uuid2);
uCReverse.put(uuid2, uuid);
}
}
if (uCMap.isEmpty()) {
MainUtil.sendMessage(player, "&c - Error! Attempting to repopulate");
for (final OfflinePlotPlayer op : currentUUIDWrapper.getOfflinePlayers()) {
if (op.getLastPlayed() != 0) {
// String name = op.getName();
// StringWrapper wrap = new StringWrapper(name);
final UUID uuid = currentUUIDWrapper.getUUID(op);
uuid2 = newWrapper.getUUID(op);
if (!uuid.equals(uuid2)) {
uCMap.put(uuid, uuid2);
uCReverse.put(uuid2, uuid);
}
}
}
if (uCMap.isEmpty()) {
MainUtil.sendMessage(player, "&cError. Failed to collect UUIDs!");
return false;
} else {
MainUtil.sendMessage(player, "&a - Successfully repopulated");
}
}
MainUtil.sendMessage(player, "&7 - Replacing cache");
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
for (final Entry<UUID, UUID> entry : uCMap.entrySet()) {
final String name = UUIDHandler.getName(entry.getKey());
if (name != null) {
UUIDHandler.add(new StringWrapper(name), entry.getValue());
}
}
MainUtil.sendMessage(player, "&7 - Scanning for applicable files (uuids.txt)");
final File file = new File(PS.get().IMP.getDirectory(), "uuids.txt");
if (file.exists()) {
try {
final List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
for (String line : lines) {
try {
line = line.trim();
if (line.isEmpty()) {
continue;
}
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
final String[] split = line.split("\\|");
final String name = split[0];
if (name.isEmpty() || name.length() > 16 || !StringMan.isAlphanumericUnd(name)) {
continue;
}
final UUID old = currentUUIDWrapper.getUUID(name);
if (old == null) {
continue;
}
final UUID now = newWrapper.getUUID(name);
UUIDHandler.add(new StringWrapper(name), now);
uCMap.put(old, now);
uCReverse.put(now, old);
} catch (final Exception e2) {
e2.printStackTrace();
}
}
} catch (final IOException e) {
e.printStackTrace();
}
}
MainUtil.sendMessage(player, "&7 - Replacing wrapper");
UUIDHandler.setUUIDWrapper(newWrapper);
MainUtil.sendMessage(player, "&7 - Updating plot objects");
for (final Plot plot : PS.get().getPlots()) {
final UUID value = uCMap.get(plot.owner);
if (value != null) {
plot.owner = value;
}
plot.getTrusted().clear();
plot.getMembers().clear();
plot.getDenied().clear();
}
MainUtil.sendMessage(player, "&7 - Deleting database");
final AbstractDB database = DBFunc.dbManager;
final boolean result = database.deleteTables();
MainUtil.sendMessage(player, "&7 - Creating tables");
try {
database.createTables();
if (!result) {
MainUtil.sendMessage(player, "&cConversion failed! Attempting recovery");
for (final Plot plot : PS.get().getPlots()) {
final UUID value = uCReverse.get(plot.owner);
if (value != null) {
plot.owner = value;
}
}
database.createPlotsAndData(new ArrayList<>(PS.get().getPlots()), new Runnable() {
@Override
public void run() {
MainUtil.sendMessage(player, "&6Recovery was successful!");
}
});
return;
}
} catch (final Exception e) {
e.printStackTrace();
return;
}
if (newWrapper instanceof OfflineUUIDWrapper) {
PS.get().config.set("UUID.force-lowercase", false);
PS.get().config.set("UUID.offline", true);
} else if (newWrapper instanceof DefaultUUIDWrapper) {
PS.get().config.set("UUID.force-lowercase", false);
PS.get().config.set("UUID.offline", false);
}
try {
PS.get().config.save(PS.get().configFile);
} catch (IOException e) {
MainUtil.sendMessage(player, "Could not save configuration. It will need to be manuall set!");
}
MainUtil.sendMessage(player, "&7 - Populating tables");
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
final ArrayList<Plot> plots = new ArrayList<>(PS.get().getPlots());
database.createPlotsAndData(plots, new Runnable() {
@Override
public void run() {
MainUtil.sendMessage(player, "&aConversion complete!");
}
});
}
});
MainUtil.sendMessage(player, "&aIt is now safe for players to join");
MainUtil.sendMessage(player, "&cConversion is still in progress, you will be notified when it is complete");
}
});
return true;
}
}

View File

@ -2,7 +2,7 @@ package com.plotsquared.bukkit.database.plotme;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import org.bukkit.Bukkit;
@ -15,11 +15,11 @@ import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
public abstract class APlotMeConnector {
public abstract Connection getPlotMeConnection(String plugin, FileConfiguration plotConfig, String dataFolder);
public abstract Connection getPlotMeConnection(final String plugin, final FileConfiguration plotConfig, final String dataFolder);
public abstract HashMap<String, HashMap<PlotId, Plot>> getPlotMePlots(Connection connection) throws SQLException;
public abstract HashMap<String, HashMap<PlotId, Plot>> getPlotMePlots(final Connection connection) throws SQLException;
public abstract boolean accepts(String version);
public abstract boolean accepts(final String version);
public String getWorld(final String world) {
for (final World newworld : Bukkit.getWorlds()) {
@ -30,11 +30,11 @@ public abstract class APlotMeConnector {
return world;
}
public boolean isValidConnection(Connection connection) {
public boolean isValidConnection(final Connection connection) {
return connection != null;
}
public void copyConfig(FileConfiguration plotConfig, String world, String actualWorldName) {
public void copyConfig(final FileConfiguration plotConfig, final String world, final String actualWorldName) {
final Integer pathwidth = plotConfig.getInt("worlds." + world + ".PathWidth"); //
PS.get().config.set("worlds." + actualWorldName + ".road.width", pathwidth);
final Integer plotsize = plotConfig.getInt("worlds." + world + ".PlotSize"); //
@ -42,19 +42,16 @@ public abstract class APlotMeConnector {
final String wallblock = plotConfig.getString("worlds." + world + ".WallBlockId"); //
PS.get().config.set("worlds." + actualWorldName + ".wall.block", wallblock);
final String floor = plotConfig.getString("worlds." + world + ".PlotFloorBlockId"); //
PS.get().config.set("worlds." + actualWorldName + ".plot.floor", Arrays.asList(floor));
PS.get().config.set("worlds." + actualWorldName + ".plot.floor", Collections.singletonList(floor));
final String filling = plotConfig.getString("worlds." + world + ".PlotFillingBlockId"); //
PS.get().config.set("worlds." + actualWorldName + ".plot.filling", Arrays.asList(filling));
PS.get().config.set("worlds." + actualWorldName + ".plot.filling", Collections.singletonList(filling));
final String road = plotConfig.getString("worlds." + world + ".RoadMainBlockId");
PS.get().config.set("worlds." + actualWorldName + ".road.block", road);
Integer height = plotConfig.getInt("worlds." + world + ".RoadHeight"); //
if (height == null) {
height = 64;
}
PS.get().config.set("worlds." + actualWorldName + ".road.height", height);
}
public Location getPlotTopLocAbs(int path, int plot, final PlotId plotid) {
public Location getPlotTopLocAbs(final int path, final int plot, final PlotId plotid) {
final int px = plotid.x;
final int pz = plotid.y;
final int x = (px * (path + plot)) - ((int) Math.floor(path / 2)) - 1;
@ -62,7 +59,7 @@ public abstract class APlotMeConnector {
return new Location(null, x, 256, z);
}
public Location getPlotBottomLocAbs(int path, int plot, final PlotId plotid) {
public Location getPlotBottomLocAbs(final int path, final int plot, final PlotId plotid) {
final int px = plotid.x;
final int pz = plotid.y;
final int x = (px * (path + plot)) - plot - ((int) Math.floor(path / 2)) - 1;
@ -70,8 +67,8 @@ public abstract class APlotMeConnector {
return new Location(null, x, 1, z);
}
public void setMerged(HashMap<String, HashMap<PlotId, boolean[]>> merges, String world, PlotId id, int direction) {
HashMap<PlotId, boolean[]> plots = merges.get(world);
public void setMerged(final HashMap<String, HashMap<PlotId, boolean[]>> merges, final String world, final PlotId id, final int direction) {
final HashMap<PlotId, boolean[]> plots = merges.get(world);
PlotId id2;
switch (direction) {
case 0: {
@ -98,15 +95,13 @@ public abstract class APlotMeConnector {
boolean[] merge2;
if (plots.containsKey(id)) {
merge1 = plots.get(id);
}
else {
merge1 = new boolean[]{false, false, false, false};
} else {
merge1 = new boolean[] { false, false, false, false };
}
if (plots.containsKey(id2)) {
merge2 = plots.get(id2);
}
else {
merge2 = new boolean[]{false, false, false, false};
} else {
merge2 = new boolean[] { false, false, false, false };
}
merge1[direction] = true;
merge2[(direction + 2) % 4] = true;

View File

@ -0,0 +1,267 @@
package com.plotsquared.bukkit.database.plotme;
import com.google.common.base.Charsets;
import com.intellectualcrafters.configuration.file.FileConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.database.SQLite;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.UUIDHandler;
import java.io.File;
import java.nio.ByteBuffer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.UUID;
public class ClassicPlotMeConnector extends APlotMeConnector {
private String plugin;
private String prefix;
@Override
public Connection getPlotMeConnection(final String plugin, final FileConfiguration plotConfig, final String dataFolder) {
this.plugin = plugin.toLowerCase();
prefix = plotConfig.getString("mySQLprefix");
if (prefix == null) {
prefix = plugin.toLowerCase();
}
try {
if (plotConfig.getBoolean("usemySQL")) {
final String user = plotConfig.getString("mySQLuname");
final String password = plotConfig.getString("mySQLpass");
final String con = plotConfig.getString("mySQLconn");
return DriverManager.getConnection(con, user, password);
// return new MySQL(plotsquared, hostname, port, database, username, password)
} else {
return new SQLite(dataFolder + File.separator + "plots.db").openConnection();
}
} catch (SQLException | ClassNotFoundException ignored) {
}
return null;
}
@Override
public HashMap<String, HashMap<PlotId, Plot>> getPlotMePlots(final Connection connection) throws SQLException {
final HashMap<String, Integer> plotWidth = new HashMap<>();
final HashMap<String, Integer> roadWidth = new HashMap<>();
final HashMap<String, HashMap<PlotId, Plot>> plots = new HashMap<>();
final HashMap<String, HashMap<PlotId, boolean[]>> merges = new HashMap<>();
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM `" + prefix + "Plots`");
ResultSet r = stmt.executeQuery();
String column = null;
final boolean checkUUID = DBFunc.hasColumn(r, "ownerid");
final boolean checkUUID2 = DBFunc.hasColumn(r, "ownerId");
if (checkUUID) {
column = "ownerid";
} else if (checkUUID2) {
column = "ownerId";
}
final boolean merge = !"plotme".equalsIgnoreCase(plugin) && Settings.CONVERT_PLOTME;
int missing = 0;
while (r.next()) {
final PlotId id = new PlotId(r.getInt("idX"), r.getInt("idZ"));
final String name = r.getString("owner");
final String world = LikePlotMeConverter.getWorld(r.getString("world"));
if (!plots.containsKey(world)) {
plots.put(world, new HashMap<PlotId, Plot>());
if (merge) {
final int plot = PS.get().config.getInt("worlds." + world + ".plot.size");
final int path = PS.get().config.getInt("worlds." + world + ".road.width");
plotWidth.put(world, plot);
roadWidth.put(world, path);
merges.put(world, new HashMap<PlotId, boolean[]>());
}
}
if (merge) {
final int tx = r.getInt("topX");
final int tz = r.getInt("topZ");
final int bx = r.getInt("bottomX") - 1;
final int bz = r.getInt("bottomZ") - 1;
final int path = roadWidth.get(world);
final int plot = plotWidth.get(world);
final Location top = getPlotTopLocAbs(path, plot, id);
final Location bot = getPlotBottomLocAbs(path, plot, id);
if (tx > top.getX()) {
setMerged(merges, world, id, 1);
}
if (tz > top.getZ()) {
setMerged(merges, world, id, 2);
}
if (bx < bot.getX()) {
setMerged(merges, world, id, 3);
}
if (bz > bot.getZ()) {
setMerged(merges, world, id, 0);
}
}
UUID owner = UUIDHandler.getUUID(name, null);
if (owner == null) {
if ("*".equals(name)) {
owner = DBFunc.everyone;
} else {
if (checkUUID || checkUUID2) {
try {
final byte[] bytes = r.getBytes(column);
if (bytes != null) {
try {
final ByteBuffer bb = ByteBuffer.wrap(bytes);
final long high = bb.getLong();
final long low = bb.getLong();
owner = new UUID(high, low);
} catch (final Exception e) {
e.printStackTrace();
owner = UUID.nameUUIDFromBytes(bytes);
}
UUIDHandler.add(new StringWrapper(name), owner);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
if (owner == null) {
if (!name.isEmpty()) {
owner = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name.toLowerCase()).getBytes(Charsets.UTF_8));
}
PS.log("&cCould not identify owner for plot: " + id + " -> '" + name + "'");
missing++;
continue;
}
}
} else {
UUIDHandler.add(new StringWrapper(name), owner);
}
final Plot plot = new Plot(PlotArea.createGeneric(world), id, owner);
plots.get(world).put(id, plot);
}
if (missing > 0) {
PS.log("&cSome names could not be identified:");
PS.log("&7 - Empty quotes mean PlotMe just stored an unowned plot in the database");
PS.log("&7 - Names you have never seen before could be from people mistyping commands");
PS.log("&7 - Converting from a non-uuid version of PlotMe can't identify owners if the playerdata files are deleted (these plots will remain unknown until the player connects)");
}
for (final Entry<String, HashMap<PlotId, boolean[]>> entry : merges.entrySet()) {
final String world = entry.getKey();
for (final Entry<PlotId, boolean[]> entry2 : entry.getValue().entrySet()) {
final HashMap<PlotId, Plot> newplots = plots.get(world);
final Plot plot = newplots.get(entry2.getKey());
if (plot != null) {
plot.setMerged(entry2.getValue());
}
}
}
r.close();
stmt.close();
try {
PS.log(" - " + prefix + "Denied");
stmt = connection.prepareStatement("SELECT * FROM `" + prefix + "Denied`");
r = stmt.executeQuery();
while (r.next()) {
final PlotId id = new PlotId(r.getInt("idX"), r.getInt("idZ"));
final String name = r.getString("player");
final String world = LikePlotMeConverter.getWorld(r.getString("world"));
UUID denied = UUIDHandler.getUUID(name, null);
if (denied == null) {
if ("*".equals(name)) {
denied = DBFunc.everyone;
} else {
if (DBFunc.hasColumn(r, "playerid")) {
try {
final byte[] bytes = r.getBytes("playerid");
if (bytes != null) {
try {
final ByteBuffer bb = ByteBuffer.wrap(bytes);
final long high = bb.getLong();
final long low = bb.getLong();
denied = new UUID(high, low);
} catch (final Exception e) {
e.printStackTrace();
denied = UUID.nameUUIDFromBytes(bytes);
}
UUIDHandler.add(new StringWrapper(name), denied);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
if (denied == null) {
PS.log("&6Could not identify denied for plot: " + id);
continue;
}
}
if (plots.get(world).containsKey(id)) {
plots.get(world).get(id).getDenied().add(denied);
}
}
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "Allowed`");
r = stmt.executeQuery();
while (r.next()) {
final PlotId id = new PlotId(r.getInt("idX"), r.getInt("idZ"));
final String name = r.getString("player");
final String world = LikePlotMeConverter.getWorld(r.getString("world"));
UUID helper = UUIDHandler.getUUID(name, null);
if (helper == null) {
if ("*".equals(name)) {
helper = DBFunc.everyone;
} else {
if (DBFunc.hasColumn(r, "playerid")) {
try {
final byte[] bytes = r.getBytes("playerid");
if (bytes != null) {
try {
final ByteBuffer bb = ByteBuffer.wrap(bytes);
final long high = bb.getLong();
final long low = bb.getLong();
helper = new UUID(high, low);
} catch (final Exception e) {
e.printStackTrace();
helper = UUID.nameUUIDFromBytes(bytes);
}
UUIDHandler.add(new StringWrapper(name), helper);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
if (helper == null) {
PS.log("&6Could not identify helper for plot: " + id);
continue;
}
}
if (plots.get(world).containsKey(id)) {
plots.get(world).get(id).getTrusted().add(helper);
}
}
r.close();
stmt.close();
} catch (SQLException e) {
}
return plots;
}
@Override
public boolean accepts(final String version) {
return version == null || PS.get().canUpdate(version, "0.17.0") || PS.get().canUpdate("0.999.999", version);
}
}

View File

@ -20,6 +20,22 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.database.plotme;
import com.intellectualcrafters.configuration.MemorySection;
import com.intellectualcrafters.configuration.file.FileConfiguration;
import com.intellectualcrafters.configuration.file.YamlConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.generator.HybridGen;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
@ -29,40 +45,27 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import com.intellectualcrafters.configuration.file.FileConfiguration;
import com.intellectualcrafters.configuration.file.YamlConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.generator.HybridGen;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Created 2014-08-17 for PlotSquared
*
* @author Citymonstret
* @author Empire92
*/
public class LikePlotMeConverter {
private String plugin;
private final String plugin;
/**
* Constructor
*
* @param plugin Plugin Used to run the converter
*/
public LikePlotMeConverter(String plugin) {
public LikePlotMeConverter(final String plugin) {
this.plugin = plugin;
}
@ -87,7 +90,7 @@ public class LikePlotMeConverter {
return new File(".").getAbsolutePath() + File.separator + "plugins" + File.separator + plugin + File.separator;
}
public FileConfiguration getPlotMeConfig(String dataFolder) {
public FileConfiguration getPlotMeConfig(final String dataFolder) {
final File plotMeFile = new File(dataFolder + "config.yml");
if (!plotMeFile.exists()) {
return null;
@ -95,50 +98,75 @@ public class LikePlotMeConverter {
return YamlConfiguration.loadConfiguration(plotMeFile);
}
public Set<String> getPlotMeWorlds(FileConfiguration plotConfig) {
public Set<String> getPlotMeWorlds(final FileConfiguration plotConfig) {
return plotConfig.getConfigurationSection("worlds").getKeys(false);
}
public void updateWorldYml(String plugin, String location) {
public void mergeWorldYml(final String plugin, FileConfiguration plotConfig) {
try {
Path path = Paths.get(location);
File file = new File(location);
File genConfig = new File("plugins" + File.separator + plugin + File.separator + "PlotMe-DefaultGenerator" + File.separator + "config.yml");
if (genConfig.exists()) {
YamlConfiguration yml = YamlConfiguration.loadConfiguration(genConfig);
for (String key : yml.getKeys(true)) {
if (!plotConfig.contains(key)) {
Object value = yml.get(key);
if (!(value instanceof MemorySection)) {
plotConfig.set(key, value);
}
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
public void updateWorldYml(final String plugin, final String location) {
try {
final Path path = Paths.get(location);
final File file = new File(location);
if (!file.exists()) {
return;
}
Charset charset = StandardCharsets.UTF_8;
final Charset charset = StandardCharsets.UTF_8;
String content = new String(Files.readAllBytes(path), charset);
content = content.replaceAll("PlotMe-DefaultGenerator", "PlotSquared");
content = content.replaceAll(plugin, "PlotSquared");
Files.write(path, content.getBytes(charset));
} catch (Exception e) {
} catch (IOException e) {
}
}
public boolean run(final APlotMeConnector connector) {
try {
String dataFolder = getPlotMePath();
FileConfiguration plotConfig = getPlotMeConfig(dataFolder);
final String dataFolder = getPlotMePath();
final FileConfiguration plotConfig = getPlotMeConfig(dataFolder);
if (plotConfig == null) {
return false;
}
String version = plotConfig.getString("Version");
if (version == null) version = plotConfig.getString("version");
if (version == null) {
version = plotConfig.getString("version");
}
if (!connector.accepts(version)) {
return false;
}
PS.debug("&3Using connector: " + connector.getClass().getCanonicalName());
Connection connection = connector.getPlotMeConnection(plugin, plotConfig, dataFolder);
final Connection connection = connector.getPlotMeConnection(plugin, plotConfig, dataFolder);
if (!connector.isValidConnection(connection)) {
sendMessage("Cannot connect to PlotMe DB. Conversion process will not continue");
return false;
}
sendMessage(plugin + " conversion has started. To disable this, please set 'plotme-convert.enabled' in the 'settings.yml'");
sendMessage(plugin + " conversion has started. To disable this, please set 'plotme-convert.enabled' to false in the 'settings.yml'");
mergeWorldYml(plugin, plotConfig);
sendMessage("Connecting to " + plugin + " DB");
int plotCount = 0;
@ -146,7 +174,7 @@ public class LikePlotMeConverter {
sendMessage("Collecting plot data");
String dbPrefix = plugin.toLowerCase();
final String dbPrefix = plugin.toLowerCase();
sendMessage(" - " + dbPrefix + "Plots");
final Set<String> worlds = getPlotMeWorlds(plotConfig);
@ -157,7 +185,7 @@ public class LikePlotMeConverter {
for (final String world : plotConfig.getConfigurationSection("worlds").getKeys(false)) {
sendMessage("Copying config for: " + world);
try {
String actualWorldName = getWorld(world);
final String actualWorldName = getWorld(world);
connector.copyConfig(plotConfig, world, actualWorldName);
PS.get().config.save(PS.get().configFile);
} catch (final Exception e) {
@ -166,8 +194,8 @@ public class LikePlotMeConverter {
}
}
}
HashMap<String, HashMap<PlotId, Plot>> plots = connector.getPlotMePlots(connection);
for (Entry<String, HashMap<PlotId, Plot>> entry : plots.entrySet()) {
final HashMap<String, HashMap<PlotId, Plot>> plots = connector.getPlotMePlots(connection);
for (final Entry<String, HashMap<PlotId, Plot>> entry : plots.entrySet()) {
plotCount += entry.getValue().size();
}
if (!Settings.CONVERT_PLOTME) {
@ -182,15 +210,27 @@ public class LikePlotMeConverter {
final YamlConfiguration PLOTME_DG_YML = YamlConfiguration.loadConfiguration(PLOTME_DG_FILE);
try {
for (final String world : plots.keySet()) {
String actualWorldName = getWorld(world);
final String actualWorldName = getWorld(world);
final String plotMeWorldName = world.toLowerCase();
Integer pathwidth = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".PathWidth"); //
/*
* TODO: dead code
*
if (pathwidth == null) {
pathwidth = 7;
}
*/
PS.get().config.set("worlds." + world + ".road.width", pathwidth);
Integer pathheight = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".RoadHeight"); //
if (pathheight == 0) {
pathheight = 64;
}
PS.get().config.set("worlds." + world + ".road.height", pathheight);
PS.get().config.set("worlds." + world + ".wall.height", pathheight);
PS.get().config.set("worlds." + world + ".plot.height", pathheight);
Integer plotsize = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".PlotSize"); //
if (plotsize == null) {
if (plotsize == 0) {
plotsize = 32;
}
PS.get().config.set("worlds." + world + ".plot.size", plotsize);
@ -203,21 +243,21 @@ public class LikePlotMeConverter {
if (floor == null) {
floor = "2";
}
PS.get().config.set("worlds." + world + ".plot.floor", Arrays.asList(floor));
PS.get().config.set("worlds." + world + ".plot.floor", Collections.singletonList(floor));
String filling = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".FillBlock"); //
if (filling == null) {
filling = "3";
}
PS.get().config.set("worlds." + world + ".plot.filling", Arrays.asList(filling));
PS.get().config.set("worlds." + world + ".plot.filling", Collections.singletonList(filling));
String road = PLOTME_DG_YML.getString("worlds." + plotMeWorldName + ".RoadMainBlock");
if (road == null) {
road = "5";
}
PS.get().config.set("worlds." + world + ".road.block", road);
Integer height = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".RoadHeight"); //
if ((height == null) || (height == 0)) {
if (height == 0) {
height = PLOTME_DG_YML.getInt("worlds." + plotMeWorldName + ".GroundHeight"); //
if ((height == null) || (height == 0)) {
if (height == 0) {
height = 64;
}
}
@ -226,33 +266,62 @@ public class LikePlotMeConverter {
PS.get().config.set("worlds." + actualWorldName + ".wall.height", height);
PS.get().config.save(PS.get().configFile);
}
} catch (final Exception e) {
} catch (IOException e) {
}
}
for (final String world : plots.keySet()) {
for (Entry<String, HashMap<PlotId, Plot>> entry : plots.entrySet()) {
String world = entry.getKey();
PlotArea area = PS.get().getPlotArea(world, null);
int duplicate = 0;
for (final Plot plot : plots.get(world).values()) {
if (PS.get().getPlot(world, plot.id) == null) {
createdPlots.add(plot);
} else {
duplicate++;
if (area != null) {
for (Entry<PlotId, Plot> entry2 : entry.getValue().entrySet()) {
if (area.getOwnedPlotAbs(entry2.getKey()) != null) {
duplicate++;
} else {
createdPlots.add(entry2.getValue());
}
}
}
if (duplicate > 0) {
PS.debug("&c[WARNING] Found " + duplicate + " duplicate plots already in DB for world: '" + world + "'. Have you run the converter already?");
if (duplicate > 0) {
PS.debug("&c[WARNING] Found " + duplicate + " duplicate plots already in DB for world: '" + world + "'. Have you run the converter already?");
}
} else {
if (PS.get().plots_tmp != null) {
HashMap<PlotId, Plot> map = PS.get().plots_tmp.get(world);
if (map != null) {
for (Entry<PlotId, Plot> entry2 : entry.getValue().entrySet()) {
if (map.containsKey(entry2.getKey())) {
duplicate++;
} else {
createdPlots.add(entry2.getValue());
}
}
if (duplicate > 0) {
PS.debug("&c[WARNING] Found " + duplicate + " duplicate plots already in DB for world: '" + world + "'. Have you run the converter already?");
}
continue;
}
}
createdPlots.addAll(entry.getValue().values());
}
}
sendMessage("Creating plot DB");
Thread.sleep(1000);
final AtomicBoolean done = new AtomicBoolean(false);
DBFunc.createPlotsAndData(createdPlots, new Runnable() {
@Override
public void run() {
sendMessage("&aDatabase conversion is now complete!");
PS.debug("&c - Stop the server");
PS.debug("&c - Disable 'plotme-convert.enabled' and 'plotme-convert.cache-uuids' in the settings.yml");
PS.debug("&c - Correct any generator settings that haven't copied to 'settings.yml' properly");
PS.debug("&c - Start the server");
PS.get().setAllPlotsRaw(DBFunc.getPlots());
if (done.get()) {
done();
sendMessage("&aDatabase conversion is now complete!");
PS.debug("&c - Stop the server");
PS.debug("&c - Disable 'plotme-convert.enabled' and 'plotme-convert.cache-uuids' in the settings.yml");
PS.debug("&c - Correct any generator settings that haven't copied to 'settings.yml' properly");
PS.debug("&c - Start the server");
PS.get().setPlots(DBFunc.getPlots());
} else {
sendMessage("&cPlease wait until database conversion is complete. You will be notified with instructions when this happens!");
done.set(true);
}
}
});
sendMessage("Saving configuration...");
@ -279,7 +348,7 @@ public class LikePlotMeConverter {
}
final String actualWorldName = world.getName();
sendMessage("Reloading generator for world: '" + actualWorldName + "'...");
PS.get().removePlotWorld(actualWorldName);
PS.get().removePlotAreas(actualWorldName);
if (MV) {
// unload world with MV
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv unload " + actualWorldName);
@ -304,14 +373,24 @@ public class LikePlotMeConverter {
// Load using Bukkit API
// - User must set generator manually
Bukkit.getServer().unloadWorld(world, true);
final World myworld = WorldCreator.name(actualWorldName).generator(new HybridGen(actualWorldName)).createWorld();
final World myworld = WorldCreator.name(actualWorldName).generator(new BukkitPlotGenerator(new HybridGen())).createWorld();
myworld.save();
}
}
} catch (final Exception e) {
e.printStackTrace();
}
sendMessage("&cPlease wait until database conversion is complete. You will be notified with instructions when this happens!");
if (done.get()) {
done();
sendMessage("&aDatabase conversion is now complete!");
PS.debug("&c - Stop the server");
PS.debug("&c - Disable 'plotme-convert.enabled' and 'plotme-convert.cache-uuids' in the settings.yml");
PS.debug("&c - Correct any generator settings that haven't copied to 'settings.yml' properly");
PS.debug("&c - Start the server");
} else {
sendMessage("&cPlease wait until database conversion is complete. You will be notified with instructions when this happens!");
done.set(true);
}
}
});
} catch (final Exception e) {
@ -320,4 +399,8 @@ public class LikePlotMeConverter {
}
return true;
}
public void done() {
PS.get().setPlots(DBFunc.getPlots());
}
}

View File

@ -0,0 +1,200 @@
package com.plotsquared.bukkit.database.plotme;
import com.intellectualcrafters.configuration.file.FileConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.database.SQLite;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.UUIDHandler;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.UUID;
public class PlotMeConnector_017 extends APlotMeConnector {
private String plugin;
@Override
public Connection getPlotMeConnection(final String plugin, final FileConfiguration plotConfig, final String dataFolder) {
this.plugin = plugin.toLowerCase();
try {
if (plotConfig.getBoolean("usemySQL")) {
final String user = plotConfig.getString("mySQLuname");
final String password = plotConfig.getString("mySQLpass");
final String con = plotConfig.getString("mySQLconn");
return DriverManager.getConnection(con, user, password);
} else {
final File file = new File(dataFolder + File.separator + "plotmecore.db");
if (file.exists()) {
return new SQLite(dataFolder + File.separator + "plotmecore.db").openConnection();
}
return new SQLite(dataFolder + File.separator + "plots.db").openConnection();
}
} catch (SQLException | ClassNotFoundException e) {}
return null;
}
@Override
public HashMap<String, HashMap<PlotId, Plot>> getPlotMePlots(final Connection connection) throws SQLException {
ResultSet r;
PreparedStatement stmt;
final HashMap<String, Integer> plotWidth = new HashMap<>();
final HashMap<String, Integer> roadWidth = new HashMap<>();
final HashMap<Integer, Plot> plots = new HashMap<>();
final HashMap<String, HashMap<PlotId, boolean[]>> merges = new HashMap<>();
try {
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "core_plots`");
r = stmt.executeQuery();
} catch (SQLException e) {
PS.debug("========= Table does not exist =========");
e.printStackTrace();
PS.debug("=======================================");
PS.debug("&8 - &7The database does not match the version specified in the PlotMe config");
PS.debug("&8 - &7Please correct this, or if you are unsure, the most common is 0.16.3");
return null;
}
final boolean checkUUID = DBFunc.hasColumn(r, "ownerID");
final boolean merge = !plugin.equals("plotme") && Settings.CONVERT_PLOTME;
while (r.next()) {
final int key = r.getInt("plot_id");
final PlotId id = new PlotId(r.getInt("plotX"), r.getInt("plotZ"));
final String name = r.getString("owner");
final String world = LikePlotMeConverter.getWorld(r.getString("world"));
if (!plots.containsKey(world)) {
if (merge) {
final int plot = PS.get().config.getInt("worlds." + world + ".plot.size");
final int path = PS.get().config.getInt("worlds." + world + ".road.width");
plotWidth.put(world, plot);
roadWidth.put(world, path);
merges.put(world, new HashMap<PlotId, boolean[]>());
}
}
if (merge) {
final int tx = r.getInt("topX");
final int tz = r.getInt("topZ");
final int bx = r.getInt("bottomX") - 1;
final int bz = r.getInt("bottomZ") - 1;
final int path = roadWidth.get(world);
final int plot = plotWidth.get(world);
final Location top = getPlotTopLocAbs(path, plot, id);
final Location bot = getPlotBottomLocAbs(path, plot, id);
if (tx > top.getX()) {
setMerged(merges, world, id, 1);
}
if (tz > top.getZ()) {
setMerged(merges, world, id, 2);
}
if (bx < bot.getX()) {
setMerged(merges, world, id, 3);
}
if (bz > bot.getZ()) {
setMerged(merges, world, id, 0);
}
}
UUID owner = UUIDHandler.getUUID(name, null);
if (owner == null) {
if (name.equals("*")) {
owner = DBFunc.everyone;
} else {
if (checkUUID) {
try {
final byte[] bytes = r.getBytes("ownerid");
if (bytes != null) {
owner = UUID.nameUUIDFromBytes(bytes);
UUIDHandler.add(new StringWrapper(name), owner);
}
} catch (final Exception e) {
e.printStackTrace();
}
}
if (owner == null) {
PS.log("&cCould not identify owner for plot: " + id + " -> '" + name + "'");
continue;
}
}
} else {
UUIDHandler.add(new StringWrapper(name), owner);
}
final Plot plot = new Plot(PlotArea.createGeneric(world), id, owner);
plots.put(key, plot);
}
for (final Entry<Integer, Plot> entry : plots.entrySet()) {
final Plot plot = entry.getValue();
final HashMap<PlotId, boolean[]> mergeMap = merges.get(plot.getArea().worldname);
if (mergeMap != null) {
if (mergeMap.containsKey(plot.getId())) {
plot.setMerged(mergeMap.get(plot.getId()));
}
}
}
r.close();
stmt.close();
try {
PS.log(" - " + plugin + "core_denied");
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "core_denied`");
r = stmt.executeQuery();
while (r.next()) {
final int key = r.getInt("plot_id");
final Plot plot = plots.get(key);
if (plot == null) {
PS.log("&6Denied (" + key + ") references deleted plot; ignoring entry.");
continue;
}
final UUID denied = UUID.fromString(r.getString("player"));
plot.getDenied().add(denied);
}
PS.log(" - " + plugin + "core_allowed");
stmt = connection.prepareStatement("SELECT * FROM `" + plugin + "core_allowed`");
r = stmt.executeQuery();
while (r.next()) {
final int key = r.getInt("plot_id");
final Plot plot = plots.get(key);
if (plot == null) {
PS.log("&6Allowed (" + key + ") references deleted plot; ignoring entry.");
continue;
}
final UUID allowed = UUID.fromString(r.getString("player"));
plot.getTrusted().add(allowed);
}
r.close();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
final HashMap<String, HashMap<PlotId, Plot>> processed = new HashMap<>();
for (final Entry<Integer, Plot> entry : plots.entrySet()) {
final Plot plot = entry.getValue();
HashMap<PlotId, Plot> map = processed.get(plot.getArea().worldname);
if (map == null) {
map = new HashMap<>();
processed.put(plot.getArea().worldname, map);
}
map.put(plot.getId(), plot);
}
return processed;
}
@Override
public boolean accepts(final String version) {
if (version == null) {
return false;
}
return !PS.get().canUpdate(version, "0.17");
}
}

View File

@ -30,8 +30,8 @@ import com.intellectualcrafters.plot.object.PlotCluster;
/**
* Called when a flag is removed from a plot
*
* @author Citymonstret
* @author Empire92
*/
public class ClusterFlagRemoveEvent extends Event implements Cancellable {
private static HandlerList handlers = new HandlerList();
@ -43,7 +43,7 @@ public class ClusterFlagRemoveEvent extends Event implements Cancellable {
* PlotFlagRemoveEvent: Called when a flag is removed from a plot
*
* @param flag Flag that was removed
* @param plot Plot from which the flag was removed
* @param cluster PlotCluster from which the flag was removed
*/
public ClusterFlagRemoveEvent(final Flag flag, final PlotCluster cluster) {
this.cluster = cluster;
@ -60,7 +60,7 @@ public class ClusterFlagRemoveEvent extends Event implements Cancellable {
* @return PlotCluster
*/
public PlotCluster getCluster() {
return this.cluster;
return cluster;
}
/**
@ -69,7 +69,7 @@ public class ClusterFlagRemoveEvent extends Event implements Cancellable {
* @return Flag
*/
public Flag getFlag() {
return this.flag;
return flag;
}
@Override
@ -79,11 +79,11 @@ public class ClusterFlagRemoveEvent extends Event implements Cancellable {
@Override
public boolean isCancelled() {
return this.cancelled;
return cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
cancelled = b;
}
}

View File

@ -28,8 +28,6 @@ import org.bukkit.event.player.PlayerEvent;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerClaimPlotEvent extends PlayerEvent implements Cancellable {
private static HandlerList handlers = new HandlerList();
@ -59,14 +57,14 @@ public class PlayerClaimPlotEvent extends PlayerEvent implements Cancellable {
* @return Plot
*/
public Plot getPlot() {
return this.plot;
return plot;
}
/**
* @return true if it was an automated claim, else false
*/
public boolean wasAuto() {
return this.auto;
return auto;
}
@Override
@ -76,11 +74,11 @@ public class PlayerClaimPlotEvent extends PlayerEvent implements Cancellable {
@Override
public boolean isCancelled() {
return this.cancelled;
return cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
cancelled = b;
}
}

View File

@ -27,8 +27,6 @@ import org.bukkit.event.player.PlayerEvent;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerEnterPlotEvent extends PlayerEvent {
private static HandlerList handlers = new HandlerList();
@ -55,7 +53,7 @@ public class PlayerEnterPlotEvent extends PlayerEvent {
* @return Plot
*/
public Plot getPlot() {
return this.plot;
return plot;
}
@Override

View File

@ -27,8 +27,6 @@ import org.bukkit.event.player.PlayerEvent;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerLeavePlotEvent extends PlayerEvent {
@ -56,7 +54,7 @@ public class PlayerLeavePlotEvent extends PlayerEvent {
* @return Plot
*/
public Plot getPlot() {
return this.plot;
return plot;
}
@Override

View File

@ -28,8 +28,6 @@ import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerPlotDeniedEvent extends PlotEvent {
@ -63,7 +61,7 @@ public class PlayerPlotDeniedEvent extends PlotEvent {
* @return boolean
*/
public boolean wasAdded() {
return this.added;
return added;
}
/**
@ -72,7 +70,7 @@ public class PlayerPlotDeniedEvent extends PlotEvent {
* @return UUID
*/
public UUID getPlayer() {
return this.player;
return player;
}
/**
@ -81,7 +79,7 @@ public class PlayerPlotDeniedEvent extends PlotEvent {
* @return Player
*/
public Player getInitiator() {
return this.initiator;
return initiator;
}
@Override

View File

@ -28,8 +28,6 @@ import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Empire92
* @author Citymonstret
*/
public class PlayerPlotHelperEvent extends PlotEvent {
@ -63,7 +61,7 @@ public class PlayerPlotHelperEvent extends PlotEvent {
* @return boolean
*/
public boolean wasAdded() {
return this.added;
return added;
}
/**
@ -72,7 +70,7 @@ public class PlayerPlotHelperEvent extends PlotEvent {
* @return UUID
*/
public UUID getPlayer() {
return this.player;
return player;
}
/**
@ -81,7 +79,7 @@ public class PlayerPlotHelperEvent extends PlotEvent {
* @return Player
*/
public Player getInitiator() {
return this.initiator;
return initiator;
}
@Override

View File

@ -28,8 +28,6 @@ import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
/**
* @author Citymonstret
* @author Empire92
*/
public class PlayerPlotTrustedEvent extends PlotEvent {
@ -63,7 +61,7 @@ public class PlayerPlotTrustedEvent extends PlotEvent {
* @return boolean
*/
public boolean wasAdded() {
return this.added;
return added;
}
/**
@ -72,7 +70,7 @@ public class PlayerPlotTrustedEvent extends PlotEvent {
* @return UUID
*/
public UUID getPlayer() {
return this.player;
return player;
}
/**
@ -81,7 +79,7 @@ public class PlayerPlotTrustedEvent extends PlotEvent {
* @return Player
*/
public Player getInitiator() {
return this.initiator;
return initiator;
}
@Override

View File

@ -31,8 +31,6 @@ import com.intellectualcrafters.plot.object.Plot;
/**
* Called when a player teleports to a plot
*
* @author Citymonstret
* @author Empire92
*/
public class PlayerTeleportToPlotEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
@ -68,7 +66,7 @@ public class PlayerTeleportToPlotEvent extends PlayerEvent implements Cancellabl
* @return Location
*/
public Location getFrom() {
return this.from;
return from;
}
/**
@ -77,12 +75,12 @@ public class PlayerTeleportToPlotEvent extends PlayerEvent implements Cancellabl
* @return Plot
*/
public Plot getPlot() {
return this.plot;
return plot;
}
@Override
public boolean isCancelled() {
return this.cancelled;
return cancelled;
}
@Override

View File

@ -21,34 +21,23 @@
package com.plotsquared.bukkit.events;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
/**
* Called when a plot is cleared
*
* @author Citymonstret
* @author Empire92
*/
public class PlotClearEvent extends Event implements Cancellable {
private static HandlerList handlers = new HandlerList();
private final PlotId id;
private final String world;
private boolean cancelled;
/**
* PlotClearEvent: Called when a plot is cleared
*
* @param world The world in which the plot was cleared
* @param id The plot that was cleared
*/
public PlotClearEvent(final String world, final PlotId id) {
this.id = id;
this.world = world;
public class PlotClearEvent extends PlotEvent implements Cancellable {
public PlotClearEvent(Plot plot) {
super(plot);
}
private static HandlerList handlers = new HandlerList();
private boolean cancelled;
public static HandlerList getHandlerList() {
return handlers;
}
@ -59,7 +48,7 @@ public class PlotClearEvent extends Event implements Cancellable {
* @return PlotId
*/
public PlotId getPlotId() {
return this.id;
return getPlot().getId();
}
/**
@ -68,7 +57,7 @@ public class PlotClearEvent extends Event implements Cancellable {
* @return String
*/
public String getWorld() {
return this.world;
return getPlot().getArea().worldname;
}
@Override
@ -78,11 +67,11 @@ public class PlotClearEvent extends Event implements Cancellable {
@Override
public boolean isCancelled() {
return this.cancelled;
return cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
cancelled = b;
}
}

View File

@ -20,33 +20,22 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.events;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
/**
* Called when a plot is deleted
*
* @author Citymonstret
* @author Empire92
*/
public class PlotDeleteEvent extends Event {
private static HandlerList handlers = new HandlerList();
private final PlotId id;
private final String world;
/**
* PlotDeleteEvent: Called when a plot is deleted
*
* @param world The world in which the plot was deleted
* @param id The ID of the plot that was deleted
*/
public PlotDeleteEvent(final String world, final PlotId id) {
this.id = id;
this.world = world;
public class PlotDeleteEvent extends PlotEvent {
public PlotDeleteEvent(Plot plot) {
super(plot);
}
private static HandlerList handlers = new HandlerList();
public static HandlerList getHandlerList() {
return handlers;
}
@ -57,7 +46,7 @@ public class PlotDeleteEvent extends Event {
* @return PlotId
*/
public PlotId getPlotId() {
return this.id;
return getPlot().getId();
}
/**
@ -66,7 +55,7 @@ public class PlotDeleteEvent extends Event {
* @return String
*/
public String getWorld() {
return this.world;
return getPlot().getArea().worldname;
}
@Override

View File

@ -13,7 +13,7 @@ public abstract class PlotEvent extends Event {
}
public final Plot getPlot() {
return this.plot;
return plot;
}
}

View File

@ -29,8 +29,6 @@ import com.intellectualcrafters.plot.object.Plot;
/**
* Called when a Flag is added to a plot
*
* @author Citymonstret
* @author Empire92
*/
public class PlotFlagAddEvent extends PlotEvent implements Cancellable {
@ -59,7 +57,7 @@ public class PlotFlagAddEvent extends PlotEvent implements Cancellable {
* @return Flag
*/
public Flag getFlag() {
return this.flag;
return flag;
}
@Override
@ -69,11 +67,11 @@ public class PlotFlagAddEvent extends PlotEvent implements Cancellable {
@Override
public final boolean isCancelled() {
return this.cancelled;
return cancelled;
}
@Override
public final void setCancelled(boolean cancelled) {
public final void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
}

View File

@ -29,8 +29,6 @@ import com.intellectualcrafters.plot.object.Plot;
/**
* Called when a flag is removed from a plot
*
* @author Citymonstret
* @author Empire92
*/
public class PlotFlagRemoveEvent extends PlotEvent implements Cancellable {
@ -53,14 +51,13 @@ public class PlotFlagRemoveEvent extends PlotEvent implements Cancellable {
return handlers;
}
/**
* Get the flag involved
*
* @return Flag
*/
public Flag getFlag() {
return this.flag;
return flag;
}
@Override
@ -70,11 +67,11 @@ public class PlotFlagRemoveEvent extends PlotEvent implements Cancellable {
@Override
public final boolean isCancelled() {
return this.cancelled;
return cancelled;
}
@Override
public final void setCancelled(boolean cancelled) {
public final void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
}

View File

@ -31,7 +31,6 @@ import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotId;
/**
* @author Empire92
*/
public class PlotMergeEvent extends Event implements Cancellable {
private static HandlerList handlers = new HandlerList();
@ -61,7 +60,7 @@ public class PlotMergeEvent extends Event implements Cancellable {
* @return Plot
*/
public ArrayList<PlotId> getPlots() {
return this.plots;
return plots;
}
/**
@ -70,11 +69,11 @@ public class PlotMergeEvent extends Event implements Cancellable {
* @return Plot
*/
public Plot getPlot() {
return this.plot;
return plot;
}
public World getWorld() {
return this.world;
return world;
}
@Override
@ -84,11 +83,11 @@ public class PlotMergeEvent extends Event implements Cancellable {
@Override
public boolean isCancelled() {
return this.cancelled;
return cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
cancelled = b;
}
}

View File

@ -9,7 +9,6 @@ import com.intellectualcrafters.plot.object.Rating;
/**
* Created 2015-07-13 for PlotSquaredGit
*
* @author Citymonstret
*/
public class PlotRateEvent extends PlotEvent {
@ -28,15 +27,15 @@ public class PlotRateEvent extends PlotEvent {
}
public PlotPlayer getRater() {
return this.rater;
return rater;
}
public void setRating(Rating rating) {
public void setRating(final Rating rating) {
this.rating = rating;
}
public Rating getRating() {
return this.rating;
return rating;
}
@Override

View File

@ -27,16 +27,17 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotId;
/**
* @author Empire92
*/
public class PlotUnlinkEvent extends Event implements Cancellable {
private static HandlerList handlers = new HandlerList();
private final ArrayList<PlotId> plots;
private final World world;
private boolean cancelled;
private final PlotArea area;
/**
* Called when a mega-plot is unlinked.
@ -44,9 +45,10 @@ public class PlotUnlinkEvent extends Event implements Cancellable {
* @param world World in which the event occurred
* @param plots Plots that are involved in the event
*/
public PlotUnlinkEvent(final World world, final ArrayList<PlotId> plots) {
public PlotUnlinkEvent(final World world, PlotArea area, final ArrayList<PlotId> plots) {
this.plots = plots;
this.world = world;
this.area = area;
}
public static HandlerList getHandlerList() {
@ -59,11 +61,15 @@ public class PlotUnlinkEvent extends Event implements Cancellable {
* @return PlotId
*/
public ArrayList<PlotId> getPlots() {
return this.plots;
return plots;
}
public World getWorld() {
return this.world;
return world;
}
public PlotArea getArea() {
return area;
}
@Override
@ -73,11 +79,11 @@ public class PlotUnlinkEvent extends Event implements Cancellable {
@Override
public boolean isCancelled() {
return this.cancelled;
return cancelled;
}
@Override
public void setCancelled(final boolean b) {
this.cancelled = b;
cancelled = b;
}
}

View File

@ -0,0 +1,33 @@
package com.plotsquared.bukkit.generator;
import com.intellectualcrafters.plot.generator.AugmentedUtils;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.generator.BlockPopulator;
import java.util.Random;
public class BukkitAugmentedGenerator extends BlockPopulator {
private static BukkitAugmentedGenerator generator;
private BukkitAugmentedGenerator() {}
public static BukkitAugmentedGenerator get(World world) {
for (BlockPopulator populator : world.getPopulators()) {
if (populator instanceof BukkitAugmentedGenerator) {
return (BukkitAugmentedGenerator) populator;
}
}
if (generator == null) {
generator = new BukkitAugmentedGenerator();
}
world.getPopulators().add(generator);
return generator;
}
@Override
public void populate(final World world, Random r, final Chunk chunk) {
AugmentedUtils.generate(world.getName(), chunk.getX(), chunk.getZ(), null);
}
}

View File

@ -0,0 +1,330 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.generator;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
import com.intellectualcrafters.plot.generator.HybridGen;
import com.intellectualcrafters.plot.generator.IndependentPlotGenerator;
import com.intellectualcrafters.plot.object.*;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.SetQueue;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.block.GenChunk;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> {
private final PlotChunk<Chunk> chunkSetter;
private final PseudoRandom random = new PseudoRandom();
private final IndependentPlotGenerator plotGenerator;
private final List<BlockPopulator> populators = new ArrayList<>();
private boolean loaded = false;
private ChunkGenerator platformGenerator;
private boolean full;
public BukkitPlotGenerator(IndependentPlotGenerator generator) {
this.plotGenerator = generator;
this.platformGenerator = this;
populators.add(new BlockPopulator() {
@Override
public void populate(World world, Random r, Chunk c) {
if (!(chunkSetter instanceof GenChunk)) {
PS.debug("Current PlotChunk is not relevant to population?");
PS.stacktrace();
return;
}
GenChunk result = (GenChunk) chunkSetter;
if (result.result_data != null) {
for (int i = 0; i < result.result_data.length; i++) {
byte[] section = result.result_data[i];
if (section == null) {
continue;
}
for (int j = 0; j < section.length; j++) {
int x = MainUtil.x_loc[i][j];
int y = MainUtil.y_loc[i][j];
int z = MainUtil.z_loc[i][j];
c.getBlock(x, y, z).setData(section[j]);
}
}
}
}
});
chunkSetter = new GenChunk(null, null);
this.full = true;
MainUtil.initCache();
}
public BukkitPlotGenerator(final String world, final ChunkGenerator cg) {
if (cg instanceof BukkitPlotGenerator) {
throw new IllegalArgumentException("ChunkGenerator: " + cg.getClass().getName() + " is already a BukkitPlotGenerator!");
}
this.full = false;
PS.get().debug("BukkitPlotGenerator does not fully support: " + cg);
platformGenerator = cg;
plotGenerator = new IndependentPlotGenerator() {
@Override
public void processSetup(SetupObject setup) {}
@Override
public void initialize(PlotArea area) {}
@Override
public PlotManager getNewPlotManager() {
return new HybridGen().getNewPlotManager();
}
@Override
public String getName() {
return cg.getClass().getName();
}
@Override
public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) {
return new HybridGen().getNewPlotArea(world, id, min, max);
}
@Override
public void generateChunk(final PlotChunk<?> result, final PlotArea settings, final PseudoRandom random) {
World w = BukkitUtil.getWorld(world);
Random r = new Random(result.getChunkWrapper().hashCode());
BiomeGrid grid = new BiomeGrid() {
@Override
public void setBiome(int x, int z, Biome biome) {
result.setBiome(x, z, biome.ordinal());
}
@Override
public Biome getBiome(int arg0, int arg1) {
return Biome.FOREST;
}
};
try {
// ChunkData will spill a bit
ChunkData data = cg.generateChunkData(w, r, result.getX(), result.getZ(), grid);
if (data != null) {
return;
}
}
catch (Throwable e) {}
// Populator spillage
short[][] tmp = cg.generateExtBlockSections(w, r, result.getX(), result.getZ(), grid);
if (tmp != null) {
for (int i = 0; i < tmp.length; i++) {
short[] section = tmp[i];
if (section == null) {
if (i < 7) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = i << 4; y < (i << 4) + 16; y++) {
result.setBlock(x, y, z, (short) 0, (byte) 0);
}
}
}
}
continue;
}
for (int j = 0; j < section.length; j++) {
int x = MainUtil.x_loc[i][j];
int y = MainUtil.y_loc[i][j];
int z = MainUtil.z_loc[i][j];
result.setBlock(x, y, z, section[j], (byte) 0);
}
}
}
for (BlockPopulator populator : cg.getDefaultPopulators(w)) {
populator.populate(w, r, (Chunk) result.getChunk());
}
}
};
chunkSetter = new GenChunk(null, SetQueue.IMP.new ChunkWrapper(world, 0, 0));
if (cg != null) {
populators.addAll(cg.getDefaultPopulators(BukkitUtil.getWorld(world)));
}
MainUtil.initCache();
}
@Override
public void augment(PlotArea area) {
BukkitAugmentedGenerator.get(BukkitUtil.getWorld(area.worldname));
}
@Override
public boolean isFull() {
return full;
}
@Override
public IndependentPlotGenerator getPlotGenerator() {
return plotGenerator;
}
@Override
public ChunkGenerator getPlatformGenerator() {
return platformGenerator;
}
@Override
public List<BlockPopulator> getDefaultPopulators(final World world) {
try {
if (!loaded) {
final String name = world.getName();
PS.get().loadWorld(name, this);
Set<PlotArea> areas = PS.get().getPlotAreas(name);
if (!areas.isEmpty()) {
PlotArea area = areas.iterator().next();
if (!area.MOB_SPAWNING) {
if (!area.SPAWN_EGGS) {
world.setSpawnFlags(false, false);
}
world.setAmbientSpawnLimit(0);
world.setAnimalSpawnLimit(0);
world.setMonsterSpawnLimit(0);
world.setWaterAnimalSpawnLimit(0);
} else {
world.setSpawnFlags(true, true);
world.setAmbientSpawnLimit(-1);
world.setAnimalSpawnLimit(-1);
world.setMonsterSpawnLimit(-1);
world.setWaterAnimalSpawnLimit(-1);
}
}
loaded = true;
}
} catch (final Exception e) {
e.printStackTrace();
}
return populators;
}
@Override
public ChunkData generateChunkData(World world, Random random, int cx, int cz, BiomeGrid grid) {
if (!(chunkSetter instanceof GenChunk)) {
PS.debug("Current PlotChunk is not relevant to generation?");
PS.stacktrace();
return null;
}
GenChunk result = (GenChunk) chunkSetter;
// Set the chunk location
result.setChunkWrapper(SetQueue.IMP.new ChunkWrapper(world.getName(), cx, cz));
// Set the result data
result.cd = createChunkData(world);
result.grid = grid;
// Catch any exceptions (as exceptions usually thrown
try {
// Fill the result data if necessary
if (platformGenerator != this) {
return platformGenerator.generateChunkData(world, random, cx, cz, grid);
} else {
generate(world, cx, cz, result);
}
} catch (Throwable e) {
e.printStackTrace();
}
// Return the result data
return result.cd;
}
public void generate(World world, int cx, int cz, GenChunk result) {
// Load if improperly loaded
if (!loaded) {
final String name = world.getName();
PS.get().loadWorld(name, this);
loaded = true;
}
// Set random seed
this.random.state = (cx << 16) | (cz & 0xFFFF);
// Process the chunk
result.modified = false;
ChunkManager.preProcessChunk(result);
if (result.modified) {
return;
}
PlotArea area = PS.get().getPlotArea(world.getName(), null);
plotGenerator.generateChunk(chunkSetter, area, this.random);
ChunkManager.postProcessChunk(result);
return;
}
@Override
public short[][] generateExtBlockSections(final World world, final Random r, final int cx, final int cz, final BiomeGrid grid) {
if (!(chunkSetter instanceof GenChunk)) {
PS.stacktrace();
return new short[16][];
}
GenChunk result = (GenChunk) chunkSetter;
// Set the chunk location
result.setChunkWrapper(SetQueue.IMP.new ChunkWrapper(world.getName(), cx, cz));
// Set the result data
result.result = new short[16][];
result.result_data = new byte[16][];
result.grid = grid;
// Catch any exceptions (as exceptions usually thrown
try {
// Fill the result data
if (platformGenerator != this) {
return platformGenerator.generateExtBlockSections(world, r, cx, cz, grid);
} else {
generate(world, cx, cz, result);
}
} catch (Throwable e) {
e.printStackTrace();
}
// Return the result data
return result.result;
}
/**
* Allow spawning everywhere
*/
@Override
public boolean canSpawn(final World world, final int x, final int z) {
return true;
}
@Override
public String toString() {
if (platformGenerator == this) {
return "" + plotGenerator;
}
return platformGenerator == null ? "null" : platformGenerator.getClass().getName();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
return (toString().equals(obj.toString()) || toString().equals(obj.getClass().getName()));
}
}

View File

@ -0,0 +1,325 @@
package com.plotsquared.bukkit.listeners;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefField;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Map.Entry;
public class ChunkListener implements Listener {
private final RefClass classChunk = getRefClass("{nms}.Chunk");
private final RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
private final RefField mustSave = classChunk.getField("mustSave");
private Chunk lastChunk = null;
private RefMethod methodGetHandleChunk;
public ChunkListener() {
RefMethod method;
try {
method = classCraftChunk.getMethod("getHandle");
} catch (final Exception e) {
method = null;
e.printStackTrace();
}
methodGetHandleChunk = method;
if (!Settings.CHUNK_PROCESSOR_GC) {
return;
}
TaskManager.runTask(new Runnable() {
@Override
public void run() {
final int distance = Bukkit.getViewDistance() + 2;
final HashMap<String, HashMap<ChunkLoc, Integer>> players = new HashMap<>();
for (final Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
final PlotPlayer pp = entry.getValue();
final Location loc = pp.getLocation();
final String world = loc.getWorld();
if (!PS.get().hasPlotArea(world)) {
continue;
}
HashMap<ChunkLoc, Integer> map = players.get(world);
if (map == null) {
map = new HashMap<>();
players.put(world, map);
}
final ChunkLoc origin = new ChunkLoc(loc.getX() >> 4, loc.getZ() >> 4);
Integer val = map.get(origin);
int check;
if (val != null) {
if (val == distance) {
continue;
}
check = distance - val;
} else {
check = distance;
map.put(origin, distance);
}
for (int x = -distance; x <= distance; x++) {
if (x >= check || -x >= check) {
continue;
}
for (int z = -distance; z <= distance; z++) {
if (z >= check || -z >= check) {
continue;
}
final int weight = distance - Math.max(Math.abs(x), Math.abs(z));
final ChunkLoc chunk = new ChunkLoc(x + origin.x, z + origin.z);
val = map.get(chunk);
if (val == null || val < weight) {
map.put(chunk, weight);
}
}
}
}
int time = 300;
for (final World world : Bukkit.getWorlds()) {
final String name = world.getName();
if (!PS.get().hasPlotArea(name)) {
continue;
}
final boolean autosave = world.isAutoSave();
if (autosave) {
world.setAutoSave(false);
}
final HashMap<ChunkLoc, Integer> map = players.get(name);
if (map == null || map.isEmpty()) {
continue;
}
Chunk[] chunks = world.getLoadedChunks();
ArrayDeque<Chunk> toUnload = new ArrayDeque<>();
for (final Chunk chunk : chunks) {
final int x = chunk.getX();
final int z = chunk.getZ();
if (!map.containsKey(new ChunkLoc(x, z))) {
toUnload.add(chunk);
}
}
if (!toUnload.isEmpty()) {
long start = System.currentTimeMillis();
Chunk chunk;
while ((chunk = toUnload.poll()) != null && System.currentTimeMillis() - start < 5) {
if (!Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE || !unloadChunk(name, chunk)) {
if (chunk.isLoaded()) {
chunk.unload(true, false);
}
}
}
if (!toUnload.isEmpty()) {
time = 1;
}
}
if (!Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE && autosave) {
world.setAutoSave(true);
}
}
TaskManager.runTaskLater(this, time);
}
});
}
public boolean unloadChunk(final String world, final Chunk chunk) {
final int X = chunk.getX();
final int Z = chunk.getZ();
final int x = X << 4;
final int z = Z << 4;
final int x2 = x + 15;
final int z2 = z + 15;
Plot plot = new Location(world, x, 1, z).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return false;
}
plot = new Location(world, x2, 1, z2).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return false;
}
plot = new Location(world, x2, 1, z).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return false;
}
plot = new Location(world, x, 1, z2).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return false;
}
plot = new Location(world, x + 7, 1, z + 7).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return false;
}
final Object c = methodGetHandleChunk.of(chunk).call();
mustSave.of(c).set(false);
if (chunk.isLoaded()) {
chunk.unload(false, false);
}
return true;
}
@EventHandler
public void onChunkUnload(final ChunkUnloadEvent event) {
if (Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE) {
final Chunk chunk = event.getChunk();
final String world = chunk.getWorld().getName();
if (PS.get().hasPlotArea(world)) {
if (unloadChunk(world, chunk)) {
return;
}
}
}
if (processChunk(event.getChunk(), true)) {
event.setCancelled(true);
}
}
@EventHandler
public void onChunkLoad(final ChunkLoadEvent event) {
processChunk(event.getChunk(), false);
}
@EventHandler(priority = EventPriority.LOWEST)
public void onItemSpawn(final ItemSpawnEvent event) {
final Item entity = event.getEntity();
final Chunk chunk = entity.getLocation().getChunk();
if (chunk == lastChunk) {
event.getEntity().remove();
event.setCancelled(true);
return;
}
if (!PS.get().hasPlotArea(chunk.getWorld().getName())) {
return;
}
final Entity[] entities = chunk.getEntities();
if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
event.getEntity().remove();
event.setCancelled(true);
lastChunk = chunk;
} else {
lastChunk = null;
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockPhysics(final BlockPhysicsEvent event) {
if (Settings.CHUNK_PROCESSOR_DISABLE_PHYSICS) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onEntitySpawn(final CreatureSpawnEvent event) {
final LivingEntity entity = event.getEntity();
final Chunk chunk = entity.getLocation().getChunk();
if (chunk == lastChunk) {
event.getEntity().remove();
event.setCancelled(true);
return;
}
if (!PS.get().hasPlotArea(chunk.getWorld().getName())) {
return;
}
final Entity[] entities = chunk.getEntities();
if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
event.getEntity().remove();
event.setCancelled(true);
lastChunk = chunk;
} else {
lastChunk = null;
}
}
public void cleanChunk(final Chunk chunk) {
TaskManager.index.incrementAndGet();
final Integer currentIndex = TaskManager.index.get();
final Integer task = TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (!chunk.isLoaded()) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PS.debug("[PlotSquared] &aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
final BlockState[] tiles = chunk.getTileEntities();
if (tiles.length == 0) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PS.debug("[PlotSquared] &aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
final long start = System.currentTimeMillis();
int i = 0;
while (System.currentTimeMillis() - start < 250) {
if (i >= tiles.length) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
TaskManager.tasks.remove(currentIndex);
PS.debug("[PlotSquared] &aSuccessfully processed and unloaded chunk!");
chunk.unload(true, true);
return;
}
tiles[i].getBlock().setType(Material.AIR, false);
i++;
}
}
}, 5);
TaskManager.tasks.put(currentIndex, task);
}
public boolean processChunk(final Chunk chunk, final boolean unload) {
if (!PS.get().hasPlotArea(chunk.getWorld().getName())) {
return false;
}
final Entity[] entities = chunk.getEntities();
final BlockState[] tiles = chunk.getTileEntities();
if (entities.length > Settings.CHUNK_PROCESSOR_MAX_ENTITIES) {
for (final Entity ent : entities) {
if (!(ent instanceof Player)) {
ent.remove();
}
}
PS.debug("[PlotSquared] &a detected unsafe chunk and processed: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
}
if (tiles.length > Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES) {
if (unload) {
PS.debug("[PlotSquared] &c detected unsafe chunk: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
cleanChunk(chunk);
return true;
}
for (final BlockState tile : tiles) {
tile.getBlock().setType(Material.AIR, false);
}
}
return false;
}
}

View File

@ -34,48 +34,45 @@ import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.plotsquared.bukkit.events.PlayerEnterPlotEvent;
import com.plotsquared.bukkit.util.BukkitPlayerFunctions;
import com.plotsquared.bukkit.object.BukkitPlayer;
import com.plotsquared.bukkit.util.BukkitUtil;
/**
* @author Citymonstret
*/
public class ForceFieldListener implements Listener {
private Set<Player> getNearbyPlayers(final Player player, final Plot plot) {
final Set<Player> players = new HashSet<>();
Player oPlayer;
private Set<PlotPlayer> getNearbyPlayers(final Player player, final Plot plot) {
final Set<PlotPlayer> players = new HashSet<>();
PlotPlayer pp;
for (final Entity entity : player.getNearbyEntities(5d, 5d, 5d)) {
if (!(entity instanceof Player) || ((oPlayer = (Player) entity) == null) || !BukkitPlayerFunctions.isInPlot(oPlayer) || !BukkitPlayerFunctions.getCurrentPlot(oPlayer).equals(plot)) {
if (!(entity instanceof Player) || ((pp = BukkitUtil.getPlayer((Player) entity)) == null) || !plot.equals(pp.getCurrentPlot())) {
continue;
}
final UUID uuid = UUIDHandler.getUUID(BukkitUtil.getPlayer(oPlayer));
if (!plot.isAdded(uuid)) {
players.add(oPlayer);
if (!plot.isAdded(pp.getUUID())) {
players.add(pp);
}
}
return players;
}
private Player hasNearbyPermitted(final Player player, final Plot plot) {
Player oPlayer;
private PlotPlayer hasNearbyPermitted(final Player player, final Plot plot) {
PlotPlayer pp;
for (final Entity entity : player.getNearbyEntities(5d, 5d, 5d)) {
if (!(entity instanceof Player) || ((oPlayer = (Player) entity) == null) || !BukkitPlayerFunctions.isInPlot(oPlayer) || !BukkitPlayerFunctions.getCurrentPlot(oPlayer).equals(plot)) {
if (!(entity instanceof Player) || ((pp = BukkitUtil.getPlayer((Player) entity)) == null) || !plot.equals(pp.getCurrentPlot())) {
continue;
}
final UUID uuid = UUIDHandler.getUUID(BukkitUtil.getPlayer(oPlayer));
if (plot.isAdded(uuid)) {
return oPlayer;
if (plot.isAdded(pp.getUUID())) {
return pp;
}
}
return null;
}
public Vector calculateVelocity(final Player p, final Player e) {
final org.bukkit.Location playerLocation = p.getLocation();
final org.bukkit.Location oPlayerLocation = e.getLocation();
final double playerX = playerLocation.getX(), playerY = playerLocation.getY(), playerZ = playerLocation.getZ(), oPlayerX = oPlayerLocation.getX(), oPlayerY = oPlayerLocation.getY(), oPlayerZ = oPlayerLocation.getZ();
public Vector calculateVelocity(final PlotPlayer pp, final PlotPlayer e) {
Location playerLocation = pp.getLocationFull();
Location oPlayerLocation = e.getLocation();
final double playerX = playerLocation.getX(), playerY = playerLocation.getY(), playerZ = playerLocation.getZ(), oPlayerX = oPlayerLocation.getX(), oPlayerY = oPlayerLocation.getY(), oPlayerZ = oPlayerLocation
.getZ();
double x = 0d, y = 0d, z = 0d;
if (playerX < oPlayerX) {
x = 1.0d;
@ -99,25 +96,24 @@ public class ForceFieldListener implements Listener {
public void onPlotEntry(final PlayerEnterPlotEvent event) {
final Player player = event.getPlayer();
final PlotPlayer pp = BukkitUtil.getPlayer(player);
final Location loc = pp.getLocation();
final Plot plot = event.getPlot();
if (plot == null) {
return;
}
if ((FlagManager.getPlotFlag(plot, "forcefield") != null) && FlagManager.getPlotFlag(plot, "forcefield").getValue().equals("true")) {
if ((FlagManager.getPlotFlagRaw(plot, "forcefield") != null) && FlagManager.getPlotFlagRaw(plot, "forcefield").getValue().equals("true")) {
if (!FlagManager.isBooleanFlag(plot, "forcefield", false)) {
final UUID uuid = pp.getUUID();
if (plot.isAdded(uuid)) {
final Set<Player> players = getNearbyPlayers(player, plot);
for (final Player oPlayer : players) {
oPlayer.setVelocity(calculateVelocity(player, oPlayer));
final Set<PlotPlayer> players = getNearbyPlayers(player, plot);
for (final PlotPlayer oPlayer : players) {
((BukkitPlayer) oPlayer).player.setVelocity(calculateVelocity(pp, oPlayer));
}
} else {
final Player oPlayer = hasNearbyPermitted(player, plot);
final PlotPlayer oPlayer = hasNearbyPermitted(player, plot);
if (oPlayer == null) {
return;
}
player.setVelocity(calculateVelocity(oPlayer, player));
player.setVelocity(calculateVelocity(oPlayer, pp));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,7 @@ import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
@ -33,34 +34,34 @@ import com.plotsquared.listener.PlotListener;
public class PlayerEvents_1_8 extends PlotListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onInventoryClick(InventoryClickEvent event) {
if (!event.isLeftClick() || event.getAction() != InventoryAction.PLACE_ALL || event.isShiftClick()) {
public void onInventoryClick(final InventoryClickEvent event) {
if (!event.isLeftClick() || (event.getAction() != InventoryAction.PLACE_ALL) || event.isShiftClick()) {
return;
}
HumanEntity entity = event.getWhoClicked();
if (!(entity instanceof Player) || !PS.get().isPlotWorld(entity.getWorld().getName())) {
final HumanEntity entity = event.getWhoClicked();
if (!(entity instanceof Player) || !PS.get().hasPlotArea(entity.getWorld().getName())) {
return;
}
Player player = (Player) entity;
PlayerInventory inv = player.getInventory();
int slot = inv.getHeldItemSlot();
if (slot != event.getSlot() || slot > 8 || !event.getEventName().equals("InventoryCreativeEvent")) {
final Player player = (Player) entity;
final PlayerInventory inv = player.getInventory();
final int slot = inv.getHeldItemSlot();
if ((slot != event.getSlot()) || (slot > 8) || !event.getEventName().equals("InventoryCreativeEvent")) {
return;
}
ItemStack current = inv.getItemInHand();
ItemStack newItem = event.getCursor();
ItemMeta newMeta = newItem.getItemMeta();
ItemMeta oldMeta = newItem.getItemMeta();
final ItemStack current = inv.getItemInHand();
final ItemStack newItem = event.getCursor();
final ItemMeta newMeta = newItem.getItemMeta();
final ItemMeta oldMeta = newItem.getItemMeta();
String newLore = "";
if (newMeta != null) {
List<String> lore = newMeta.getLore();
final List<String> lore = newMeta.getLore();
if (lore != null) {
newLore = lore.toString();
}
}
String oldLore = "";
if (oldMeta != null) {
List<String> lore = oldMeta.getLore();
final List<String> lore = oldMeta.getLore();
if (lore != null) {
oldLore = lore.toString();
}
@ -68,9 +69,9 @@ public class PlayerEvents_1_8 extends PlotListener implements Listener {
if (!newLore.equals("[(+NBT)]") || (current.equals(newItem) && newLore.equals(oldLore))) {
return;
}
HashSet<Byte> blocks = null;
Block block = player.getTargetBlock(blocks, 7);
BlockState state = block.getState();
final HashSet<Byte> blocks = null;
final Block block = player.getTargetBlock(blocks, 7);
final BlockState state = block.getState();
if (state == null) {
return;
}
@ -78,26 +79,25 @@ public class PlayerEvents_1_8 extends PlotListener implements Listener {
return;
}
final Location l = BukkitUtil.getLocation(state.getLocation());
Plot plot = MainUtil.getPlot(l);
PlotPlayer pp = BukkitUtil.getPlayer(player);
PlotArea area = l.getPlotArea();
if (area == null) {
return;
}
final Plot plot = area.getPlotAbs(l);
final PlotPlayer pp = BukkitUtil.getPlayer(player);
boolean cancelled = false;
if (plot == null) {
if (!MainUtil.isPlotArea(l)) {
return;
}
if (!Permissions.hasPermission(pp, "plots.admin.interact.road")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, "plots.admin.interact.road");
cancelled = true;
}
}
else {
} else {
if (!plot.hasOwner()) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.unowned")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, "plots.admin.interact.unowned");
cancelled = true;
}
}
else {
} else {
final UUID uuid = pp.getUUID();
if (!plot.isAdded(uuid)) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.other")) {
@ -108,7 +108,7 @@ public class PlayerEvents_1_8 extends PlotListener implements Listener {
}
}
if (cancelled) {
if (current.getTypeId() == newItem.getTypeId() && current.getDurability() == newItem.getDurability()) {
if ((current.getTypeId() == newItem.getTypeId()) && (current.getDurability() == newItem.getDurability())) {
event.setCursor(new ItemStack(newItem.getTypeId(), newItem.getAmount(), newItem.getDurability()));
event.setCancelled(true);
return;
@ -119,34 +119,29 @@ public class PlayerEvents_1_8 extends PlotListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onInteract(final PlayerInteractAtEntityEvent e) {
Entity entity = e.getRightClicked();
final Entity entity = e.getRightClicked();
if (!(entity instanceof ArmorStand)) {
return;
}
final Location l = BukkitUtil.getLocation(e.getRightClicked().getLocation());
String world = l.getWorld();
if (!PS.get().isPlotWorld(world)) {
final PlotArea area = l.getPlotArea();
if (area == null) {
return;
}
Plot plot = MainUtil.getPlot(l);
PlotPlayer pp = BukkitUtil.getPlayer(e.getPlayer());
final Plot plot = area.getPlotAbs(l);
final PlotPlayer pp = BukkitUtil.getPlayer(e.getPlayer());
if (plot == null) {
if (!MainUtil.isPlotArea(l)) {
return;
}
if (!Permissions.hasPermission(pp, "plots.admin.interact.road")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, "plots.admin.interact.road");
e.setCancelled(true);
}
}
else {
} else {
if (!plot.hasOwner()) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.unowned")) {
MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, "plots.admin.interact.unowned");
e.setCancelled(true);
}
}
else {
} else {
final UUID uuid = pp.getUUID();
if (!plot.isAdded(uuid)) {
if (!Permissions.hasPermission(pp, "plots.admin.interact.other")) {

View File

@ -1,52 +1,50 @@
package com.plotsquared.bukkit.listeners;
import java.util.Iterator;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.plotsquared.bukkit.util.BukkitUtil;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockExplodeEvent;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.util.MainUtil;
import com.plotsquared.bukkit.util.BukkitUtil;
import java.util.Iterator;
public class PlayerEvents_1_8_3 implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBigBoom(final BlockExplodeEvent event) {
Block block = event.getBlock();
final Block block = event.getBlock();
Location loc = BukkitUtil.getLocation(block.getLocation());
final String world = loc.getWorld();
if (!PS.get().isPlotWorld(world)) {
if (!PS.get().hasPlotArea(world)) {
return;
}
final Plot plot = MainUtil.getPlot(loc);
if ((plot != null) && plot.hasOwner()) {
if (FlagManager.isPlotFlagTrue(plot, "explosion")) {
final Iterator<Block> iter = event.blockList().iterator();
while (iter.hasNext()) {
final Block b = iter.next();
if (!plot.equals(MainUtil.getPlot(BukkitUtil.getLocation(b.getLocation())))) {
iter.remove();
}
}
return;
}
}
if (MainUtil.isPlotArea(loc)) {
event.setCancelled(true);
} else {
PlotArea area = loc.getPlotArea();
if (area == null) {
final Iterator<Block> iter = event.blockList().iterator();
while (iter.hasNext()) {
iter.next();
if (MainUtil.isPlotArea(loc)) {
loc = BukkitUtil.getLocation(iter.next().getLocation());
if (loc.getPlotArea() != null) {
iter.remove();
}
}
return;
}
Plot plot = area.getOwnedPlot(loc);
if (plot == null || !FlagManager.isPlotFlagTrue(plot, "explosion")) {
event.setCancelled(true);
}
final Iterator<Block> iter = event.blockList().iterator();
while (iter.hasNext()) {
final Block b = iter.next();
if (!plot.equals(area.getOwnedPlot(BukkitUtil.getLocation(b.getLocation())))) {
iter.remove();
}
}
return;
}
}

View File

@ -20,6 +20,31 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.listeners;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.plotsquared.bukkit.events.PlayerEnterPlotEvent;
import com.plotsquared.bukkit.events.PlayerLeavePlotEvent;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.listener.PlotListener;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@ -27,42 +52,12 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotHandler;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.plotsquared.bukkit.events.PlayerEnterPlotEvent;
import com.plotsquared.bukkit.events.PlayerLeavePlotEvent;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.listener.PlotListener;
/**
* Created 2014-10-30 for PlotSquared
*
* @author Citymonstret
*/
@SuppressWarnings({ "deprecation"})
@SuppressWarnings({ "deprecation" })
public class PlotPlusListener extends PlotListener implements Listener {
private final static HashMap<String, Interval> feedRunnable = new HashMap<>();
private final static HashMap<String, Interval> healRunnable = new HashMap<>();
@ -71,37 +66,41 @@ public class PlotPlusListener extends PlotListener implements Listener {
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
@Override
public void run() {
for (Iterator<Entry<String, Interval>> iter = healRunnable.entrySet().iterator(); iter.hasNext();){
Entry<String, Interval> entry = iter.next();
final Interval value = entry.getValue();
++value.count;
if (value.count == value.interval) {
value.count = 0;
final Player player = Bukkit.getPlayer(entry.getKey());
if (player == null) {
iter.remove();
continue;
}
final double level = player.getHealth();
if (level != value.max) {
player.setHealth(Math.min(level + value.amount, value.max));
if (!healRunnable.isEmpty()) {
for (final Iterator<Entry<String, Interval>> iter = healRunnable.entrySet().iterator(); iter.hasNext();) {
final Entry<String, Interval> entry = iter.next();
final Interval value = entry.getValue();
++value.count;
if (value.count == value.interval) {
value.count = 0;
final Player player = Bukkit.getPlayer(entry.getKey());
if (player == null) {
iter.remove();
continue;
}
final double level = player.getHealth();
if (level != value.max) {
player.setHealth(Math.min(level + value.amount, value.max));
}
}
}
}
for (Iterator<Entry<String, Interval>> iter = feedRunnable.entrySet().iterator(); iter.hasNext();){
Entry<String, Interval> entry = iter.next();
final Interval value = entry.getValue();
++value.count;
if (value.count == value.interval) {
value.count = 0;
final Player player = Bukkit.getPlayer(entry.getKey());
if (player == null) {
iter.remove();
continue;
}
final int level = player.getFoodLevel();
if (level != value.max) {
player.setFoodLevel(Math.min(level + value.amount, value.max));
if (!feedRunnable.isEmpty()) {
for (final Iterator<Entry<String, Interval>> iter = feedRunnable.entrySet().iterator(); iter.hasNext();) {
final Entry<String, Interval> entry = iter.next();
final Interval value = entry.getValue();
++value.count;
if (value.count == value.interval) {
value.count = 0;
final Player player = Bukkit.getPlayer(entry.getKey());
if (player == null) {
iter.remove();
continue;
}
final int level = player.getFoodLevel();
if (level != value.max) {
player.setFoodLevel(Math.min(level + value.amount, value.max));
}
}
}
}
@ -109,13 +108,29 @@ public class PlotPlusListener extends PlotListener implements Listener {
}, 0l, 20l);
}
@EventHandler(priority = EventPriority.HIGH)
public void onMelt(final BlockFadeEvent event) {
final BlockState state = event.getNewState();
if (state.getType() != Material.WATER && state.getType() != Material.STATIONARY_WATER) {
return;
}
final Plot plot = BukkitUtil.getLocation(state.getLocation()).getOwnedPlot();
if (plot == null) {
return;
}
if (!FlagManager.isBooleanFlag(plot, "ice-melt", false)) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onInteract(final BlockDamageEvent event) {
final Player player = event.getPlayer();
if (player.getGameMode() != GameMode.SURVIVAL) {
return;
}
final Plot plot = MainUtil.getPlot(BukkitUtil.getLocation(player));
final Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
if (plot == null) {
return;
}
@ -130,7 +145,7 @@ public class PlotPlusListener extends PlotListener implements Listener {
return;
}
final Player player = (Player) event.getEntity();
final Plot plot = MainUtil.getPlot(BukkitUtil.getLocation(player));
final Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
if (plot == null) {
return;
}
@ -143,7 +158,7 @@ public class PlotPlusListener extends PlotListener implements Listener {
public void onItemPickup(final PlayerPickupItemEvent event) {
final Player player = event.getPlayer();
final PlotPlayer pp = BukkitUtil.getPlayer(player);
final Plot plot = MainUtil.getPlot(pp.getLocation());
final Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
if (plot == null) {
return;
}
@ -157,7 +172,7 @@ public class PlotPlusListener extends PlotListener implements Listener {
public void onItemDrop(final PlayerDropItemEvent event) {
final Player player = event.getPlayer();
final PlotPlayer pp = BukkitUtil.getPlayer(player);
final Plot plot = MainUtil.getPlot(pp.getLocation());
final Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
if (plot == null) {
return;
}
@ -169,42 +184,18 @@ public class PlotPlusListener extends PlotListener implements Listener {
@EventHandler
public void onPlotEnter(final PlayerEnterPlotEvent event) {
Player player = event.getPlayer();
final Player player = event.getPlayer();
final Plot plot = event.getPlot();
if (FlagManager.getPlotFlag(plot, "greeting") != null) {
event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_GREETING.s().replaceAll("%id%", plot.id + "") + FlagManager.getPlotFlag(plot, "greeting").getValueString()));
}
Flag feed = FlagManager.getPlotFlag(plot, "feed");
final Flag feed = FlagManager.getPlotFlagRaw(plot, "feed");
if (feed != null) {
Integer[] value = (Integer[]) feed.getValue();
final Integer[] value = (Integer[]) feed.getValue();
feedRunnable.put(player.getName(), new Interval(value[0], value[1], 20));
}
Flag heal = FlagManager.getPlotFlag(plot, "heal");
final Flag heal = FlagManager.getPlotFlagRaw(plot, "heal");
if (heal != null) {
Integer[] value = (Integer[]) heal.getValue();
final Integer[] value = (Integer[]) heal.getValue();
healRunnable.put(player.getName(), new Interval(value[0], value[1], 20));
}
if (FlagManager.isBooleanFlag(plot, "notify-enter", false)) {
final Player trespasser = event.getPlayer();
final PlotPlayer pt = BukkitUtil.getPlayer(trespasser);
if (Permissions.hasPermission(pt, "plots.flag.notify-enter.bypass")) {
return;
}
if (plot.hasOwner()) {
for (UUID owner : PlotHandler.getOwners(plot)) {
final PlotPlayer pp = UUIDHandler.getPlayer(owner);
if (pp == null) {
return;
}
if (pp.getUUID().equals(pt.getUUID())) {
return;
}
if (pp.isOnline()) {
MainUtil.sendMessage(pp, C.NOTIFY_ENTER.s().replace("%player", trespasser.getName()).replace("%plot", plot.getId().toString()));
}
}
}
}
}
@EventHandler
@ -222,32 +213,10 @@ public class PlotPlusListener extends PlotListener implements Listener {
if (!plot.hasOwner()) {
return;
}
if (FlagManager.getPlotFlag(plot, "farewell") != null) {
event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', C.PREFIX_FAREWELL.s().replaceAll("%id%", plot.id + "") + FlagManager.getPlotFlag(plot, "farewell").getValueString()));
}
final PlotPlayer pl = BukkitUtil.getPlayer(leaver);
String name = leaver.getName();
BukkitUtil.getPlayer(leaver);
final String name = leaver.getName();
feedRunnable.remove(name);
healRunnable.remove(name);
if (FlagManager.isBooleanFlag(plot, "notify-leave", false)) {
if (Permissions.hasPermission(pl, "plots.flag.notify-leave.bypass")) {
return;
}
if (plot.hasOwner()) {
for (UUID owner : PlotHandler.getOwners(plot)) {
final PlotPlayer pp = UUIDHandler.getPlayer(owner);
if (pp == null) {
return;
}
if (pp.getUUID().equals(pl.getUUID())) {
return;
}
if (pp.isOnline()) {
MainUtil.sendMessage(pp, C.NOTIFY_LEAVE.s().replace("%player", leaver.getName()).replace("%plot", plot.getId().toString()));
}
}
}
}
}
public static class Interval {
@ -266,7 +235,7 @@ public class PlotPlusListener extends PlotListener implements Listener {
/**
* Record Meta Class
*
* @author Citymonstret
*/
public static class RecordMeta {
public final static List<RecordMeta> metaList = new ArrayList<>();
@ -285,16 +254,16 @@ public class PlotPlusListener extends PlotListener implements Listener {
@Override
public String toString() {
return this.name;
return name;
}
@Override
public int hashCode() {
return this.name.hashCode();
return name.hashCode();
}
public Material getMaterial() {
return this.material;
return material;
}
}
}

View File

@ -0,0 +1,27 @@
package com.plotsquared.bukkit.listeners;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.generator.ChunkGenerator;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
public class WorldEvents implements Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public static void onWorldInit(final WorldInitEvent event) {
final World world = event.getWorld();
final String name = world.getName();
final ChunkGenerator gen = world.getGenerator();
if (gen instanceof GeneratorWrapper) {
PS.get().loadWorld(name, (GeneratorWrapper<?>) gen);
} else {
PS.get().loadWorld(name, new BukkitPlotGenerator(name, gen));
}
}
}

View File

@ -1,13 +1,16 @@
package com.plotsquared.bukkit.listeners.worldedit;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
@ -19,9 +22,12 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SetQueue;
import com.plotsquared.bukkit.BukkitMain;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.listener.WEManager;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.selections.Selection;
public class WEListener implements Listener {
@ -30,18 +36,20 @@ public class WEListener implements Listener {
public final HashSet<String> rad2 = new HashSet<>(Arrays.asList("fill", "fillr", "removenear", "remove"));
public final HashSet<String> rad2_1 = new HashSet<>(Arrays.asList("hcyl", "cyl"));
public final HashSet<String> rad2_2 = new HashSet<>(Arrays.asList("sphere", "pyramid"));
public final HashSet<String> rad2_3 = new HashSet<>(Arrays.asList("brush smooth"));
public final HashSet<String> rad3_1 = new HashSet<>(Arrays.asList("brush gravity"));
public final HashSet<String> rad2_3 = new HashSet<>(Collections.singletonList("brush smooth"));
public final HashSet<String> rad3_1 = new HashSet<>(Collections.singletonList("brush gravity"));
public final HashSet<String> rad3_2 = new HashSet<>(Arrays.asList("brush sphere", "brush cylinder"));
public final HashSet<String> region = new HashSet<>(Arrays.asList("move", "set", "replace", "overlay", "walls", "outline", "deform", "hollow", "smooth", "naturalize", "paste", "count", "distr", "regen", "copy", "cut", "green", "setbiome"));
public final HashSet<String> regionExtend = new HashSet<>(Arrays.asList("stack"));
public final HashSet<String> region = new HashSet<>(Arrays.asList("move", "set", "replace", "overlay", "walls", "outline", "deform", "hollow", "smooth", "naturalize", "paste", "count", "distr",
"regen", "copy", "cut", "green", "setbiome"));
public final HashSet<String> regionExtend = new HashSet<>(Collections.singletonList("stack"));
public final HashSet<String> unregioned = new HashSet<>(Arrays.asList("paste", "redo", "undo", "rotate", "flip", "generate", "schematic", "schem"));
public final HashSet<String> unsafe1 = new HashSet<>(Arrays.asList("cs", ".s", "restore", "snapshot", "delchunks", "listchunks"));
public final HashSet<String> restricted = new HashSet<>(Arrays.asList("up"));
public final HashSet<String> unsafe1 = new HashSet<>(Arrays.asList("cs", ".s", "restore", "snapshot", "delchunks", "listchunks"));
public final HashSet<String> restricted = new HashSet<>(Collections.singletonList("up"));
public final HashSet<String> other = new HashSet<>(Arrays.asList("undo", "redo"));
public boolean checkCommand(List<String> list, String cmd) {
for (String identifier : list) {
public boolean checkCommand(final List<String> list, final String cmd) {
for (final String identifier : list) {
if (("/" + identifier).equals(cmd) || ("//" + identifier).equals(cmd) || ("/worldedit:/" + identifier).equals(cmd) || ("/worldedit:" + identifier).equals(cmd)) {
return true;
}
@ -49,7 +57,7 @@ public class WEListener implements Listener {
return false;
}
public String reduceCmd(String cmd, boolean single) {
public String reduceCmd(final String cmd, final boolean single) {
if (cmd.startsWith("/worldedit:/")) {
return cmd.substring(12);
}
@ -65,24 +73,23 @@ public class WEListener implements Listener {
return cmd;
}
public int getInt(String s) {
public int getInt(final String s) {
try {
int max = 0;
String[] split = s.split(",");
for (String rad : split) {
int val = Integer.parseInt(rad);
final String[] split = s.split(",");
for (final String rad : split) {
final int val = Integer.parseInt(rad);
if (val > max) {
max = val;
}
}
return max;
}
catch (NumberFormatException e) {
} catch (final NumberFormatException e) {
return 0;
}
}
public boolean checkVolume(PlotPlayer player, long volume, long max, Cancellable e) {
public boolean checkVolume(final PlotPlayer player, final long volume, final long max, final Cancellable e) {
if (volume > max) {
MainUtil.sendMessage(player, C.WORLDEDIT_VOLUME.s().replaceAll("%current%", volume + "").replaceAll("%max%", max + ""));
e.setCancelled(true);
@ -93,24 +100,22 @@ public class WEListener implements Listener {
return true;
}
public boolean checkSelection(Player p, PlotPlayer pp, int modifier, long max, Cancellable e) {
public boolean checkSelection(final Player p, final PlotPlayer pp, final int modifier, final long max, final Cancellable e) {
final Selection selection = BukkitMain.worldEdit.getSelection(p);
if (selection == null) {
return true;
}
final BlockVector pos1 = selection.getNativeMinimumPoint().toBlockVector();
final BlockVector pos2 = selection.getNativeMaximumPoint().toBlockVector();
HashSet<RegionWrapper> mask = WEManager.getMask(pp);
RegionWrapper region = new RegionWrapper(pos1.getBlockX(), pos2.getBlockX(), pos1.getBlockZ(), pos2.getBlockZ());
final HashSet<RegionWrapper> mask = WEManager.getMask(pp);
final RegionWrapper region = new RegionWrapper(pos1.getBlockX(), pos2.getBlockX(), pos1.getBlockZ(), pos2.getBlockZ());
if (Settings.REQUIRE_SELECTION) {
String arg = null;
if (!WEManager.regionContains(region, mask)) {
arg = "pos1 + pos2";
}
else if (!WEManager.maskContains(mask, pos1.getBlockX(), pos1.getBlockZ())) {
} else if (!WEManager.maskContains(mask, pos1.getBlockX(), pos1.getBlockY(), pos1.getBlockZ())) {
arg = "pos1";
}
else if (!WEManager.maskContains(mask, pos2.getBlockX(), pos2.getBlockZ())) {
} else if (!WEManager.maskContains(mask, pos2.getBlockX(), pos2.getBlockY(), pos2.getBlockZ())) {
arg = "pos2";
}
if (arg != null) {
@ -130,59 +135,111 @@ public class WEListener implements Listener {
return true;
}
}
long volume = Math.abs((pos1.getBlockX() - pos2.getBlockX()) * (pos1.getBlockY() - pos2.getBlockY()) * (pos1.getBlockZ() - pos2.getBlockZ())) * modifier;
final long volume = Math.abs((pos1.getBlockX() - pos2.getBlockX()) * (pos1.getBlockY() - pos2.getBlockY()) * (pos1.getBlockZ() - pos2.getBlockZ())) * modifier;
return checkVolume(pp, volume, max, e);
}
public boolean delay(final Player player, final String command, final boolean delayed) {
if (!Settings.QUEUE_COMMANDS || !Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) {
return false;
}
final boolean free = SetQueue.IMP.addTask(null);
if (free) {
if (delayed) {
MainUtil.sendMessage(BukkitUtil.getPlayer(player), C.WORLDEDIT_RUN, command);
Bukkit.getServer().dispatchCommand(player, command.substring(1));
} else {
return false;
}
} else {
if (!delayed) {
MainUtil.sendMessage(BukkitUtil.getPlayer(player), C.WORLDEDIT_DELAYED);
}
SetQueue.IMP.addTask(new Runnable() {
@Override
public void run() {
delay(player, command, true);
}
});
}
return true;
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public boolean onPlayerCommand(final PlayerCommandPreprocessEvent e) {
final Player p = e.getPlayer();
final PlotPlayer pp = BukkitUtil.getPlayer(p);
if (!PS.get().isPlotWorld(p.getWorld().getName())) {
final WorldEditPlugin worldedit = BukkitMain.worldEdit;
if (worldedit == null) {
HandlerList.unregisterAll(this);
return true;
}
String cmd = e.getMessage().toLowerCase();
boolean single = true;
String[] split = cmd.split(" ");
final Player p = e.getPlayer();
final PlotPlayer pp = BukkitUtil.getPlayer(p);
if (!PS.get().hasPlotArea(p.getWorld().getName())) {
return true;
}
final String message = e.getMessage();
final String cmd = message.toLowerCase();
final boolean single = true;
final String[] split = cmd.split(" ");
long maxVolume = Settings.WE_MAX_VOLUME;
long maxIterations = Settings.WE_MAX_ITERATIONS;
if (pp.getAttribute("worldedit" )) {
final long maxVolume = Settings.WE_MAX_VOLUME;
final long maxIterations = Settings.WE_MAX_ITERATIONS;
if (pp.getAttribute("worldedit")) {
return true;
}
if (split.length >= 2) {
String reduced = reduceCmd(split[0], single);
String reduced2 = reduceCmd(split[0] + " " + split[1], single);
final String reduced = reduceCmd(split[0], single);
final String reduced2 = reduceCmd(split[0] + " " + split[1], single);
if (rad1.contains(reduced)) {
long volume = getInt(split[1]) * 256;
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
final long volume = getInt(split[1]) * 256;
return checkVolume(pp, volume, maxVolume, e);
}
if (rad2.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 3) {
long volume = getInt(split[2]) * 256;
final long volume = getInt(split[2]) * 256;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad2_1.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 4) {
long volume = getInt(split[2]) * getInt(split[3]);
final long volume = getInt(split[2]) * getInt(split[3]);
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad2_2.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 3) {
long radius = getInt(split[2]);
long volume = radius * radius;
final long radius = getInt(split[2]);
final long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad2_3.contains(reduced2)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 3) {
if (split.length == 4) {
int iterations = getInt(split[3]);
final int iterations = getInt(split[3]);
if (iterations > maxIterations) {
MainUtil.sendMessage(pp, C.WORLDEDIT_ITERATIONS.s().replaceAll("%current%", iterations + "").replaceAll("%max%", maxIterations + ""));
e.setCancelled(true);
@ -192,41 +249,53 @@ public class WEListener implements Listener {
return true;
}
}
long radius = getInt(split[2]);
long volume = radius * radius;
final long radius = getInt(split[2]);
final long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad3_1.contains(reduced2)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 3) {
int i = 2;
if (split[i].equalsIgnoreCase("-h")) {
i = 3;
}
long radius = getInt(split[i]);
long volume = radius * radius;
final long radius = getInt(split[i]);
final long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (rad3_2.contains(reduced2)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 4) {
int i = 3;
if (split[i].equalsIgnoreCase("-h")) {
i = 4;
}
long radius = getInt(split[i]);
long volume = radius * radius;
final long radius = getInt(split[i]);
final long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (regionExtend.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
return checkSelection(p, pp, getInt(split[1]), maxVolume, e);
}
}
String reduced = reduceCmd(split[0], single);
final String reduced = reduceCmd(split[0], single);
if (Settings.WE_BLACKLIST.contains(reduced)) {
MainUtil.sendMessage(pp, C.WORLDEDIT_UNSAFE);
e.setCancelled(true);
@ -235,8 +304,12 @@ public class WEListener implements Listener {
}
}
if (restricted.contains(reduced)) {
Plot plot = MainUtil.getPlot(pp.getLocation());
if (plot != null && plot.isAdded(pp.getUUID())) {
final Plot plot = pp.getCurrentPlot();
if ((plot != null) && plot.isAdded(pp.getUUID())) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
return true;
}
e.setCancelled(true);
@ -247,9 +320,18 @@ public class WEListener implements Listener {
return true;
}
if (region.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
return checkSelection(p, pp, 1, maxVolume, e);
}
if (other.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
}
return true;
}
}

View File

@ -7,22 +7,21 @@ import com.intellectualcrafters.plot.object.PlotBlock;
public class BukkitLazyBlock extends LazyBlock {
private int id = -1;
private int id;
private Block block;
private PlotBlock pb;
public BukkitLazyBlock(int id, Block block) {
public BukkitLazyBlock(final int id, final Block block) {
this.id = id;
this.block = block;
}
public BukkitLazyBlock(PlotBlock pb) {
this.id = pb.id;
public BukkitLazyBlock(final PlotBlock pb) {
id = pb.id;
this.pb = pb;
}
public BukkitLazyBlock(Block block) {
public BukkitLazyBlock(final Block block) {
this.block = block;
}
@ -31,11 +30,11 @@ public class BukkitLazyBlock extends LazyBlock {
if (pb != null) {
return pb;
}
if (id == -1 ) {
if (id == 0) {
id = block.getTypeId();
}
byte data;
switch(id) {
switch (id) {
case 0:
case 2:
case 4:
@ -59,7 +58,6 @@ public class BukkitLazyBlock extends LazyBlock {
case 47:
case 48:
case 49:
case 50:
case 51:
case 52:
case 54:
@ -77,8 +75,6 @@ public class BukkitLazyBlock extends LazyBlock {
case 11:
case 73:
case 74:
case 75:
case 76:
case 78:
case 79:
case 80:
@ -122,8 +118,10 @@ public class BukkitLazyBlock extends LazyBlock {
case 191:
case 192:
data = 0;
break;
default:
data = block.getData();
break;
}
pb = new PlotBlock((short) id, data);
return pb;
@ -132,7 +130,7 @@ public class BukkitLazyBlock extends LazyBlock {
@Override
public int getId() {
if (id == -1) {
if (id == 0) {
id = block.getTypeId();
}
return id;

View File

@ -20,21 +20,21 @@ public class BukkitOfflinePlayer implements OfflinePlotPlayer {
@Override
public UUID getUUID() {
return this.player.getUniqueId();
return player.getUniqueId();
}
@Override
public long getLastPlayed() {
return this.player.getLastPlayed();
return player.getLastPlayed();
}
@Override
public boolean isOnline() {
return this.player.isOnline();
return player.isOnline();
}
@Override
public String getName() {
return this.player.getName();
return player.getName();
}
}

View File

@ -1,37 +1,31 @@
package com.plotsquared.bukkit.object;
import java.util.HashSet;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.WeatherType;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.EconHandler;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotGamemode;
import com.intellectualcrafters.plot.util.PlotWeather;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.plotsquared.bukkit.util.BukkitUtil;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.GameMode;
import org.bukkit.WeatherType;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.PluginManager;
import java.util.UUID;
public class BukkitPlayer extends PlotPlayer {
public final Player player;
public boolean offline;
private UUID uuid;
private String name;
private long last = 0;
public HashSet<String> hasPerm = new HashSet<>();
public HashSet<String> noPerm = new HashSet<>();
public boolean offline;
/**
* Please do not use this method. Instead use BukkitUtil.getPlayer(Player), as it caches player objects.
@ -39,13 +33,16 @@ public class BukkitPlayer extends PlotPlayer {
*/
public BukkitPlayer(final Player player) {
this.player = player;
super.populatePersistentMetaMap();
}
public BukkitPlayer(final Player player, boolean offline) {
public BukkitPlayer(final Player player, final boolean offline) {
this.player = player;
this.offline = offline;
super.populatePersistentMetaMap();
}
@Override
public long getPreviousLogin() {
if (last == 0) {
last = player.getLastPlayed();
@ -55,114 +52,84 @@ public class BukkitPlayer extends PlotPlayer {
@Override
public Location getLocation() {
Location loc = super.getLocation();
return loc == null ? BukkitUtil.getLocation(this.player) : loc;
final Location loc = super.getLocation();
return loc == null ? BukkitUtil.getLocation(player) : loc;
}
@Override
public UUID getUUID() {
if (this.uuid == null) {
this.uuid = UUIDHandler.getUUID(this);
if (uuid == null) {
uuid = UUIDHandler.getUUID(this);
}
return this.uuid;
return uuid;
}
@Override
public boolean hasPermission(final String perm) {
if (Settings.PERMISSION_CACHING) {
if (this.noPerm.contains(perm)) {
return false;
}
if (this.hasPerm.contains(perm)) {
return true;
}
final boolean result = this.player.hasPermission(perm);
if (!result) {
this.noPerm.add(perm);
return false;
}
this.hasPerm.add(perm);
return true;
}
public boolean hasPermission(final String node) {
if (offline && EconHandler.manager != null) {
return EconHandler.manager.hasPermission(getName(), perm);
return EconHandler.manager.hasPermission(getName(), node);
}
return this.player.hasPermission(perm);
return player.hasPermission(node);
}
public Permission getPermission(final String node) {
final PluginManager manager = Bukkit.getPluginManager();
Permission perm = manager.getPermission(node);
if (perm == null) {
final String[] nodes = node.split("\\.");
perm = new Permission(node);
final StringBuilder n = new StringBuilder();
for (int i = 0; i < nodes.length - 1; i++) {
n.append(nodes[i]).append(".");
if (!node.equals(n + C.PERMISSION_STAR.s())) {
final Permission parent = getPermission(n + C.PERMISSION_STAR.s());
if (parent != null) {
perm.addParent(parent, true);
}
}
}
manager.addPermission(perm);
}
manager.recalculatePermissionDefaults(perm);
perm.recalculatePermissibles();
return perm;
}
@Override
public void sendMessage(final String message) {
this.player.sendMessage(message);
}
@Override
public void sendMessage(C c, String... args) {
MainUtil.sendMessage(this, c, args);
player.sendMessage(message);
}
@Override
public void teleport(final Location loc) {
this.player.teleport(new org.bukkit.Location(BukkitUtil.getWorld(loc.getWorld()), loc.getX() + 0.5, loc.getY(), loc.getZ() + 0.5, loc.getYaw(), loc.getPitch()));
if (Math.abs(loc.getX()) >= 30000000 || Math.abs(loc.getZ()) >= 30000000) {
return;
}
player.teleport(new org.bukkit.Location(BukkitUtil.getWorld(loc.getWorld()), loc.getX() + 0.5, loc.getY(), loc.getZ() + 0.5, loc.getYaw(), loc.getPitch()), TeleportCause.COMMAND);
}
@Override
public String getName() {
if (this.name == null) {
this.name = this.player.getName();
if (name == null) {
name = player.getName();
}
return this.name;
return name;
}
@Override
public boolean isOnline() {
return !offline && this.player.isOnline();
return !offline && player.isOnline();
}
@Override
public void setCompassTarget(final Location loc) {
this.player.setCompassTarget(new org.bukkit.Location(BukkitUtil.getWorld(loc.getWorld()), loc.getX(), loc.getY(), loc.getZ()));
player.setCompassTarget(new org.bukkit.Location(BukkitUtil.getWorld(loc.getWorld()), loc.getX(), loc.getY(), loc.getZ()));
}
@Override
public Location getLocationFull() {
return BukkitUtil.getLocationFull(this.player);
}
@Override
public void setAttribute(String key) {
key = "plotsquared_user_attributes." + key;
if (EconHandler.manager == null) {
setMeta(key, true);
return;
}
EconHandler.manager.setPermission(getName(), key, true);
}
@Override
public boolean getAttribute(String key) {
key = "plotsquared_user_attributes." + key;
if (EconHandler.manager == null) {
Object v = getMeta(key);
return v == null ? false : (Boolean) v;
}
Permission perm = Bukkit.getServer().getPluginManager().getPermission(key);
if (perm == null) {
perm = new Permission(key, PermissionDefault.FALSE);
Bukkit.getServer().getPluginManager().addPermission(perm);
Bukkit.getServer().getPluginManager().recalculatePermissionDefaults(perm);
}
return player.hasPermission(key);
}
@Override
public void removeAttribute(String key) {
key = "plotsquared_user_attributes." + key;
if (EconHandler.manager == null) {
deleteMeta(key);
return;
}
EconHandler.manager.setPermission(getName(), key, false);
return BukkitUtil.getLocationFull(player);
}
@Override
@ -178,15 +145,14 @@ public class BukkitPlayer extends PlotPlayer {
}
@Override
public void setWeather(PlotWeather weather) {
public void setWeather(final PlotWeather weather) {
switch (weather) {
case CLEAR:
player.setPlayerWeather(WeatherType.CLEAR);
return;
case RAIN: {
case RAIN:
player.setPlayerWeather(WeatherType.DOWNFALL);
return;
}
case RESET:
player.resetPlayerWeather();
return;
@ -209,7 +175,7 @@ public class BukkitPlayer extends PlotPlayer {
}
@Override
public void setGamemode(PlotGamemode gamemode) {
public void setGamemode(final PlotGamemode gamemode) {
switch (gamemode) {
case ADVENTURE:
player.setGameMode(GameMode.ADVENTURE);
@ -227,22 +193,37 @@ public class BukkitPlayer extends PlotPlayer {
}
@Override
public void setTime(long time) {
player.setPlayerTime(time, false);
public void setTime(final long time) {
if (time != Long.MAX_VALUE) {
player.setPlayerTime(time, false);
} else {
player.resetPlayerTime();
}
}
@Override
public void setFlight(boolean fly) {
public void setFlight(final boolean fly) {
player.setAllowFlight(fly);
}
@Override
public void playMusic(Location loc, int id) {
public void playMusic(final Location loc, final int id) {
player.playEffect(BukkitUtil.getLocation(loc), Effect.RECORD_PLAY, id);
}
@Override
public void kick(String message) {
public void kick(final String message) {
player.kickPlayer(message);
}
@Override public void stopSpectating() {
if (getGamemode() == PlotGamemode.SPECTATOR) {
player.setSpectatorTarget(null);
}
}
@Override
public boolean isBanned() {
return player.isBanned();
}
}

View File

@ -1,4 +1,4 @@
package com.intellectualcrafters.plot.object.entity;
package com.plotsquared.bukkit.object.entity;
public class AgeableStats {
public int age;

View File

@ -1,4 +1,4 @@
package com.intellectualcrafters.plot.object.entity;
package com.plotsquared.bukkit.object.entity;
public class ArmorStandStats {
public float[] head = new float[3];

View File

@ -1,6 +1,5 @@
package com.intellectualcrafters.plot.object.entity;
package com.plotsquared.bukkit.object.entity;
import com.plotsquared.bukkit.object.entity.EntityWrapper;
public class EntityBaseStats {
public EntityWrapper passenger;

View File

@ -1,5 +1,6 @@
package com.plotsquared.bukkit.object.entity;
import com.intellectualcrafters.plot.PS;
import org.bukkit.Art;
import org.bukkit.DyeColor;
import org.bukkit.Location;
@ -31,14 +32,9 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.entity.AgeableStats;
import com.intellectualcrafters.plot.object.entity.ArmorStandStats;
import com.intellectualcrafters.plot.object.entity.EntityBaseStats;
import com.intellectualcrafters.plot.object.entity.HorseStats;
public class EntityWrapper {
public short id;
public EntityType type;
public float yaw;
public float pitch;
public double x;
@ -60,140 +56,32 @@ public class EntityWrapper {
private int hash;
@Override
public boolean equals(Object obj) {
return hash == obj.hashCode();
}
@Override
public int hashCode() {
return hash;
}
public void storeInventory(final InventoryHolder held) {
this.inventory = held.getInventory().getContents().clone();
}
private void restoreLiving(final LivingEntity entity) {
if (this.lived.loot) {
entity.setCanPickupItems(this.lived.loot);
}
if (this.lived.name != null) {
entity.setCustomName(this.lived.name);
entity.setCustomNameVisible(this.lived.visible);
}
if ((this.lived.potions != null) && (this.lived.potions.size() > 0)) {
entity.addPotionEffects(this.lived.potions);
}
entity.setRemainingAir(this.lived.air);
entity.setRemoveWhenFarAway(this.lived.persistent);
if (this.lived.equipped) {
final EntityEquipment equipment = entity.getEquipment();
equipment.setItemInHand(this.lived.hands);
equipment.setHelmet(this.lived.helmet);
equipment.setChestplate(this.lived.chestplate);
equipment.setLeggings(this.lived.leggings);
equipment.setBoots(this.lived.boots);
}
if (this.lived.leashed) {
// TODO leashes
// World world = entity.getWorld();
// Entity leash = world.spawnEntity(new Location(world, Math.floor(x) + lived.leash_x, Math.floor(y) + lived.leash_y, Math.floor(z) + lived.leash_z), EntityType.LEASH_HITCH);
// entity.setLeashHolder(leash);
}
}
private void restoreInventory(final InventoryHolder entity) {
entity.getInventory().setContents(this.inventory);
}
public void storeLiving(final LivingEntity lived) {
this.lived = new LivingEntityStats();
this.lived.potions = lived.getActivePotionEffects();
this.lived.loot = lived.getCanPickupItems();
this.lived.name = lived.getCustomName();
this.lived.visible = lived.isCustomNameVisible();
this.lived.health = (float) lived.getHealth();
this.lived.air = (short) lived.getRemainingAir();
this.lived.persistent = lived.getRemoveWhenFarAway();
this.lived.leashed = lived.isLeashed();
if (this.lived.leashed) {
final Location loc = lived.getLeashHolder().getLocation();
this.lived.leash_x = (short) (this.x - loc.getBlockX());
this.lived.leash_y = (short) (this.y - loc.getBlockY());
this.lived.leash_z = (short) (this.z - loc.getBlockZ());
}
final EntityEquipment equipment = lived.getEquipment();
this.lived.equipped = equipment != null;
if (this.lived.equipped) {
this.lived.hands = equipment.getItemInHand().clone();
this.lived.boots = equipment.getBoots().clone();
this.lived.leggings = equipment.getLeggings().clone();
this.lived.chestplate = equipment.getChestplate().clone();
this.lived.helmet = equipment.getHelmet().clone();
}
}
private void restoreTameable(final Tameable entity) {
if (this.tamed.tamed) {
if (this.tamed.owner != null) {
entity.setTamed(true);
entity.setOwner(this.tamed.owner);
}
}
}
private void restoreAgeable(final Ageable entity) {
if (!this.aged.adult) {
entity.setBaby();
}
if (this.aged.locked) {
entity.setAgeLock(this.aged.locked);
}
if (this.aged.age > 0) {
entity.setAge(this.aged.age);
}
}
public void storeAgeable(final Ageable aged) {
this.aged = new AgeableStats();
this.aged.age = aged.getAge();
this.aged.locked = aged.getAgeLock();
this.aged.adult = aged.isAdult();
}
public void storeTameable(final Tameable tamed) {
this.tamed = new TameableStats();
this.tamed.owner = tamed.getOwner();
this.tamed.tamed = tamed.isTamed();
}
@SuppressWarnings("deprecation")
public EntityWrapper(final org.bukkit.entity.Entity entity, final short depth) {
this.hash = entity.getEntityId();
hash = entity.getEntityId();
this.depth = depth;
final Location loc = entity.getLocation();
this.yaw = loc.getYaw();
this.pitch = loc.getPitch();
this.x = loc.getX();
this.y = loc.getY();
this.z = loc.getZ();
this.id = entity.getType().getTypeId();
yaw = loc.getYaw();
pitch = loc.getPitch();
x = loc.getX();
y = loc.getY();
z = loc.getZ();
type = entity.getType();
if (depth == 0) {
return;
}
this.base = new EntityBaseStats();
base = new EntityBaseStats();
final Entity p = entity.getPassenger();
if (p != null) {
this.base.passenger = new EntityWrapper(p, depth);
base.passenger = new EntityWrapper(p, depth);
}
this.base.fall = entity.getFallDistance();
this.base.fire = (short) entity.getFireTicks();
this.base.age = entity.getTicksLived();
base.fall = entity.getFallDistance();
base.fire = (short) entity.getFireTicks();
base.age = entity.getTicksLived();
final Vector velocity = entity.getVelocity();
this.base.v_x = velocity.getX();
this.base.v_y = velocity.getY();
this.base.v_z = velocity.getZ();
base.v_x = velocity.getX();
base.v_y = velocity.getY();
base.v_z = velocity.getZ();
if (depth == 1) {
return;
}
@ -237,30 +125,30 @@ public class EntityWrapper {
// MISC //
case DROPPED_ITEM: {
final Item item = (Item) entity;
this.stack = item.getItemStack();
stack = item.getItemStack();
return;
}
case ITEM_FRAME: {
final ItemFrame itemframe = (ItemFrame) entity;
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
this.z = Math.floor(this.z);
this.dataByte = getOrdinal(Rotation.values(), itemframe.getRotation());
this.stack = itemframe.getItem().clone();
x = Math.floor(x);
y = Math.floor(y);
z = Math.floor(z);
dataByte = getOrdinal(Rotation.values(), itemframe.getRotation());
stack = itemframe.getItem().clone();
return;
}
case PAINTING: {
final Painting painting = (Painting) entity;
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
this.z = Math.floor(this.z);
x = Math.floor(x);
y = Math.floor(y);
z = Math.floor(z);
final Art a = painting.getArt();
this.dataByte = getOrdinal(BlockFace.values(), painting.getFacing());
dataByte = getOrdinal(BlockFace.values(), painting.getFacing());
final int h = a.getBlockHeight();
if ((h % 2) == 0) {
this.y -= 1;
y -= 1;
}
this.dataString = a.name();
dataString = a.name();
return;
}
// END MISC //
@ -301,8 +189,8 @@ public class EntityWrapper {
// END AMEABLE //
case SHEEP: {
final Sheep sheep = (Sheep) entity;
this.dataByte = (byte) ((sheep).isSheared() ? 1 : 0);
this.dataByte2 = sheep.getColor().getDyeData();
dataByte = (byte) ((sheep).isSheared() ? 1 : 0);
dataByte2 = sheep.getColor().getDyeData();
storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity);
return;
@ -318,54 +206,54 @@ public class EntityWrapper {
}
// END AGEABLE //
case RABBIT: { // NEW
this.dataByte = getOrdinal(Type.values(), ((Rabbit) entity).getRabbitType());
dataByte = getOrdinal(Type.values(), ((Rabbit) entity).getRabbitType());
storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity);
return;
}
case GUARDIAN: { // NEW
this.dataByte = (byte) (((Guardian) entity).isElder() ? 1 : 0);
dataByte = (byte) (((Guardian) entity).isElder() ? 1 : 0);
storeLiving((LivingEntity) entity);
return;
}
case SKELETON: { // NEW
this.dataByte = (byte) ((Skeleton) entity).getSkeletonType().getId();
dataByte = (byte) ((Skeleton) entity).getSkeletonType().getId();
storeLiving((LivingEntity) entity);
return;
}
case ARMOR_STAND: { // NEW
// CHECK positions
// CHECK positions
final ArmorStand stand = (ArmorStand) entity;
this.inventory = new ItemStack[] { stand.getItemInHand().clone(), stand.getHelmet().clone(), stand.getChestplate().clone(), stand.getLeggings().clone(), stand.getBoots().clone() };
inventory = new ItemStack[] { stand.getItemInHand().clone(), stand.getHelmet().clone(), stand.getChestplate().clone(), stand.getLeggings().clone(), stand.getBoots().clone() };
storeLiving((LivingEntity) entity);
this.stand = new ArmorStandStats();
EulerAngle head = stand.getHeadPose();
final EulerAngle head = stand.getHeadPose();
this.stand.head[0] = (float) head.getX();
this.stand.head[1] = (float) head.getY();
this.stand.head[2] = (float) head.getZ();
EulerAngle body = stand.getBodyPose();
final EulerAngle body = stand.getBodyPose();
this.stand.body[0] = (float) body.getX();
this.stand.body[1] = (float) body.getY();
this.stand.body[2] = (float) body.getZ();
EulerAngle leftLeg = stand.getLeftLegPose();
final EulerAngle leftLeg = stand.getLeftLegPose();
this.stand.leftLeg[0] = (float) leftLeg.getX();
this.stand.leftLeg[1] = (float) leftLeg.getY();
this.stand.leftLeg[2] = (float) leftLeg.getZ();
EulerAngle rightLeg = stand.getRightLegPose();
final EulerAngle rightLeg = stand.getRightLegPose();
this.stand.rightLeg[0] = (float) rightLeg.getX();
this.stand.rightLeg[1] = (float) rightLeg.getY();
this.stand.rightLeg[2] = (float) rightLeg.getZ();
EulerAngle leftArm = stand.getLeftArmPose();
final EulerAngle leftArm = stand.getLeftArmPose();
this.stand.leftArm[0] = (float) leftArm.getX();
this.stand.leftArm[1] = (float) leftArm.getY();
this.stand.leftArm[2] = (float) leftArm.getZ();
EulerAngle rightArm = stand.getRightArmPose();
final EulerAngle rightArm = stand.getRightArmPose();
this.stand.rightArm[0] = (float) rightArm.getX();
this.stand.rightArm[1] = (float) rightArm.getY();
this.stand.rightArm[2] = (float) rightArm.getZ();
@ -413,19 +301,123 @@ public class EntityWrapper {
}
}
@Override
public boolean equals(final Object obj) {
return hash == obj.hashCode();
}
@Override
public int hashCode() {
return hash;
}
public void storeInventory(final InventoryHolder held) {
inventory = held.getInventory().getContents().clone();
}
private void restoreLiving(final LivingEntity entity) {
entity.setCanPickupItems(lived.loot);
if (lived.name != null) {
entity.setCustomName(lived.name);
entity.setCustomNameVisible(lived.visible);
}
if ((lived.potions != null) && (!lived.potions.isEmpty())) {
entity.addPotionEffects(lived.potions);
}
entity.setRemainingAir(lived.air);
entity.setRemoveWhenFarAway(lived.persistent);
if (lived.equipped) {
final EntityEquipment equipment = entity.getEquipment();
equipment.setItemInHand(lived.hands);
equipment.setHelmet(lived.helmet);
equipment.setChestplate(lived.chestplate);
equipment.setLeggings(lived.leggings);
equipment.setBoots(lived.boots);
}
if (lived.leashed) {
// TODO leashes
// World world = entity.getWorld();
// Entity leash = world.spawnEntity(new Location(world, Math.floor(x) + lived.leash_x, Math.floor(y) + lived.leash_y, Math
// .floor(z) + lived.leash_z), EntityType.LEASH_HITCH);
// entity.setLeashHolder(leash);
}
}
private void restoreInventory(final InventoryHolder entity) {
entity.getInventory().setContents(inventory);
}
public void storeLiving(final LivingEntity lived) {
this.lived = new LivingEntityStats();
this.lived.potions = lived.getActivePotionEffects();
this.lived.loot = lived.getCanPickupItems();
this.lived.name = lived.getCustomName();
this.lived.visible = lived.isCustomNameVisible();
this.lived.health = (float) lived.getHealth();
this.lived.air = (short) lived.getRemainingAir();
this.lived.persistent = lived.getRemoveWhenFarAway();
this.lived.leashed = lived.isLeashed();
if (this.lived.leashed) {
final Location loc = lived.getLeashHolder().getLocation();
this.lived.leash_x = (short) (x - loc.getBlockX());
this.lived.leash_y = (short) (y - loc.getBlockY());
this.lived.leash_z = (short) (z - loc.getBlockZ());
}
final EntityEquipment equipment = lived.getEquipment();
this.lived.equipped = equipment != null;
if (this.lived.equipped) {
this.lived.hands = equipment.getItemInHand().clone();
this.lived.boots = equipment.getBoots().clone();
this.lived.leggings = equipment.getLeggings().clone();
this.lived.chestplate = equipment.getChestplate().clone();
this.lived.helmet = equipment.getHelmet().clone();
}
}
private void restoreTameable(final Tameable entity) {
if (tamed.tamed) {
if (tamed.owner != null) {
entity.setTamed(true);
entity.setOwner(tamed.owner);
}
}
}
private void restoreAgeable(final Ageable entity) {
if (!aged.adult) {
entity.setBaby();
}
entity.setAgeLock(aged.locked);
if (aged.age > 0) {
entity.setAge(aged.age);
}
}
public void storeAgeable(final Ageable aged) {
this.aged = new AgeableStats();
this.aged.age = aged.getAge();
this.aged.locked = aged.getAgeLock();
this.aged.adult = aged.isAdult();
}
public void storeTameable(final Tameable tamed) {
this.tamed = new TameableStats();
this.tamed.owner = tamed.getOwner();
this.tamed.tamed = tamed.isTamed();
}
@SuppressWarnings("deprecation")
public Entity spawn(final World world, final int x_offset, final int z_offset) {
final Location loc = new Location(world, this.x + x_offset, this.y, this.z + z_offset);
loc.setYaw(this.yaw);
loc.setPitch(this.pitch);
if (this.id == -1) {
final Location loc = new Location(world, x + x_offset, y, z + z_offset);
loc.setYaw(yaw);
loc.setPitch(pitch);
if (type.isSpawnable()) {
return null;
}
final EntityType type = EntityType.fromId(this.id);
Entity entity;
switch (type) {
case DROPPED_ITEM: {
return world.dropItem(loc, this.stack);
return world.dropItem(loc, stack);
}
case PLAYER:
case LEASH_HITCH: {
@ -443,20 +435,25 @@ public class EntityWrapper {
entity = world.spawnEntity(loc, type);
break;
}
if (this.depth == 0) {
if (depth == 0) {
return entity;
}
if (this.base.passenger != null) {
if (base.passenger != null) {
try {
entity.setPassenger(this.base.passenger.spawn(world, x_offset, z_offset));
} catch (final Exception e) {
}
entity.setPassenger(base.passenger.spawn(world, x_offset, z_offset));
} catch (final Exception e) {}
}
if (this.base.fall != 0) entity.setFallDistance(this.base.fall);
if (this.base.fire != 0) entity.setFireTicks(this.base.fire);
if (this.base.age != 0) entity.setTicksLived(this.base.age);
entity.setVelocity(new Vector(this.base.v_x, this.base.v_y, this.base.v_z));
if (this.depth == 1) {
if (base.fall != 0) {
entity.setFallDistance(base.fall);
}
if (base.fire != 0) {
entity.setFireTicks(base.fire);
}
if (base.age != 0) {
entity.setTicksLived(base.age);
}
entity.setVelocity(new Vector(base.v_x, base.v_y, base.v_z));
if (depth == 1) {
return entity;
}
switch (entity.getType()) {
@ -499,14 +496,14 @@ public class EntityWrapper {
// MISC //
case ITEM_FRAME: {
final ItemFrame itemframe = (ItemFrame) entity;
itemframe.setRotation(Rotation.values()[this.dataByte]);
itemframe.setItem(this.stack);
itemframe.setRotation(Rotation.values()[dataByte]);
itemframe.setItem(stack);
return entity;
}
case PAINTING: {
final Painting painting = (Painting) entity;
painting.setFacingDirection(BlockFace.values()[this.dataByte], true);
painting.setArt(Art.getByName(this.dataString), true);
painting.setFacingDirection(BlockFace.values()[dataByte], true);
painting.setArt(Art.getByName(dataString), true);
return entity;
}
// END MISC //
@ -543,14 +540,14 @@ public class EntityWrapper {
restoreLiving((LivingEntity) entity);
return entity;
}
// END AMEABLE //
// END AGEABLE //
case SHEEP: {
final Sheep sheep = (Sheep) entity;
if (this.dataByte == 1) {
if (dataByte == 1) {
sheep.setSheared(true);
}
if (this.dataByte2 != 0) {
sheep.setColor(DyeColor.getByDyeData(this.dataByte2));
if (dataByte2 != 0) {
sheep.setColor(DyeColor.getByDyeData(dataByte2));
}
restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity);
@ -567,67 +564,67 @@ public class EntityWrapper {
}
// END AGEABLE //
case RABBIT: { // NEW
if (this.dataByte != 0) {
((Rabbit) entity).setRabbitType(Type.values()[this.dataByte]);
if (dataByte != 0) {
((Rabbit) entity).setRabbitType(Type.values()[dataByte]);
}
restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity);
return entity;
}
case GUARDIAN: { // NEW
if (this.dataByte != 0) {
if (dataByte != 0) {
((Guardian) entity).setElder(true);
}
restoreLiving((LivingEntity) entity);
return entity;
}
case SKELETON: { // NEW
if (this.dataByte != 0) {
((Skeleton) entity).setSkeletonType(SkeletonType.values()[this.dataByte]);
if (dataByte != 0) {
((Skeleton) entity).setSkeletonType(SkeletonType.values()[dataByte]);
}
storeLiving((LivingEntity) entity);
return entity;
}
case ARMOR_STAND: { // NEW
// CHECK positions
// CHECK positions
final ArmorStand stand = (ArmorStand) entity;
if (this.inventory[0] != null) {
stand.setItemInHand(this.inventory[0]);
if (inventory[0] != null) {
stand.setItemInHand(inventory[0]);
}
if (this.inventory[1] != null) {
stand.setHelmet(this.inventory[1]);
if (inventory[1] != null) {
stand.setHelmet(inventory[1]);
}
if (this.inventory[2] != null) {
stand.setChestplate(this.inventory[2]);
if (inventory[2] != null) {
stand.setChestplate(inventory[2]);
}
if (this.inventory[3] != null) {
stand.setLeggings(this.inventory[3]);
if (inventory[3] != null) {
stand.setLeggings(inventory[3]);
}
if (this.inventory[4] != null) {
stand.setBoots(this.inventory[4]);
if (inventory[4] != null) {
stand.setBoots(inventory[4]);
}
if (this.stand.head[0] != 0 || this.stand.head[1] != 0 || this.stand.head[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.head[0], this.stand.head[1], this.stand.head[2]);
if ((this.stand.head[0] != 0) || (this.stand.head[1] != 0) || (this.stand.head[2] != 0)) {
final EulerAngle pose = new EulerAngle(this.stand.head[0], this.stand.head[1], this.stand.head[2]);
stand.setHeadPose(pose);
}
if (this.stand.body[0] != 0 || this.stand.body[1] != 0 || this.stand.body[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.body[0], this.stand.body[1], this.stand.body[2]);
if ((this.stand.body[0] != 0) || (this.stand.body[1] != 0) || (this.stand.body[2] != 0)) {
final EulerAngle pose = new EulerAngle(this.stand.body[0], this.stand.body[1], this.stand.body[2]);
stand.setBodyPose(pose);
}
if (this.stand.leftLeg[0] != 0 || this.stand.leftLeg[1] != 0 || this.stand.leftLeg[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.leftLeg[0], this.stand.leftLeg[1], this.stand.leftLeg[2]);
if ((this.stand.leftLeg[0] != 0) || (this.stand.leftLeg[1] != 0) || (this.stand.leftLeg[2] != 0)) {
final EulerAngle pose = new EulerAngle(this.stand.leftLeg[0], this.stand.leftLeg[1], this.stand.leftLeg[2]);
stand.setLeftLegPose(pose);
}
if (this.stand.rightLeg[0] != 0 || this.stand.rightLeg[1] != 0 || this.stand.rightLeg[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.rightLeg[0], this.stand.rightLeg[1], this.stand.rightLeg[2]);
if ((this.stand.rightLeg[0] != 0) || (this.stand.rightLeg[1] != 0) || (this.stand.rightLeg[2] != 0)) {
final EulerAngle pose = new EulerAngle(this.stand.rightLeg[0], this.stand.rightLeg[1], this.stand.rightLeg[2]);
stand.setRightLegPose(pose);
}
if (this.stand.leftArm[0] != 0 || this.stand.leftArm[1] != 0 || this.stand.leftArm[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.leftArm[0], this.stand.leftArm[1], this.stand.leftArm[2]);
if ((this.stand.leftArm[0] != 0) || (this.stand.leftArm[1] != 0) || (this.stand.leftArm[2] != 0)) {
final EulerAngle pose = new EulerAngle(this.stand.leftArm[0], this.stand.leftArm[1], this.stand.leftArm[2]);
stand.setLeftArmPose(pose);
}
if (this.stand.rightArm[0] != 0 || this.stand.rightArm[1] != 0 || this.stand.rightArm[2] != 0) {
EulerAngle pose = new EulerAngle(this.stand.rightArm[0], this.stand.rightArm[1], this.stand.rightArm[2]);
if ((this.stand.rightArm[0] != 0) || (this.stand.rightArm[1] != 0) || (this.stand.rightArm[2] != 0)) {
final EulerAngle pose = new EulerAngle(this.stand.rightArm[0], this.stand.rightArm[1], this.stand.rightArm[2]);
stand.setRightArmPose(pose);
}
if (this.stand.invisible) {

View File

@ -1,4 +1,4 @@
package com.intellectualcrafters.plot.object.entity;
package com.plotsquared.bukkit.object.entity;
public class HorseStats {
public double jump;

View File

@ -1,4 +1,4 @@
package com.plotsquared.object.schematic;
package com.plotsquared.bukkit.object.schematic;
import java.util.ArrayList;
import java.util.HashMap;
@ -26,30 +26,30 @@ public class StateWrapper {
public BlockState state = null;
public CompoundTag tag = null;
public StateWrapper(BlockState state) {
public StateWrapper(final BlockState state) {
this.state = state;
}
public StateWrapper(CompoundTag tag) {
public StateWrapper(final CompoundTag tag) {
this.tag = tag;
}
public boolean restoreTag(short x, short y, short z, Schematic schematic) {
if (this.tag == null) {
public boolean restoreTag(final short x, final short y, final short z, final Schematic schematic) {
if (tag == null) {
return false;
}
List<Tag> itemsTag = this.tag.getListTag("Items").getValue();
int length = itemsTag.size();
short[] ids = new short[length];
byte[] datas = new byte[length];
byte[] amounts = new byte[length];
final List<Tag> itemsTag = tag.getListTag("Items").getValue();
final int length = itemsTag.size();
final short[] ids = new short[length];
final byte[] datas = new byte[length];
final byte[] amounts = new byte[length];
for (int i = 0; i < length; i++) {
Tag itemTag = itemsTag.get(i);
CompoundTag itemComp = (CompoundTag) itemTag;
final Tag itemTag = itemsTag.get(i);
final CompoundTag itemComp = (CompoundTag) itemTag;
short id = itemComp.getShort("id");
String idStr = itemComp.getString("id");
if (idStr != null && !MathMan.isInteger(idStr)) {
idStr = idStr.split(":")[1].toLowerCase();
idStr = idStr.split(":")[0].toLowerCase();
id = (short) ItemType.getId(idStr);
}
ids[i] = id;
@ -63,13 +63,13 @@ public class StateWrapper {
}
public CompoundTag getTag() {
if (this.tag != null) {
return this.tag;
if (tag != null) {
return tag;
}
if (state instanceof InventoryHolder) {
InventoryHolder inv = (InventoryHolder) state;
ItemStack[] contents = inv.getInventory().getContents();
Map<String, Tag> values = new HashMap<String, Tag>();
final InventoryHolder inv = (InventoryHolder) state;
final ItemStack[] contents = inv.getInventory().getContents();
final Map<String, Tag> values = new HashMap<>();
values.put("Items", new ListTag("Items", CompoundTag.class, serializeInventory(contents)));
return new CompoundTag(values);
}
@ -80,11 +80,11 @@ public class StateWrapper {
return "Chest";
}
public List<CompoundTag> serializeInventory(ItemStack[] items) {
List<CompoundTag> tags = new ArrayList<CompoundTag>();
public List<CompoundTag> serializeInventory(final ItemStack[] items) {
final List<CompoundTag> tags = new ArrayList<>();
for (int i = 0; i < items.length; ++i) {
if (items[i] != null) {
Map<String, Tag> tagData = serializeItem(items[i]);
final Map<String, Tag> tagData = serializeItem(items[i]);
tagData.put("Slot", new ByteTag("Slot", (byte) i));
tags.add(new CompoundTag(tagData));
}
@ -92,28 +92,32 @@ public class StateWrapper {
return tags;
}
public Map<String, Tag> serializeItem(org.spongepowered.api.item.inventory.ItemStack item) {
Map<String, Tag> data = new HashMap<String, Tag>();
/*
* TODO: Move this into the sponge module!
*
public Map<String, Tag> serializeItem(final org.spongepowered.api.item.inventory.ItemStack item) {
final Map<String, Tag> data = new HashMap<String, Tag>();
// FIXME serialize sponge item
return data;
}
*/
public Map<String, Tag> serializeItem(ItemStack item) {
Map<String, Tag> data = new HashMap<String, Tag>();
public Map<String, Tag> serializeItem(final ItemStack item) {
final Map<String, Tag> data = new HashMap<>();
data.put("id", new ShortTag("id", (short) item.getTypeId()));
data.put("Damage", new ShortTag("Damage", item.getDurability()));
data.put("Count", new ByteTag("Count", (byte) item.getAmount()));
if (!item.getEnchantments().isEmpty()) {
List<CompoundTag> enchantmentList = new ArrayList<CompoundTag>();
for(Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
Map<String, Tag> enchantment = new HashMap<String, Tag>();
final List<CompoundTag> enchantmentList = new ArrayList<>();
for (final Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
final Map<String, Tag> enchantment = new HashMap<>();
enchantment.put("id", new ShortTag("id", (short) entry.getKey().getId()));
enchantment.put("lvl", new ShortTag("lvl", entry.getValue().shortValue()));
enchantmentList.add(new CompoundTag(enchantment));
}
Map<String, Tag> auxData = new HashMap<String, Tag>();
final Map<String, Tag> auxData = new HashMap<>();
auxData.put("ench", new ListTag("ench", CompoundTag.class, enchantmentList));
data.put("tag", new CompoundTag("tag", auxData));
}

View File

@ -4,13 +4,17 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.AbstractTitle;
import com.plotsquared.bukkit.object.BukkitPlayer;
import java.lang.reflect.InvocationTargetException;
public class DefaultTitle extends AbstractTitle {
@Override
public void sendTitle(final PlotPlayer player, final String head, final String sub, int in, int delay, int out) {
public void sendTitle(final PlotPlayer player, final String head, final String sub, final int in, final int delay, final int out) {
try {
final DefaultTitleManager title = new DefaultTitleManager(head, sub, in, delay, out);
title.send(((BukkitPlayer) player).player);
} catch (final Throwable e) {
} catch (ClassNotFoundException | InvocationTargetException | SecurityException | NoSuchMethodException | InstantiationException |
IllegalArgumentException | IllegalAccessException e) {
AbstractTitle.TITLE_CLASS = new DefaultTitle_183();
AbstractTitle.TITLE_CLASS.sendTitle(player, head, sub, in, delay, out);
}

View File

@ -1,15 +1,15 @@
package com.plotsquared.bukkit.titles;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
/**
* [ PlotSquared DefaultTitleManager by Maxim Van de Wynckel ]
*
@ -18,6 +18,8 @@ import org.bukkit.entity.Player;
*
*/
public class DefaultTitleManager {
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<>();
/* Title packet */
private Class<?> packetTitle;
/* Title packet actions ENUM */
@ -36,7 +38,6 @@ public class DefaultTitleManager {
private int stayTime = -1;
private int fadeOutTime = -1;
private boolean ticks = false;
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<Class<?>, Class<?>>();
/**
* Create a new 1.8 title
@ -75,13 +76,13 @@ public class DefaultTitleManager {
public DefaultTitleManager(final DefaultTitleManager title) throws ClassNotFoundException {
// Copy title
this.title = title.title;
this.subtitle = title.subtitle;
this.titleColor = title.titleColor;
this.subtitleColor = title.subtitleColor;
this.fadeInTime = title.fadeInTime;
this.fadeOutTime = title.fadeOutTime;
this.stayTime = title.stayTime;
this.ticks = title.ticks;
subtitle = title.subtitle;
titleColor = title.titleColor;
subtitleColor = title.subtitleColor;
fadeInTime = title.fadeInTime;
fadeOutTime = title.fadeOutTime;
stayTime = title.stayTime;
ticks = title.ticks;
loadClasses();
}
@ -100,7 +101,8 @@ public class DefaultTitleManager {
* Fade out time
* @throws ClassNotFoundException
*/
public DefaultTitleManager(final String title, final String subtitle, final int fadeInTime, final int stayTime, final int fadeOutTime) throws ClassNotFoundException {
public DefaultTitleManager(final String title, final String subtitle, final int fadeInTime, final int stayTime, final int fadeOutTime)
throws ClassNotFoundException {
this.title = title;
this.subtitle = subtitle;
this.fadeInTime = fadeInTime;
@ -109,15 +111,36 @@ public class DefaultTitleManager {
loadClasses();
}
private static boolean equalsTypeArray(final Class<?>[] a, final Class<?>[] o) {
if (a.length != o.length) {
return false;
}
for (int i = 0; i < a.length; i++) {
if (!a[i].equals(o[i]) && !a[i].isAssignableFrom(o[i])) {
return false;
}
}
return true;
}
/**
* Load spigot and NMS classes
* @throws ClassNotFoundException
*/
private void loadClasses() throws ClassNotFoundException {
this.packetTitle = getNMSClass("PacketPlayOutTitle");
this.packetActions = getNMSClass("EnumTitleAction");
this.chatBaseComponent = getNMSClass("IChatBaseComponent");
this.nmsChatSerializer = getNMSClass("ChatSerializer");
packetTitle = getNMSClass("PacketPlayOutTitle");
packetActions = getNMSClass("EnumTitleAction");
chatBaseComponent = getNMSClass("IChatBaseComponent");
nmsChatSerializer = getNMSClass("ChatSerializer");
}
/**
* Get title text
*
* @return Title text
*/
public String getTitle() {
return title;
}
/**
@ -131,12 +154,12 @@ public class DefaultTitleManager {
}
/**
* Get title text
* Get subtitle text
*
* @return Title text
* @return Subtitle text
*/
public String getTitle() {
return this.title;
public String getSubtitle() {
return subtitle;
}
/**
@ -149,15 +172,6 @@ public class DefaultTitleManager {
this.subtitle = subtitle;
}
/**
* Get subtitle text
*
* @return Subtitle text
*/
public String getSubtitle() {
return this.subtitle;
}
/**
* Set the title color
*
@ -165,7 +179,7 @@ public class DefaultTitleManager {
* Chat color
*/
public void setTitleColor(final ChatColor color) {
this.titleColor = color;
titleColor = color;
}
/**
@ -175,7 +189,7 @@ public class DefaultTitleManager {
* Chat color
*/
public void setSubtitleColor(final ChatColor color) {
this.subtitleColor = color;
subtitleColor = color;
}
/**
@ -185,7 +199,7 @@ public class DefaultTitleManager {
* Time
*/
public void setFadeInTime(final int time) {
this.fadeInTime = time;
fadeInTime = time;
}
/**
@ -195,7 +209,7 @@ public class DefaultTitleManager {
* Time
*/
public void setFadeOutTime(final int time) {
this.fadeOutTime = time;
fadeOutTime = time;
}
/**
@ -205,21 +219,21 @@ public class DefaultTitleManager {
* Time
*/
public void setStayTime(final int time) {
this.stayTime = time;
stayTime = time;
}
/**
* Set timings to ticks
*/
public void setTimingsToTicks() {
this.ticks = true;
ticks = true;
}
/**
* Set timings to seconds
*/
public void setTimingsToSeconds() {
this.ticks = false;
ticks = false;
}
/**
@ -231,28 +245,34 @@ public class DefaultTitleManager {
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public void send(final Player player) throws Exception {
if (this.packetTitle != null) {
public void send(final Player player)
throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException,
SecurityException {
if (packetTitle != null) {
// First reset previous settings
resetTitle(player);
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Object[] actions = packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2], null, this.fadeInTime * (this.ticks ? 1 : 20), this.stayTime * (this.ticks ? 1 : 20), this.fadeOutTime * (this.ticks ? 1 : 20));
Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE)
.newInstance(actions[2], null, fadeInTime * (ticks ? 1 : 20),
stayTime * (ticks ? 1 : 20), fadeOutTime * (ticks ? 1 : 20));
// Send if set
if ((this.fadeInTime != -1) && (this.fadeOutTime != -1) && (this.stayTime != -1)) {
if (fadeInTime != -1 && fadeOutTime != -1 && stayTime != -1) {
sendPacket.invoke(connection, packet);
}
// Send title
Object serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.title) + "\",color:" + this.titleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[0], serialized);
Object serialized = getMethod(nmsChatSerializer, "a", String.class).invoke(null,
"{text:\"" + ChatColor.translateAlternateColorCodes('&', title) + "\",color:" + titleColor.name().toLowerCase() + "}");
packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[0], serialized);
sendPacket.invoke(connection, packet);
if (this.subtitle != "") {
if (!subtitle.isEmpty()) {
// Send subtitle if present
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.subtitle) + "\",color:" + this.subtitleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[1], serialized);
serialized = getMethod(nmsChatSerializer, "a", String.class).invoke(null,
"{text:\"" + ChatColor.translateAlternateColorCodes('&', subtitle) + "\",color:" + subtitleColor.name().toLowerCase() + "}");
packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[1], serialized);
sendPacket.invoke(connection, packet);
}
}
@ -260,9 +280,12 @@ public class DefaultTitleManager {
/**
* Broadcast the title to all players
* @throws Exception
* @throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException,
SecurityException
*/
public void broadcast() throws Exception {
public void broadcast()
throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException,
SecurityException {
for (final Player p : Bukkit.getOnlinePlayers()) {
send(p);
}
@ -276,14 +299,16 @@ public class DefaultTitleManager {
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
public void clearTitle(final Player player) throws Exception {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[3], null);
sendPacket.invoke(connection, packet);
public void clearTitle(final Player player)
throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException,
SecurityException {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[3], null);
sendPacket.invoke(connection, packet);
}
/**
@ -292,13 +317,15 @@ public class DefaultTitleManager {
* @param player
* Player
*/
public void resetTitle(final Player player) throws Exception {
// Send timings first
public void resetTitle(final Player player)
throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException,
SecurityException {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Object[] actions = packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[4], null);
final Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[4], null);
sendPacket.invoke(connection, packet);
}
@ -315,22 +342,16 @@ public class DefaultTitleManager {
return types;
}
private static boolean equalsTypeArray(final Class<?>[] a, final Class<?>[] o) {
if (a.length != o.length) {
return false;
}
for (int i = 0; i < a.length; i++) {
if (!a[i].equals(o[i]) && !a[i].isAssignableFrom(o[i])) {
return false;
}
}
return true;
}
private Object getHandle(final Object obj) {
try {
return getMethod("getHandle", obj.getClass()).invoke(obj);
} catch (final Exception e) {
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
} catch (InvocationTargetException e) {
e.printStackTrace();
return null;
}
@ -349,15 +370,12 @@ public class DefaultTitleManager {
private String getVersion() {
final String name = Bukkit.getServer().getClass().getPackage().getName();
final String version = name.substring(name.lastIndexOf('.') + 1) + ".";
return version;
return name.substring(name.lastIndexOf('.') + 1) + ".";
}
private Class<?> getNMSClass(final String className) throws ClassNotFoundException {
final String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = null;
clazz = Class.forName(fullName);
return clazz;
return Class.forName(fullName);
}
private Field getField(final Class<?> clazz, final String name) {
@ -365,7 +383,10 @@ public class DefaultTitleManager {
final Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field;
} catch (final Exception e) {
} catch (NoSuchFieldException e) {
e.printStackTrace();
return null;
} catch (SecurityException e) {
e.printStackTrace();
return null;
}
@ -373,7 +394,7 @@ public class DefaultTitleManager {
private Method getMethod(final Class<?> clazz, final String name, final Class<?>... args) {
for (final Method m : clazz.getMethods()) {
if (m.getName().equals(name) && ((args.length == 0) || ClassListEqual(args, m.getParameterTypes()))) {
if (m.getName().equals(name) && (args.length == 0 || ClassListEqual(args, m.getParameterTypes()))) {
m.setAccessible(true);
return m;
}
@ -382,10 +403,10 @@ public class DefaultTitleManager {
}
private boolean ClassListEqual(final Class<?>[] l1, final Class<?>[] l2) {
boolean equal = true;
if (l1.length != l2.length) {
return false;
}
boolean equal = true;
for (int i = 0; i < l1.length; i++) {
if (l1[i] != l2[i]) {
equal = false;

View File

@ -1,15 +1,15 @@
package com.plotsquared.bukkit.titles;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
/**
* [ PlotSquared DefaultTitleManager by Maxim Van de Wynckel ]
*
@ -36,7 +36,7 @@ public class DefaultTitleManager_183 {
private int stayTime = -1;
private int fadeOutTime = -1;
private boolean ticks = false;
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<Class<?>, Class<?>>();
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<>();
/**
* Create a new 1.8 title
@ -75,13 +75,13 @@ public class DefaultTitleManager_183 {
public DefaultTitleManager_183(final DefaultTitleManager_183 title) throws ClassNotFoundException {
// Copy title
this.title = title.title;
this.subtitle = title.subtitle;
this.titleColor = title.titleColor;
this.subtitleColor = title.subtitleColor;
this.fadeInTime = title.fadeInTime;
this.fadeOutTime = title.fadeOutTime;
this.stayTime = title.stayTime;
this.ticks = title.ticks;
subtitle = title.subtitle;
titleColor = title.titleColor;
subtitleColor = title.subtitleColor;
fadeInTime = title.fadeInTime;
fadeOutTime = title.fadeOutTime;
stayTime = title.stayTime;
ticks = title.ticks;
loadClasses();
}
@ -114,10 +114,10 @@ public class DefaultTitleManager_183 {
* @throws ClassNotFoundException
*/
private void loadClasses() throws ClassNotFoundException {
this.packetTitle = getNMSClass("PacketPlayOutTitle");
this.chatBaseComponent = getNMSClass("IChatBaseComponent");
this.packetActions = getNMSClass("PacketPlayOutTitle$EnumTitleAction");
this.nmsChatSerializer = getNMSClass("IChatBaseComponent$ChatSerializer");
packetTitle = getNMSClass("PacketPlayOutTitle");
chatBaseComponent = getNMSClass("IChatBaseComponent");
packetActions = getNMSClass("PacketPlayOutTitle$EnumTitleAction");
nmsChatSerializer = getNMSClass("IChatBaseComponent$ChatSerializer");
}
@ -137,7 +137,7 @@ public class DefaultTitleManager_183 {
* @return Title text
*/
public String getTitle() {
return this.title;
return title;
}
/**
@ -156,7 +156,7 @@ public class DefaultTitleManager_183 {
* @return Subtitle text
*/
public String getSubtitle() {
return this.subtitle;
return subtitle;
}
/**
@ -166,7 +166,7 @@ public class DefaultTitleManager_183 {
* Chat color
*/
public void setTitleColor(final ChatColor color) {
this.titleColor = color;
titleColor = color;
}
/**
@ -176,7 +176,7 @@ public class DefaultTitleManager_183 {
* Chat color
*/
public void setSubtitleColor(final ChatColor color) {
this.subtitleColor = color;
subtitleColor = color;
}
/**
@ -186,7 +186,7 @@ public class DefaultTitleManager_183 {
* Time
*/
public void setFadeInTime(final int time) {
this.fadeInTime = time;
fadeInTime = time;
}
/**
@ -196,7 +196,7 @@ public class DefaultTitleManager_183 {
* Time
*/
public void setFadeOutTime(final int time) {
this.fadeOutTime = time;
fadeOutTime = time;
}
/**
@ -206,21 +206,21 @@ public class DefaultTitleManager_183 {
* Time
*/
public void setStayTime(final int time) {
this.stayTime = time;
stayTime = time;
}
/**
* Set timings to ticks
*/
public void setTimingsToTicks() {
this.ticks = true;
ticks = true;
}
/**
* Set timings to seconds
*/
public void setTimingsToSeconds() {
this.ticks = false;
ticks = false;
}
/**
@ -233,27 +233,30 @@ public class DefaultTitleManager_183 {
* @throws IllegalAccessException
*/
public void send(final Player player) throws Exception {
if (this.packetTitle != null) {
if (packetTitle != null) {
// First reset previous settings
resetTitle(player);
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Object[] actions = packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2], null, this.fadeInTime * (this.ticks ? 1 : 20), this.stayTime * (this.ticks ? 1 : 20), this.fadeOutTime * (this.ticks ? 1 : 20));
Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2], null, fadeInTime * (ticks ? 1 : 20),
stayTime * (ticks ? 1 : 20), fadeOutTime * (ticks ? 1 : 20));
// Send if set
if ((this.fadeInTime != -1) && (this.fadeOutTime != -1) && (this.stayTime != -1)) {
if ((fadeInTime != -1) && (fadeOutTime != -1) && (stayTime != -1)) {
sendPacket.invoke(connection, packet);
}
// Send title
Object serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.title) + "\",color:" + this.titleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[0], serialized);
Object serialized = getMethod(nmsChatSerializer, "a", String.class).invoke(null,
"{text:\"" + ChatColor.translateAlternateColorCodes('&', title) + "\",color:" + titleColor.name().toLowerCase() + "}");
packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[0], serialized);
sendPacket.invoke(connection, packet);
if (this.subtitle != "") {
if (!subtitle.isEmpty()) {
// Send subtitle if present
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.subtitle) + "\",color:" + this.subtitleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[1], serialized);
serialized = getMethod(nmsChatSerializer, "a", String.class).invoke(null,
"{text:\"" + ChatColor.translateAlternateColorCodes('&', subtitle) + "\",color:" + subtitleColor.name().toLowerCase() + "}");
packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[1], serialized);
sendPacket.invoke(connection, packet);
}
}
@ -278,13 +281,13 @@ public class DefaultTitleManager_183 {
* @throws IllegalArgumentException
*/
public void clearTitle(final Player player) throws Exception {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[3], null);
sendPacket.invoke(connection, packet);
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[3], null);
sendPacket.invoke(connection, packet);
}
/**
@ -303,9 +306,9 @@ public class DefaultTitleManager_183 {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Object[] actions = packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions, this.chatBaseComponent).newInstance(actions[4], null);
final Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[4], null);
sendPacket.invoke(connection, packet);
}
@ -362,9 +365,7 @@ public class DefaultTitleManager_183 {
private Class<?> getNMSClass(final String className) throws ClassNotFoundException {
final String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = null;
clazz = Class.forName(fullName);
return clazz;
return Class.forName(fullName);
}
private Field getField(final Class<?> clazz, final String name) {
@ -389,10 +390,10 @@ public class DefaultTitleManager_183 {
}
private boolean ClassListEqual(final Class<?>[] l1, final Class<?>[] l2) {
boolean equal = true;
if (l1.length != l2.length) {
return false;
}
boolean equal = true;
for (int i = 0; i < l1.length; i++) {
if (l1[i] != l2[i]) {
equal = false;

View File

@ -6,7 +6,7 @@ import com.plotsquared.bukkit.object.BukkitPlayer;
public class DefaultTitle_183 extends AbstractTitle {
@Override
public void sendTitle(final PlotPlayer player, final String head, final String sub, int in, int delay, int out) {
public void sendTitle(final PlotPlayer player, final String head, final String sub, final int in, final int delay, final int out) {
try {
final DefaultTitleManager_183 title = new DefaultTitleManager_183(head, sub, in, delay, out);
title.send(((BukkitPlayer) player).player);

View File

@ -8,11 +8,11 @@ import com.plotsquared.bukkit.object.BukkitPlayer;
public class HackTitle extends AbstractTitle {
@Override
public void sendTitle(final PlotPlayer player, final String head, final String sub, int in, int delay, int out) {
public void sendTitle(final PlotPlayer player, final String head, final String sub, final int in, final int delay, final int out) {
try {
final HackTitleManager title = new HackTitleManager(head, sub, in, delay, out);
title.send(((BukkitPlayer) player).player);
} catch (final Throwable e) {
} catch (Exception e) {
PS.debug("&cYour server version does not support titles!");
Settings.TITLES = false;
AbstractTitle.TITLE_CLASS = null;

View File

@ -1,14 +1,15 @@
package com.plotsquared.bukkit.titles;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* Minecraft 1.8 Title
*
@ -33,7 +34,7 @@ public class HackTitleManager {
private int stayTime = -1;
private int fadeOutTime = -1;
private boolean ticks = false;
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<Class<?>, Class<?>>();
private static final Map<Class<?>, Class<?>> CORRESPONDING_TYPES = new HashMap<>();
/**
* Create a new 1.8 title
@ -72,13 +73,13 @@ public class HackTitleManager {
public HackTitleManager(final HackTitleManager title) throws ClassNotFoundException {
// Copy title
this.title = title.title;
this.subtitle = title.subtitle;
this.titleColor = title.titleColor;
this.subtitleColor = title.subtitleColor;
this.fadeInTime = title.fadeInTime;
this.fadeOutTime = title.fadeOutTime;
this.stayTime = title.stayTime;
this.ticks = title.ticks;
subtitle = title.subtitle;
titleColor = title.titleColor;
subtitleColor = title.subtitleColor;
fadeInTime = title.fadeInTime;
fadeOutTime = title.fadeOutTime;
stayTime = title.stayTime;
ticks = title.ticks;
loadClasses();
}
@ -111,9 +112,9 @@ public class HackTitleManager {
* @throws ClassNotFoundException
*/
private void loadClasses() throws ClassNotFoundException {
this.packetTitle = getClass("org.spigotmc.ProtocolInjector$PacketTitle");
this.packetActions = getClass("org.spigotmc.ProtocolInjector$PacketTitle$Action");
this.nmsChatSerializer = getNMSClass("ChatSerializer");
packetTitle = getClass("org.spigotmc.ProtocolInjector$PacketTitle");
packetActions = getClass("org.spigotmc.ProtocolInjector$PacketTitle$Action");
nmsChatSerializer = getNMSClass("ChatSerializer");
}
/**
@ -132,7 +133,7 @@ public class HackTitleManager {
* @return Title text
*/
public String getTitle() {
return this.title;
return title;
}
/**
@ -151,7 +152,7 @@ public class HackTitleManager {
* @return Subtitle text
*/
public String getSubtitle() {
return this.subtitle;
return subtitle;
}
/**
@ -161,7 +162,7 @@ public class HackTitleManager {
* Chat color
*/
public void setTitleColor(final ChatColor color) {
this.titleColor = color;
titleColor = color;
}
/**
@ -171,7 +172,7 @@ public class HackTitleManager {
* Chat color
*/
public void setSubtitleColor(final ChatColor color) {
this.subtitleColor = color;
subtitleColor = color;
}
/**
@ -181,7 +182,7 @@ public class HackTitleManager {
* Time
*/
public void setFadeInTime(final int time) {
this.fadeInTime = time;
fadeInTime = time;
}
/**
@ -191,7 +192,7 @@ public class HackTitleManager {
* Time
*/
public void setFadeOutTime(final int time) {
this.fadeOutTime = time;
fadeOutTime = time;
}
/**
@ -201,21 +202,21 @@ public class HackTitleManager {
* Time
*/
public void setStayTime(final int time) {
this.stayTime = time;
stayTime = time;
}
/**
* Set timings to ticks
*/
public void setTimingsToTicks() {
this.ticks = true;
ticks = true;
}
/**
* Set timings to seconds
*/
public void setTimingsToSeconds() {
this.ticks = false;
ticks = false;
}
/**
@ -225,27 +226,30 @@ public class HackTitleManager {
* Player
*/
public void send(final Player player) throws Exception {
if ((getProtocolVersion(player) >= 47) && isSpigot() && (this.packetTitle != null)) {
if ((getProtocolVersion(player) >= 47) && isSpigot() && (packetTitle != null)) {
// First reset previous settings
resetTitle(player);
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Object[] actions = packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
Object packet = this.packetTitle.getConstructor(this.packetActions, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2], this.fadeInTime * (this.ticks ? 1 : 20), this.stayTime * (this.ticks ? 1 : 20), this.fadeOutTime * (this.ticks ? 1 : 20));
Object packet = packetTitle.getConstructor(packetActions, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2], fadeInTime * (ticks ? 1 : 20), stayTime * (ticks ? 1 : 20),
fadeOutTime * (ticks ? 1 : 20));
// Send if set
if ((this.fadeInTime != -1) && (this.fadeOutTime != -1) && (this.stayTime != -1)) {
if ((fadeInTime != -1) && (fadeOutTime != -1) && (stayTime != -1)) {
sendPacket.invoke(connection, packet);
}
// Send title
Object serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.title) + "\",color:" + this.titleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, getNMSClass("IChatBaseComponent")).newInstance(actions[0], serialized);
Object serialized = getMethod(nmsChatSerializer, "a", String.class).invoke(null,
"{text:\"" + ChatColor.translateAlternateColorCodes('&', title) + "\",color:" + titleColor.name().toLowerCase() + "}");
packet = packetTitle.getConstructor(packetActions, getNMSClass("IChatBaseComponent")).newInstance(actions[0], serialized);
sendPacket.invoke(connection, packet);
if (this.subtitle != "") {
if (!subtitle.isEmpty()) {
// Send subtitle if present
serialized = getMethod(this.nmsChatSerializer, "a", String.class).invoke(null, "{text:\"" + ChatColor.translateAlternateColorCodes('&', this.subtitle) + "\",color:" + this.subtitleColor.name().toLowerCase() + "}");
packet = this.packetTitle.getConstructor(this.packetActions, getNMSClass("IChatBaseComponent")).newInstance(actions[1], serialized);
serialized = getMethod(nmsChatSerializer, "a", String.class).invoke(null,
"{text:\"" + ChatColor.translateAlternateColorCodes('&', subtitle) + "\",color:" + subtitleColor.name().toLowerCase() + "}");
packet = packetTitle.getConstructor(packetActions, getNMSClass("IChatBaseComponent")).newInstance(actions[1], serialized);
sendPacket.invoke(connection, packet);
}
}
@ -272,9 +276,9 @@ public class HackTitleManager {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Object[] actions = packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions).newInstance(actions[3]);
final Object packet = packetTitle.getConstructor(packetActions).newInstance(actions[3]);
sendPacket.invoke(connection, packet);
}
}
@ -291,9 +295,9 @@ public class HackTitleManager {
// Send timings first
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object[] actions = this.packetActions.getEnumConstants();
final Object[] actions = packetActions.getEnumConstants();
final Method sendPacket = getMethod(connection.getClass(), "sendPacket");
final Object packet = this.packetTitle.getConstructor(this.packetActions).newInstance(actions[4]);
final Object packet = packetTitle.getConstructor(packetActions).newInstance(actions[4]);
sendPacket.invoke(connection, packet);
}
}
@ -310,8 +314,7 @@ public class HackTitleManager {
final Object handle = getHandle(player);
final Object connection = getField(handle.getClass(), "playerConnection").get(handle);
final Object networkManager = getValue("networkManager", connection);
Integer version = (Integer) getMethod("getVersion", networkManager.getClass()).invoke(networkManager);
return version;
return (Integer) getMethod("getVersion", networkManager.getClass()).invoke(networkManager);
}
/**
@ -333,7 +336,7 @@ public class HackTitleManager {
private Class<?> getClass(final String namespace) {
try {
return Class.forName(namespace);
} catch (final Exception e) {
} catch (ClassNotFoundException e) {
}
return null;
}
@ -376,7 +379,7 @@ public class HackTitleManager {
private Object getHandle(final Object obj) {
try {
return getMethod("getHandle", obj.getClass()).invoke(obj);
} catch (final Exception e) {
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
return null;
}
@ -395,15 +398,12 @@ public class HackTitleManager {
private String getVersion() {
final String name = Bukkit.getServer().getClass().getPackage().getName();
final String version = name.substring(name.lastIndexOf('.') + 1) + ".";
return version;
return name.substring(name.lastIndexOf('.') + 1) + ".";
}
private Class<?> getNMSClass(final String className) throws ClassNotFoundException {
final String fullName = "net.minecraft.server." + getVersion() + className;
Class<?> clazz = null;
clazz = Class.forName(fullName);
return clazz;
return Class.forName(fullName);
}
private Field getField(final Class<?> clazz, final String name) {
@ -411,7 +411,7 @@ public class HackTitleManager {
final Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field;
} catch (final Exception e) {
} catch (SecurityException | NoSuchFieldException e) {
e.printStackTrace();
return null;
}
@ -428,10 +428,10 @@ public class HackTitleManager {
}
private boolean ClassListEqual(final Class<?>[] l1, final Class<?>[] l2) {
boolean equal = true;
if (l1.length != l2.length) {
return false;
}
boolean equal = true;
for (int i = 0; i < l1.length; i++) {
if (l1[i] != l2[i]) {
equal = false;

View File

@ -0,0 +1,60 @@
package com.plotsquared.bukkit.util;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.object.ConsolePlayer;
import com.intellectualcrafters.plot.object.PlotMessage;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.ChatManager;
import com.plotsquared.bukkit.chat.FancyMessage;
import com.plotsquared.bukkit.object.BukkitPlayer;
import org.bukkit.ChatColor;
import java.util.ArrayList;
import java.util.List;
public class BukkitChatManager extends ChatManager<FancyMessage> {
@Override
public FancyMessage builder() {
return new FancyMessage("");
}
@Override
public void color(final PlotMessage m, final String color) {
m.$(this).color(ChatColor.getByChar(C.color(color).substring(1)));
}
@Override
public void tooltip(final PlotMessage m, final PlotMessage... tooltips) {
final List<FancyMessage> lines = new ArrayList<>();
for (final PlotMessage tooltip : tooltips) {
lines.add(tooltip.$(this));
}
m.$(this).formattedTooltip(lines);
}
@Override
public void command(final PlotMessage m, final String command) {
m.$(this).command(command);
}
@Override
public void text(final PlotMessage m, final String text) {
m.$(this).then(ChatColor.stripColor(text));
}
@Override
public void send(final PlotMessage m, final PlotPlayer player) {
if (ConsolePlayer.isConsole(player)) {
player.sendMessage(m.$(this).toOldMessageFormat());
} else {
m.$(this).send(((BukkitPlayer) player).player);
}
}
@Override
public void suggest(final PlotMessage m, final String command) {
m.$(this).suggest(command);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +1,28 @@
package com.plotsquared.bukkit.util;
import com.intellectualcrafters.plot.commands.MainCommand;
import com.intellectualcrafters.plot.object.ConsolePlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.StringComparison;
import com.plotsquared.bukkit.commands.DebugUUID;
import com.plotsquared.general.commands.Command;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import com.intellectualcrafters.plot.commands.DebugUUID;
import com.intellectualcrafters.plot.commands.MainCommand;
import com.intellectualcrafters.plot.object.ConsolePlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.StringComparison;
import com.plotsquared.general.commands.Command;
/**
* Created 2015-02-20 for PlotSquared
*
* @author Citymonstret
*/
public class BukkitCommand implements CommandExecutor, TabCompleter {
@ -31,15 +31,43 @@ public class BukkitCommand implements CommandExecutor, TabCompleter {
}
@Override
public boolean onCommand(final CommandSender commandSender, final org.bukkit.command.Command command, final String commandLabel, final String[] args) {
public boolean onCommand(final CommandSender commandSender, final org.bukkit.command.Command command, final String commandLabel,
final String[] args) {
if (commandSender instanceof Player) {
return MainCommand.onCommand(BukkitUtil.getPlayer((Player) commandSender), commandLabel, args);
}
return MainCommand.onCommand(ConsolePlayer.getConsole(), commandLabel, args);
if (commandSender == null || commandSender.getClass() == Bukkit.getConsoleSender().getClass()) {
return MainCommand.onCommand(ConsolePlayer.getConsole(), commandLabel, args);
}
@SuppressWarnings("deprecation")
ConsolePlayer sender = new ConsolePlayer() {
@Override
public void sendMessage(String message) {
commandSender.sendMessage(commandLabel);
}
@Override
public boolean hasPermission(String perm) {
return commandSender.hasPermission(commandLabel);
}
@Override
public String getName() {
if (commandSender.getName().equals("CONSOLE")) {
return "*";
}
return commandSender.getName();
}
};
sender.teleport(ConsolePlayer.getConsole().getLocationFull());
boolean result = MainCommand.onCommand(sender, commandLabel, args);
ConsolePlayer.getConsole().teleport(sender.getLocationFull());
return result;
}
@Override
public List<String> onTabComplete(final CommandSender commandSender, final org.bukkit.command.Command command, final String s, final String[] strings) {
public List<String> onTabComplete(final CommandSender commandSender, final org.bukkit.command.Command command, final String s,
final String[] strings) {
if (!(commandSender instanceof Player)) {
return null;
}
@ -52,32 +80,27 @@ public class BukkitCommand implements CommandExecutor, TabCompleter {
if (strings.length > 1) {
return null;
}
if (!command.getLabel().equalsIgnoreCase("plots")) {
return null;
}
final Set<String> tabOptions = new HashSet<>();
ArrayList<Command<PlotPlayer>> commands = MainCommand.getInstance().getCommands();
String best = new StringComparison(strings[0], commands).getBestMatch();
tabOptions.add(best);
final String arg = strings[0].toLowerCase();
ArrayList<String> labels = new ArrayList<>();
for (final Command<PlotPlayer> cmd : MainCommand.getInstance().getCommands()) {
String label = cmd.getCommand();
if (!label.equalsIgnoreCase(best)) {
if (label.startsWith(arg)) {
final String label = cmd.getCommand();
HashSet<String> aliases = new HashSet<>(cmd.getAliases());
aliases.add(label);
for (String alias : aliases) {
labels.add(alias);
if (alias.startsWith(arg)) {
if (Permissions.hasPermission(player, cmd.getPermission())) {
tabOptions.add(cmd.getCommand());
} else if (cmd.getAliases().size() > 0) {
for (String alias : cmd.getAliases()) {
if (alias.startsWith(arg)) {
tabOptions.add(label);
break;
}
}
tabOptions.add(label);
} else {
break;
}
}
}
}
if (tabOptions.size() > 0) {
String best = new StringComparison<>(arg, labels).getBestMatch();
tabOptions.add(best);
if (!tabOptions.isEmpty()) {
return new ArrayList<>(tabOptions);
}
return null;

View File

@ -0,0 +1,98 @@
package com.plotsquared.bukkit.util;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.EconHandler;
import com.plotsquared.bukkit.object.BukkitOfflinePlayer;
import com.plotsquared.bukkit.object.BukkitPlayer;
public class BukkitEconHandler extends EconHandler {
private Economy econ;
private Permission perms;
public Economy getEconomy() {
init();
return econ;
}
public Permission getPermissions() {
init();
return perms;
}
public boolean init() {
if (econ == null || perms == null) {
setupPermissions();
setupEconomy();
}
return econ != null && perms != null;
}
private boolean setupPermissions() {
final RegisteredServiceProvider<Permission> permissionProvider =
Bukkit.getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class);
if (permissionProvider != null) {
perms = permissionProvider.getProvider();
}
return perms != null;
}
private boolean setupEconomy() {
final RegisteredServiceProvider<Economy> economyProvider =
Bukkit.getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if (economyProvider != null) {
econ = economyProvider.getProvider();
}
return econ != null;
}
@Override
public double getMoney(final PlotPlayer player) {
final double bal = super.getMoney(player);
if (Double.isNaN(bal)) {
return econ.getBalance(((BukkitPlayer) player).player);
}
return bal;
}
@Override
public void withdrawMoney(final PlotPlayer player, final double amount) {
econ.withdrawPlayer(((BukkitPlayer) player).player, amount);
}
@Override
public void depositMoney(final PlotPlayer player, final double amount) {
econ.depositPlayer(((BukkitPlayer) player).player, amount);
}
@Override
public void depositMoney(final OfflinePlotPlayer player, final double amount) {
econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount);
}
@Override
public void setPermission(final String world, final String player, final String perm, final boolean value) {
if (value) {
perms.playerAdd(world, player, perm);
} else {
perms.playerRemove(world, player, perm);
}
}
@Override
public boolean hasPermission(final String world, final String player, final String perm) {
return perms.playerHas(world, Bukkit.getOfflinePlayer(player), perm);
}
@Override
public double getBalance(PlotPlayer player) {
return econ.getBalance(player.getName());
}
}

View File

@ -1,16 +1,9 @@
package com.plotsquared.bukkit.util;
import java.util.ArrayList;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import com.intellectualcrafters.plot.flag.Flag;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.PlotCluster;
import com.intellectualcrafters.plot.object.PlotId;
import com.intellectualcrafters.plot.object.PlotPlayer;
@ -32,97 +25,101 @@ import com.plotsquared.bukkit.events.PlotMergeEvent;
import com.plotsquared.bukkit.events.PlotRateEvent;
import com.plotsquared.bukkit.events.PlotUnlinkEvent;
import com.plotsquared.bukkit.object.BukkitPlayer;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import java.util.ArrayList;
import java.util.UUID;
public class BukkitEventUtil extends EventUtil {
public Player getPlayer(PlotPlayer player) {
public Player getPlayer(final PlotPlayer player) {
if (player instanceof BukkitPlayer) {
return ((BukkitPlayer) player).player;
}
return null;
}
public boolean callEvent(Event event) {
public boolean callEvent(final Event event) {
Bukkit.getServer().getPluginManager().callEvent(event);
if (event instanceof Cancellable) {
return !((Cancellable) event).isCancelled();
}
return true;
return !(event instanceof Cancellable) || !((Cancellable) event).isCancelled();
}
@Override
public boolean callClaim(PlotPlayer player, Plot plot, boolean auto) {
public boolean callClaim(final PlotPlayer player, final Plot plot, final boolean auto) {
return callEvent(new PlayerClaimPlotEvent(getPlayer(player), plot, auto));
}
@Override
public boolean callTeleport(PlotPlayer player, Location from, Plot plot) {
public boolean callTeleport(final PlotPlayer player, final Location from, final Plot plot) {
return callEvent(new PlayerTeleportToPlotEvent(getPlayer(player), from, plot));
}
@Override
public boolean callClear(String world, PlotId id) {
return callEvent(new PlotClearEvent(world, id));
public boolean callClear(final Plot plot) {
return callEvent(new PlotClearEvent(plot));
}
@Override
public void callDelete(String world, PlotId id) {
callEvent(new PlotDeleteEvent(world, id));
public void callDelete(final Plot plot) {
callEvent(new PlotDeleteEvent(plot));
}
@Override
public boolean callFlagAdd(Flag flag, Plot plot) {
public boolean callFlagAdd(final Flag flag, final Plot plot) {
return callEvent(new PlotFlagAddEvent(flag, plot));
}
@Override
public boolean callFlagRemove(Flag flag, Plot plot) {
public boolean callFlagRemove(final Flag flag, final Plot plot) {
return callEvent(new PlotFlagRemoveEvent(flag, plot));
}
@Override
public boolean callMerge(String world, Plot plot, ArrayList<PlotId> plots) {
return callEvent(new PlotMergeEvent(BukkitUtil.getWorld(world), plot, plots));
public boolean callMerge(final Plot plot, final ArrayList<PlotId> plots) {
return callEvent(new PlotMergeEvent(BukkitUtil.getWorld(plot.getArea().worldname), plot, plots));
}
@Override
public boolean callUnlink(String world, ArrayList<PlotId> plots) {
return callEvent(new PlotUnlinkEvent(BukkitUtil.getWorld(world), plots));
public boolean callUnlink(final PlotArea area, final ArrayList<PlotId> plots) {
return callEvent(new PlotUnlinkEvent(BukkitUtil.getWorld(area.worldname), area, plots));
}
@Override
public void callEntry(PlotPlayer player, Plot plot) {
public void callEntry(final PlotPlayer player, final Plot plot) {
callEvent(new PlayerEnterPlotEvent(getPlayer(player), plot));
}
@Override
public void callLeave(PlotPlayer player, Plot plot) {
public void callLeave(final PlotPlayer player, final Plot plot) {
callEvent(new PlayerLeavePlotEvent(getPlayer(player), plot));
}
@Override
public void callDenied(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
public void callDenied(final PlotPlayer initiator, final Plot plot, final UUID player, final boolean added) {
callEvent(new PlayerPlotDeniedEvent(getPlayer(initiator), plot, player, added));
}
@Override
public void callTrusted(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
public void callTrusted(final PlotPlayer initiator, final Plot plot, final UUID player, final boolean added) {
callEvent(new PlayerPlotHelperEvent(getPlayer(initiator), plot, player, added));
}
@Override
public void callMember(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
public void callMember(final PlotPlayer initiator, final Plot plot, final UUID player, final boolean added) {
callEvent(new PlayerPlotTrustedEvent(getPlayer(initiator), plot, player, added));
}
@Override
public boolean callFlagRemove(Flag flag, PlotCluster cluster) {
public boolean callFlagRemove(final Flag flag, final PlotCluster cluster) {
return callEvent(new ClusterFlagRemoveEvent(flag, cluster));
}
@Override
public Rating callRating(PlotPlayer player, Plot plot, Rating rating) {
PlotRateEvent event = new PlotRateEvent(player, rating, plot);
public Rating callRating(final PlotPlayer player, final Plot plot, final Rating rating) {
final PlotRateEvent event = new PlotRateEvent(player, rating, plot);
Bukkit.getServer().getPluginManager().callEvent(event);
return event.getRating();
}

View File

@ -0,0 +1,323 @@
package com.plotsquared.bukkit.util;
import java.util.HashSet;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.bukkit.material.Directional;
import org.bukkit.material.MaterialData;
import com.intellectualcrafters.plot.generator.HybridUtils;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotAnalysis;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.TaskManager;
public class BukkitHybridUtils extends HybridUtils {
@Override
public void analyzeRegion(final String world, final RegionWrapper region, final RunnableVal<PlotAnalysis> whenDone) {
// int diff, int variety, int vertices, int rotation, int height_sd
/*
* diff: compare to base by looping through all blocks
* variety: add to HashSet for each PlotBlock
* height_sd: loop over all blocks and get top block
*
* vertices: store air map and compare with neighbours
* for each block check the adjacent
* - Store all blocks then go through in second loop
* - recheck each block
*
*/
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
final World worldObj = Bukkit.getWorld(world);
final ChunkGenerator gen = worldObj.getGenerator();
if (gen == null) {
return;
}
final BiomeGrid nullBiomeGrid = new BiomeGrid() {
@Override
public void setBiome(final int a, final int b, final Biome c) {
}
@Override
public Biome getBiome(final int a, final int b) {
return null;
}
};
final Location bot = new Location(world, region.minX, region.minY, region.minZ);
final Location top = new Location(world, region.maxX, region.maxY, region.maxZ);
final int bx = bot.getX();
final int bz = bot.getZ();
final int tx = top.getX();
final int tz = top.getZ();
final int cbx = bx >> 4;
final int cbz = bz >> 4;
final int ctx = tx >> 4;
final int ctz = tz >> 4;
final Random r = new Random();
MainUtil.initCache();
final int width = (tx - bx) + 1;
final int length = (tz - bz) + 1;
System.gc();
System.gc();
final short[][][] oldblocks = new short[256][width][length];
final short[][][] newblocks = new short[256][width][length];
final Runnable run = new Runnable() {
@Override
public void run() {
ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
@Override
public void run(int[] value) {
// [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge]
final int X = value[0];
final int Z = value[1];
final short[][] result = gen.generateExtBlockSections(worldObj, r, X, Z, nullBiomeGrid);
final int xb = ((X) << 4) - bx;
final int zb = ((Z) << 4) - bz;
for (int i = 0; i < result.length; i++) {
if (result[i] == null) {
for (int j = 0; j < 4096; j++) {
final int x = MainUtil.x_loc[i][j] + xb;
if ((x < 0) || (x >= width)) {
continue;
}
final int z = MainUtil.z_loc[i][j] + zb;
if ((z < 0) || (z >= length)) {
continue;
}
final int y = MainUtil.y_loc[i][j];
oldblocks[y][x][z] = 0;
}
continue;
}
for (int j = 0; j < result[i].length; j++) {
final int x = MainUtil.x_loc[i][j] + xb;
if ((x < 0) || (x >= width)) {
continue;
}
final int z = MainUtil.z_loc[i][j] + zb;
if ((z < 0) || (z >= length)) {
continue;
}
final int y = MainUtil.y_loc[i][j];
oldblocks[y][x][z] = result[i][j];
}
}
}
}, new Runnable() {
@Override
public void run() {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
final int size = width * length;
final int[] changes = new int[size];
final int[] faces = new int[size];
final int[] data = new int[size];
final int[] air = new int[size];
final int[] variety = new int[size];
int i = 0;
for (int x = 0; x < width; x++) {
for (int z = 0; z < length; z++) {
final HashSet<Short> types = new HashSet<>();
for (int y = 0; y < 256; y++) {
final short old = oldblocks[y][x][z];
final short now = newblocks[y][x][z];
if (old != now) {
changes[i]++;
}
if (now == 0) {
air[i]++;
} else {
// check vertices
// modifications_adjacent
if ((x > 0) && (z > 0) && (y > 0) && (x < (width - 1)) && (z < (length - 1)) && (y < 255)) {
if (newblocks[y - 1][x][z] == 0) {
faces[i]++;
}
if (newblocks[y][x - 1][z] == 0) {
faces[i]++;
}
if (newblocks[y][x][z - 1] == 0) {
faces[i]++;
}
if (newblocks[y + 1][x][z] == 0) {
faces[i]++;
}
if (newblocks[y][x + 1][z] == 0) {
faces[i]++;
}
if (newblocks[y][x][z + 1] == 0) {
faces[i]++;
}
}
final Material material = Material.getMaterial(now);
final Class<? extends MaterialData> md = material.getData();
if (md.equals(Directional.class)) {
data[i] += 8;
} else if (!md.equals(MaterialData.class)) {
data[i]++;
}
types.add(now);
}
}
variety[i] = types.size();
i++;
}
}
// analyze plot
// put in analysis obj
// run whenDone
final PlotAnalysis analysis = new PlotAnalysis();
analysis.changes = (int) (MathMan.getMean(changes) * 100);
analysis.faces = (int) (MathMan.getMean(faces) * 100);
analysis.data = (int) (MathMan.getMean(data) * 100);
analysis.air = (int) (MathMan.getMean(air) * 100);
analysis.variety = (int) (MathMan.getMean(variety) * 100);
analysis.changes_sd = (int) (MathMan.getSD(changes, analysis.changes));
analysis.faces_sd = (int) (MathMan.getSD(faces, analysis.faces));
analysis.data_sd = (int) (MathMan.getSD(data, analysis.data));
analysis.air_sd = (int) (MathMan.getSD(air, analysis.air));
analysis.variety_sd = (int) (MathMan.getSD(variety, analysis.variety));
System.gc();
System.gc();
whenDone.value = analysis;
whenDone.run();
}
});
}
}, 5);
}
};
System.gc();
MainUtil.initCache();
ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
@Override
public void run(int[] value) {
final int X = value[0];
final int Z = value[1];
worldObj.loadChunk(X, Z);
int minX;
int minZ;
int maxX;
int maxZ;
if (X == cbx) {
minX = bx & 15;
} else {
minX = 0;
}
if (Z == cbz) {
minZ = bz & 15;
} else {
minZ = 0;
}
if (X == ctx) {
maxX = tx & 15;
} else {
maxX = 16;
}
if (Z == ctz) {
maxZ = tz & 15;
} else {
maxZ = 16;
}
final int cbx = X << 4;
final int cbz = Z << 4;
final int xb = (cbx) - bx;
final int zb = (cbz) - bz;
for (int x = minX; x <= maxX; x++) {
final int xx = cbx + x;
for (int z = minZ; z <= maxZ; z++) {
final int zz = cbz + z;
for (int y = 0; y < 256; y++) {
final Block block = worldObj.getBlockAt(xx, y, zz);
final int xr = xb + x;
final int zr = zb + z;
newblocks[y][xr][zr] = (short) block.getTypeId();
}
}
}
worldObj.unloadChunkRequest(X, Z, true);
}
}, new Runnable() {
@Override
public void run() {
TaskManager.runTaskAsync(run);
}
}, 5);
}
});
}
@Override
public int checkModified(final String worldname, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2,
final PlotBlock[] blocks) {
final World world = BukkitUtil.getWorld(worldname);
int count = 0;
for (int y = y1; y <= y2; y++) {
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
final Block block = world.getBlockAt(x, y, z);
final int id = block.getTypeId();
boolean same = false;
for (final PlotBlock p : blocks) {
if (id == p.id) {
same = true;
break;
}
}
if (!same) {
count++;
}
}
}
}
return count;
}
@Override
public int get_ey(final String worldname, final int sx, final int ex, final int sz, final int ez, final int sy) {
final World world = BukkitUtil.getWorld(worldname);
final int maxY = world.getMaxHeight();
int ey = sy;
for (int x = sx; x <= ex; x++) {
for (int z = sz; z <= ez; z++) {
for (int y = sy; y < maxY; y++) {
if (y > ey) {
final Block block = world.getBlockAt(x, y, z);
if (block.getTypeId() != 0) {
ey = y;
}
}
}
}
}
return ey;
}
}

View File

@ -1,8 +1,10 @@
package com.plotsquared.bukkit.util;
import java.util.ArrayList;
import java.util.List;
import com.intellectualcrafters.plot.object.PlotInventory;
import com.intellectualcrafters.plot.object.PlotItemStack;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.InventoryUtil;
import com.plotsquared.bukkit.object.BukkitPlayer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.event.inventory.InventoryType;
@ -12,77 +14,16 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import com.intellectualcrafters.plot.object.PlotInventory;
import com.intellectualcrafters.plot.object.PlotItemStack;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.InventoryUtil;
import com.plotsquared.bukkit.object.BukkitPlayer;
import java.util.ArrayList;
import java.util.List;
public class BukkitInventoryUtil extends InventoryUtil {
@Override
public void open(PlotInventory inv) {
BukkitPlayer bp = ((BukkitPlayer) inv.player);
Inventory inventory = Bukkit.createInventory(null, inv.size * 9, inv.getTitle());
PlotItemStack[] items = inv.getItems();
for (int i = 0; i < inv.size * 9; i++) {
PlotItemStack item = items[i];
if (item != null) {
inventory.setItem(i, getItem(item));
}
}
inv.player.setMeta("inventory", inv);
bp.player.openInventory(inventory);
}
@Override
public void close(PlotInventory inv) {
if (!inv.isOpen()) {
return;
}
inv.player.deleteMeta("inventory");
BukkitPlayer bp = ((BukkitPlayer) inv.player);
bp.player.closeInventory();
}
@Override
public void setItem(PlotInventory inv, int index, PlotItemStack item) {
BukkitPlayer bp = ((BukkitPlayer) inv.player);
InventoryView opened = bp.player.getOpenInventory();
if (!inv.isOpen()) {
return;
}
opened.setItem(index, getItem(item));
bp.player.updateInventory();
}
public PlotItemStack getItem(ItemStack item ) {
public static ItemStack getItem(final PlotItemStack item) {
if (item == null) {
return null;
}
int id = item.getTypeId();
short data = item.getDurability();
int amount = item.getAmount();
String name = null;
String[] lore = null;
if (item.hasItemMeta()) {
ItemMeta meta = item.getItemMeta();
if (meta.hasDisplayName()) {
name = meta.getDisplayName();
}
if (meta.hasLore()) {
List<String> itemLore = meta.getLore();
lore = itemLore.toArray(new String[itemLore.size()]);
}
}
return new PlotItemStack(id, data, amount, name, lore);
}
public static ItemStack getItem(PlotItemStack item) {
if (item == null) {
return null;
}
ItemStack stack = new ItemStack(item.id, item.amount, item.data);
final ItemStack stack = new ItemStack(item.id, item.amount, item.data);
ItemMeta meta = null;
if (item.name != null) {
meta = stack.getItemMeta();
@ -92,8 +33,8 @@ public class BukkitInventoryUtil extends InventoryUtil {
if (meta == null) {
meta = stack.getItemMeta();
}
List<String> lore = new ArrayList<>();
for (String entry : item.lore) {
final List<String> lore = new ArrayList<>();
for (final String entry : item.lore) {
lore.add(ChatColor.translateAlternateColorCodes('&', entry));
}
meta.setLore(lore);
@ -105,10 +46,68 @@ public class BukkitInventoryUtil extends InventoryUtil {
}
@Override
public PlotItemStack[] getItems(PlotPlayer player) {
BukkitPlayer bp = ((BukkitPlayer) player);
PlayerInventory inv = bp.player.getInventory();
PlotItemStack[] items = new PlotItemStack[36];
public void open(final PlotInventory inv) {
final BukkitPlayer bp = (BukkitPlayer) inv.player;
final Inventory inventory = Bukkit.createInventory(null, inv.size * 9, inv.getTitle());
final PlotItemStack[] items = inv.getItems();
for (int i = 0; i < inv.size * 9; i++) {
final PlotItemStack item = items[i];
if (item != null) {
inventory.setItem(i, getItem(item));
}
}
inv.player.setMeta("inventory", inv);
bp.player.openInventory(inventory);
}
@Override
public void close(final PlotInventory inv) {
if (!inv.isOpen()) {
return;
}
inv.player.deleteMeta("inventory");
final BukkitPlayer bp = (BukkitPlayer) inv.player;
bp.player.closeInventory();
}
@Override
public void setItem(final PlotInventory inv, final int index, final PlotItemStack item) {
final BukkitPlayer bp = (BukkitPlayer) inv.player;
final InventoryView opened = bp.player.getOpenInventory();
if (!inv.isOpen()) {
return;
}
opened.setItem(index, getItem(item));
bp.player.updateInventory();
}
public PlotItemStack getItem(final ItemStack item) {
if (item == null) {
return null;
}
final int id = item.getTypeId();
final short data = item.getDurability();
final int amount = item.getAmount();
String name = null;
String[] lore = null;
if (item.hasItemMeta()) {
final ItemMeta meta = item.getItemMeta();
if (meta.hasDisplayName()) {
name = meta.getDisplayName();
}
if (meta.hasLore()) {
final List<String> itemLore = meta.getLore();
lore = itemLore.toArray(new String[itemLore.size()]);
}
}
return new PlotItemStack(id, data, amount, name, lore);
}
@Override
public PlotItemStack[] getItems(final PlotPlayer player) {
final BukkitPlayer bp = (BukkitPlayer) player;
final PlayerInventory inv = bp.player.getInventory();
final PlotItemStack[] items = new PlotItemStack[36];
for (int i = 0; i < 36; i++) {
items[i] = getItem(inv.getItem(i));
}
@ -116,12 +115,12 @@ public class BukkitInventoryUtil extends InventoryUtil {
}
@Override
public boolean isOpen(PlotInventory inv) {
public boolean isOpen(final PlotInventory inv) {
if (!inv.isOpen()) {
return false;
}
BukkitPlayer bp = ((BukkitPlayer) inv.player);
InventoryView opened = bp.player.getOpenInventory();
return (inv.isOpen() && opened.getType() == InventoryType.CRAFTING && opened.getTitle() == null);
final BukkitPlayer bp = (BukkitPlayer) inv.player;
final InventoryView opened = bp.player.getOpenInventory();
return inv.isOpen() && opened.getType() == InventoryType.CRAFTING && opened.getTitle() == null;
}
}

View File

@ -0,0 +1,50 @@
package com.plotsquared.bukkit.util;
import com.intellectualcrafters.plot.object.PlotMessage;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.ChatManager;
import org.bukkit.ChatColor;
import java.util.ArrayList;
import java.util.List;
public class BukkitPlainChatManager extends ChatManager<List<StringBuilder>> {
@Override
public List<StringBuilder> builder() {
return new ArrayList<>();
}
@Override
public void color(final PlotMessage m, final String color) {
final List<StringBuilder> parts = m.$(this);
parts.get(parts.size() - 1).insert(0, color);
}
@Override
public void tooltip(final PlotMessage m, final PlotMessage... tooltips) {
}
@Override
public void command(final PlotMessage m, final String command) {
}
@Override
public void text(final PlotMessage m, final String text) {
m.$(this).add(new StringBuilder(ChatColor.stripColor(text)));
}
@Override
public void send(final PlotMessage m, final PlotPlayer player) {
final StringBuilder built = new StringBuilder();
for (final StringBuilder sb : m.$(this)) {
built.append(sb);
}
player.sendMessage(built.toString());
}
@Override
public void suggest(final PlotMessage m, final String command) {
}
}

View File

@ -0,0 +1,340 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
// PlotSquared - A plot manager and world generator for the Bukkit API /
// Copyright (c) 2014 IntellectualSites/IntellectualCrafters /
// /
// This program is free software; you can redistribute it and/or modify /
// it under the terms of the GNU General Public License as published by /
// the Free Software Foundation; either version 3 of the License, or /
// (at your option) any later version. /
// /
// This program is distributed in the hope that it will be useful, /
// but WITHOUT ANY WARRANTY; without even the implied warranty of /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /
// GNU General Public License for more details. /
// /
// You should have received a copy of the GNU General Public License /
// along with this program; if not, write to the Free Software Foundation, /
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA /
// /
// You can contact us via: support@intellectualsites.com /
////////////////////////////////////////////////////////////////////////////////////////////////////
package com.plotsquared.bukkit.util;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import com.intellectualcrafters.jnbt.ByteArrayTag;
import com.intellectualcrafters.jnbt.CompoundTag;
import com.intellectualcrafters.jnbt.IntTag;
import com.intellectualcrafters.jnbt.ListTag;
import com.intellectualcrafters.jnbt.ShortTag;
import com.intellectualcrafters.jnbt.StringTag;
import com.intellectualcrafters.jnbt.Tag;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.SchematicHandler;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.object.schematic.StateWrapper;
/**
* Schematic Handler
*
*/
public class BukkitSchematicHandler extends SchematicHandler {
@Override
public void getCompoundTag(final String world, final Set<RegionWrapper> regions, final RunnableVal<CompoundTag> whenDone) {
// async
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
// Main positions
Location[] corners = MainUtil.getCorners(world, regions);
final Location bot = corners[0];
final Location top = corners[1];
final int width = (top.getX() - bot.getX()) + 1;
final int height = (top.getY() - bot.getY()) + 1;
final int length = (top.getZ() - bot.getZ()) + 1;
// Main Schematic tag
final HashMap<String, Tag> schematic = new HashMap<>();
schematic.put("Width", new ShortTag("Width", (short) width));
schematic.put("Length", new ShortTag("Length", (short) length));
schematic.put("Height", new ShortTag("Height", (short) height));
schematic.put("Materials", new StringTag("Materials", "Alpha"));
schematic.put("WEOriginX", new IntTag("WEOriginX", 0));
schematic.put("WEOriginY", new IntTag("WEOriginY", 0));
schematic.put("WEOriginZ", new IntTag("WEOriginZ", 0));
schematic.put("WEOffsetX", new IntTag("WEOffsetX", 0));
schematic.put("WEOffsetY", new IntTag("WEOffsetY", 0));
schematic.put("WEOffsetZ", new IntTag("WEOffsetZ", 0));
// Arrays of data types
final List<Tag> tileEntities = new ArrayList<>();
final byte[] blocks = new byte[width * height * length];
final byte[] blockData = new byte[width * height * length];
// Queue
final ArrayDeque<RegionWrapper> queue = new ArrayDeque<>(regions);
TaskManager.runTask(new Runnable() {
@Override
public void run() {
if (queue.isEmpty()) {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
schematic.put("Blocks", new ByteArrayTag("Blocks", blocks));
schematic.put("Data", new ByteArrayTag("Data", blockData));
schematic.put("Entities", new ListTag("Entities", CompoundTag.class, new ArrayList<Tag>()));
schematic.put("TileEntities", new ListTag("TileEntities", CompoundTag.class, tileEntities));
whenDone.value = new CompoundTag("Schematic", schematic);
TaskManager.runTask(whenDone);
System.gc();
System.gc();
}
});
return;
}
final Runnable regionTask = this;
RegionWrapper region = queue.poll();
Location pos1 = new Location(world, region.minX, region.minY, region.minZ);
Location pos2 = new Location(world, region.maxX, region.maxY, region.maxZ);
final int bx = bot.getX();
final int bz = bot.getZ();
final int p1x = pos1.getX();
final int p1z = pos1.getZ();
final int p2x = pos2.getX();
final int p2z = pos2.getZ();
final int bcx = p1x >> 4;
final int bcz = p1z >> 4;
final int tcx = p2x >> 4;
final int tcz = p2z >> 4;
final int sy = pos1.getY();
final int ey = pos2.getY();
// Generate list of chunks
final ArrayList<ChunkLoc> chunks = new ArrayList<>();
for (int x = bcx; x <= tcx; x++) {
for (int z = bcz; z <= tcz; z++) {
chunks.add(new ChunkLoc(x, z));
}
}
final World worldObj = Bukkit.getWorld(world);
// Main thread
TaskManager.runTask(new Runnable() {
@Override
public void run() {
final long start = System.currentTimeMillis();
while ((!chunks.isEmpty()) && ((System.currentTimeMillis() - start) < 20)) {
// save schematics
final ChunkLoc chunk = chunks.remove(0);
final Chunk bc = worldObj.getChunkAt(chunk.x, chunk.z);
if (!bc.load(false)) {
continue;
}
final int X = chunk.x;
final int Z = chunk.z;
int xxb = X << 4;
int zzb = Z << 4;
int xxt = xxb + 15;
int zzt = zzb + 15;
if (X == bcx) {
xxb = p1x;
}
if (X == tcx) {
xxt = p2x;
}
if (Z == bcz) {
zzb = p1z;
}
if (Z == tcz) {
zzt = p2z;
}
for (int y = sy; y <= Math.min(255, ey); y++) {
final int ry = y - sy;
final int i1 = (ry * width * length);
for (int z = zzb; z <= zzt; z++) {
final int rz = z - bz;
final int i2 = i1 + (rz * width);
for (int x = xxb; x <= xxt; x++) {
final int rx = x - bx;
final int index = i2 + rx;
final Block block = worldObj.getBlockAt(x, y, z);
final int id = block.getTypeId();
switch (id) {
case 0:
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 24:
case 30:
case 32:
case 37:
case 39:
case 40:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
case 51:
case 55:
case 56:
case 57:
case 58:
case 60:
case 7:
case 8:
case 9:
case 10:
case 11:
case 73:
case 74:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 121:
case 122:
case 129:
case 133:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192: {
break;
}
case 54:
case 130:
case 142:
case 27:
case 137:
case 52:
case 154:
case 84:
case 25:
case 144:
case 138:
case 176:
case 177:
case 63:
case 68:
case 323:
case 117:
case 116:
case 28:
case 66:
case 157:
case 61:
case 62:
case 140:
case 146:
case 149:
case 150:
case 158:
case 23:
case 123:
case 124:
case 29:
case 33:
case 151:
case 178: {
// TODO implement fully
final BlockState state = block.getState();
if (state != null) {
final StateWrapper wrapper = new StateWrapper(state);
final CompoundTag rawTag = wrapper.getTag();
if (rawTag != null) {
final Map<String, Tag> values = new HashMap<String, Tag>();
for (final Entry<String, Tag> entry : rawTag.getValue().entrySet()) {
values.put(entry.getKey(), entry.getValue());
}
values.put("id", new StringTag("id", wrapper.getId()));
values.put("x", new IntTag("x", x));
values.put("y", new IntTag("y", y));
values.put("z", new IntTag("z", z));
final CompoundTag tileEntityTag = new CompoundTag(values);
tileEntities.add(tileEntityTag);
}
}
}
default: {
blockData[index] = block.getData();
}
}
// For optimization reasons, we are not supporting custom data types
// Especially since the most likely reason beyond this range is modded servers in which the blocks
// have NBT
// if (type > 255) {
// if (addBlocks == null) {
// addBlocks = new byte[(blocks.length >> 1) + 1];
// }
// addBlocks[index >> 1] = (byte) (((index & 1) == 0) ?
// (addBlocks[index >> 1] & 0xF0) | ((type >> 8) & 0xF) : (addBlocks[index >> 1] & 0xF) | (((type
// >> 8) & 0xF) << 4));
// }
blocks[index] = (byte) id;
}
}
}
}
if (!chunks.isEmpty()) {
TaskManager.runTaskLater(this, 1);
} else {
regionTask.run();
}
}
});
}
});
}
});
}
@Override
public void restoreTag(CompoundTag ct, short x, short y, short z, Schematic schem) {
new StateWrapper(ct).restoreTag(x, y, z, schem);
}
}

View File

@ -0,0 +1,204 @@
package com.plotsquared.bukkit.util;
import com.intellectualcrafters.configuration.ConfigurationSection;
import com.intellectualcrafters.configuration.file.YamlConfiguration;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.ConfigurationNode;
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
import com.intellectualcrafters.plot.object.PlotArea;
import com.intellectualcrafters.plot.object.SetupObject;
import com.intellectualcrafters.plot.util.SetupUtils;
import com.plotsquared.bukkit.generator.BukkitPlotGenerator;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.WorldCreator;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.Plugin;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Objects;
public class BukkitSetupUtils extends SetupUtils {
@Override
public void updateGenerators() {
if (!SetupUtils.generators.isEmpty()) {
return;
}
final String testWorld = "CheckingPlotSquaredGenerator";
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
if (plugin.isEnabled()) {
final ChunkGenerator generator = plugin.getDefaultWorldGenerator(testWorld, "");
if (generator != null) {
PS.get().removePlotAreas(testWorld);
final String name = plugin.getDescription().getName();
GeneratorWrapper<?> wrapped;
if (generator instanceof GeneratorWrapper<?>) {
wrapped = (GeneratorWrapper<?>) generator;
} else {
wrapped = new BukkitPlotGenerator(testWorld, generator);
}
SetupUtils.generators.put(name, wrapped);
}
}
}
}
@Override
public String setupWorld(final SetupObject object) {
SetupUtils.manager.updateGenerators();
ConfigurationNode[] steps = object.step == null ? new ConfigurationNode[0] : object.step;
final String world = object.world;
int type = object.type;
String worldPath = "worlds." + object.world;
if (!PS.get().config.contains(worldPath)) {
PS.get().config.createSection(worldPath);
}
ConfigurationSection worldSection = PS.get().config.getConfigurationSection(worldPath);
switch (type) {
case 2: {
if (object.id != null) {
String areaname = object.id + "-" + object.min + "-" + object.max;
String areaPath = "areas." + areaname;
if (!worldSection.contains(areaPath)) {
worldSection.createSection(areaPath);
}
ConfigurationSection areaSection = worldSection.getConfigurationSection(areaPath);
HashMap<String, Object> options = new HashMap<>();
for (final ConfigurationNode step : steps) {
options.put(step.getConstant(), step.getValue());
}
options.put("generator.type", object.type);
options.put("generator.terrain", object.terrain);
options.put("generator.plugin", object.plotManager);
if ((object.setupGenerator != null) && !object.setupGenerator.equals(object.plotManager)) {
options.put("generator.init", object.setupGenerator);
}
for (Entry<String, Object> entry : options.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (worldSection.contains(key)) {
Object current = worldSection.get(key);
if (!Objects.equals(value, current)) {
areaSection.set(key, value);
}
} else {
worldSection.set(key, value);
}
}
}
GeneratorWrapper<?> gen = generators.get(object.setupGenerator);
if ((gen != null) && gen.isFull()) {
object.setupGenerator = null;
}
break;
}
case 1: {
for (final ConfigurationNode step : steps) {
worldSection.set(step.getConstant(), step.getValue());
}
PS.get().config.set("worlds." + world + "." + "generator.type", object.type);
PS.get().config.set("worlds." + world + "." + "generator.terrain", object.terrain);
PS.get().config.set("worlds." + world + "." + "generator.plugin", object.plotManager);
if ((object.setupGenerator != null) && !object.setupGenerator.equals(object.plotManager)) {
PS.get().config.set("worlds." + world + "." + "generator.init", object.setupGenerator);
}
GeneratorWrapper<?> gen = generators.get(object.setupGenerator);
if ((gen != null) && gen.isFull()) {
object.setupGenerator = null;
}
break;
}
case 0: {
for (final ConfigurationNode step : steps) {
worldSection.set(step.getConstant(), step.getValue());
}
break;
}
}
try {
PS.get().config.save(PS.get().configFile);
} catch (final IOException e) {
e.printStackTrace();
}
if (object.setupGenerator != null) {
if ((Bukkit.getPluginManager().getPlugin("Multiverse-Core") != null) && Bukkit.getPluginManager().getPlugin("Multiverse-Core")
.isEnabled()) {
Bukkit.getServer()
.dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv create " + world + " normal -g " + object.setupGenerator);
setGenerator(world, object.setupGenerator);
if (Bukkit.getWorld(world) != null) {
return world;
}
}
if ((Bukkit.getPluginManager().getPlugin("MultiWorld") != null) && Bukkit.getPluginManager().getPlugin("MultiWorld").isEnabled()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + world + " plugin:" + object.setupGenerator);
setGenerator(world, object.setupGenerator);
if (Bukkit.getWorld(world) != null) {
return world;
}
}
final WorldCreator wc = new WorldCreator(object.world);
wc.generator(object.setupGenerator);
wc.environment(Environment.NORMAL);
Bukkit.createWorld(wc);
setGenerator(world, object.setupGenerator);
} else {
if ((Bukkit.getPluginManager().getPlugin("Multiverse-Core") != null) && Bukkit.getPluginManager().getPlugin("Multiverse-Core")
.isEnabled()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mv create " + world + " normal");
if (Bukkit.getWorld(world) != null) {
return world;
}
}
if ((Bukkit.getPluginManager().getPlugin("MultiWorld") != null) && Bukkit.getPluginManager().getPlugin("MultiWorld").isEnabled()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + world);
if (Bukkit.getWorld(world) != null) {
return world;
}
}
Bukkit.createWorld(new WorldCreator(object.world).environment(World.Environment.NORMAL));
}
return object.world;
}
public void setGenerator(final String world, final String generator) {
if ((Bukkit.getWorlds().isEmpty()) || !Bukkit.getWorlds().get(0).getName().equals(world)) {
return;
}
final File file = new File("bukkit.yml").getAbsoluteFile();
final YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
yml.set("worlds." + world + ".generator", generator);
try {
yml.save(file);
} catch (final IOException e) {
e.printStackTrace();
}
}
@Override
public String getGenerator(final PlotArea plotworld) {
if (SetupUtils.generators.isEmpty()) {
updateGenerators();
}
final World world = Bukkit.getWorld(plotworld.worldname);
if (world == null) {
return null;
}
final ChunkGenerator generator = world.getGenerator();
if (!(generator instanceof BukkitPlotGenerator)) {
return null;
}
for (final Entry<String, GeneratorWrapper<?>> entry : generators.entrySet()) {
GeneratorWrapper<?> current = entry.getValue();
if (current.equals(generator)) {
return entry.getKey();
}
}
return null;
}
}

View File

@ -1,17 +1,17 @@
package com.plotsquared.bukkit.util;
import org.bukkit.Bukkit;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.BukkitMain;
import org.bukkit.Bukkit;
public class BukkitTaskManager extends TaskManager {
@Override
public int taskRepeat(final Runnable r, final int interval) {
return BukkitMain.THIS.getServer().getScheduler().scheduleSyncRepeatingTask(BukkitMain.THIS, r, interval, interval);
}
@Override
@SuppressWarnings("deprecation") @Override
public int taskRepeatAsync(final Runnable r, final int interval) {
return BukkitMain.THIS.getServer().getScheduler().scheduleAsyncRepeatingTask(BukkitMain.THIS, r, interval, interval);
}

View File

@ -0,0 +1,294 @@
package com.plotsquared.bukkit.util;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.object.schematic.PlotItem;
import com.intellectualcrafters.plot.util.*;
import com.plotsquared.bukkit.object.BukkitPlayer;
import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.*;
import java.util.Arrays;
import java.util.List;
public class BukkitUtil extends WorldUtil {
private static String lastString = null;
private static World lastWorld = null;
private static Player lastPlayer = null;
private static PlotPlayer lastPlotPlayer = null;
public static void removePlayer(final String plr) {
lastPlayer = null;
lastPlotPlayer = null;
}
public static PlotPlayer getPlayer(final OfflinePlayer op) {
if (op.isOnline()) {
return getPlayer(op.getPlayer());
}
final Player player = OfflinePlayerUtil.loadPlayer(op);
player.loadData();
return new BukkitPlayer(player, true);
}
public static PlotPlayer getPlayer(final Player player) {
if (player == lastPlayer) {
return lastPlotPlayer;
}
final String name = player.getName();
final PlotPlayer pp = UUIDHandler.getPlayer(name);
if (pp != null) {
return pp;
}
lastPlotPlayer = new BukkitPlayer(player);
UUIDHandler.getPlayers().put(name, lastPlotPlayer);
lastPlayer = player;
return lastPlotPlayer;
}
public static Location getLocation(final org.bukkit.Location loc) {
return new Location(loc.getWorld().getName(), MathMan.roundInt(loc.getX()), MathMan.roundInt(loc.getY()), MathMan.roundInt(loc.getZ()));
}
public static org.bukkit.Location getLocation(final Location loc) {
return new org.bukkit.Location(getWorld(loc.getWorld()), loc.getX(), loc.getY(), loc.getZ());
}
public static World getWorld(final String string) {
if (StringMan.isEqual(string, lastString)) {
if (lastWorld != null) {
return lastWorld;
}
}
final World world = Bukkit.getWorld(string);
lastString = string;
lastWorld = world;
return world;
}
public static String getWorld(final Entity entity) {
return entity.getWorld().getName();
}
public static List<Entity> getEntities(final String worldname) {
return getWorld(worldname).getEntities();
}
public static Location getLocation(final Entity entity) {
final org.bukkit.Location loc = entity.getLocation();
final String world = loc.getWorld().getName();
return new Location(world, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
}
public static Location getLocationFull(final Entity entity) {
final org.bukkit.Location loc = entity.getLocation();
return new Location(loc.getWorld().getName(), MathMan.roundInt(loc.getX()), MathMan.roundInt(loc.getY()), MathMan.roundInt(loc.getZ()),
loc.getYaw(), loc.getPitch());
}
@Override
public boolean isWorld(final String world) {
return getWorld(world) != null;
}
@Override
public String getBiome(final String world, final int x, final int z) {
return getWorld(world).getBiome(x, z).name();
}
@Override
public void setSign(final String worldname, final int x, final int y, final int z, final String[] lines) {
final World world = getWorld(worldname);
final Block block = world.getBlockAt(x, y, z);
// block.setType(Material.AIR);
block.setTypeIdAndData(Material.WALL_SIGN.getId(), (byte) 2, false);
final BlockState blockstate = block.getState();
if (blockstate instanceof Sign) {
final Sign sign = (Sign) blockstate;
for (int i = 0; i < lines.length; i++) {
sign.setLine(i, lines[i]);
}
sign.update(true);
TaskManager.runTaskLater(new Runnable() {
@Override
public void run() {
sign.update(true);
}
}, 20);
}
}
@Override
public String[] getSign(final Location loc) {
final Block block = getWorld(loc.getWorld()).getBlockAt(loc.getX(), loc.getY(), loc.getZ());
if (block != null) {
if (block.getState() instanceof Sign) {
final Sign sign = (Sign) block.getState();
return sign.getLines();
}
}
return null;
}
@Override
public Location getSpawn(final String world) {
final org.bukkit.Location temp = getWorld(world).getSpawnLocation();
return new Location(world, temp.getBlockX(), temp.getBlockY(), temp.getBlockZ(), temp.getYaw(), temp.getPitch());
}
@Override
public int getHighestBlock(final String world, final int x, final int z) {
return getWorld(world).getHighestBlockAt(x, z).getY();
}
@Override
public int getBiomeFromString(final String biomeStr) {
try {
final Biome biome = Biome.valueOf(biomeStr.toUpperCase());
return Arrays.asList(Biome.values()).indexOf(biome);
} catch (final IllegalArgumentException e) {
return -1;
}
}
@Override
public String[] getBiomeList() {
final Biome[] biomes = Biome.values();
final String[] list = new String[biomes.length];
for (int i = 0; i < biomes.length; i++) {
list[i] = biomes[i].name();
}
return list;
}
@Override
public boolean addItems(final String worldname, final PlotItem items) {
final World world = getWorld(worldname);
final Block block = world.getBlockAt(items.x, items.y, items.z);
if (block == null) {
return false;
}
final BlockState state = block.getState();
if (state instanceof InventoryHolder) {
final InventoryHolder holder = (InventoryHolder) state;
final Inventory inv = holder.getInventory();
for (int i = 0; i < items.id.length; i++) {
final ItemStack item = new ItemStack(items.id[i], items.amount[i], items.data[i]);
inv.addItem(item);
}
state.update(true);
return true;
}
return false;
}
@Override
public boolean isBlockSolid(final PlotBlock block) {
try {
final Material material = Material.getMaterial(block.id);
if (material.isBlock() && material.isSolid() && !material.hasGravity()) {
final Class<? extends MaterialData> data = material.getData();
if (data.equals(MaterialData.class) && !material.isTransparent() && material.isOccluding()
|| data.equals(Tree.class)
|| data.equals(Sandstone.class)
|| data.equals(Wool.class)
|| data.equals(Step.class)
|| data.equals(WoodenStep.class)) {
switch (material) {
case NOTE_BLOCK:
case MOB_SPAWNER:
return false;
default:
return true;
}
}
}
return false;
} catch (final Exception e) {
return false;
}
}
@Override
public String getClosestMatchingName(final PlotBlock block) {
try {
return Material.getMaterial(block.id).name();
} catch (final Exception e) {
return null;
}
}
@Override
public StringComparison<PlotBlock>.ComparisonResult getClosestBlock(String name) {
try {
final Material material = Material.valueOf(name.toUpperCase());
return new StringComparison<PlotBlock>().new ComparisonResult(0, new PlotBlock((short) material.getId(), (byte) 0));
} catch (IllegalArgumentException e) {
}
try {
byte data;
final String[] split = name.split(":");
if (split.length == 2) {
data = Byte.parseByte(split[1]);
name = split[0];
} else {
data = 0;
}
double match;
short id;
if (MathMan.isInteger(split[0])) {
id = Short.parseShort(split[0]);
match = 0;
} else {
final StringComparison<Material>.ComparisonResult comparison = new StringComparison<>(name, Material.values()).getBestMatchAdvanced();
match = comparison.match;
id = (short) comparison.best.getId();
}
final PlotBlock block = new PlotBlock(id, data);
final StringComparison<PlotBlock> outer = new StringComparison<>();
return outer.new ComparisonResult(match, block);
} catch (NumberFormatException e) {
}
return null;
}
@Override
public void setBiomes(final String worldname, RegionWrapper region, final String biomeStr) {
final World world = getWorld(worldname);
final Biome biome = Biome.valueOf(biomeStr.toUpperCase());
for (int x = region.minX; x <= region.maxX; x++) {
for (int z = region.minZ; z <= region.maxZ; z++) {
world.setBiome(x, z, biome);
}
}
}
@Override
public PlotBlock getBlock(final Location loc) {
final World world = getWorld(loc.getWorld());
final Block block = world.getBlockAt(loc.getX(), loc.getY(), loc.getZ());
if (block == null) {
return new PlotBlock((short) 0, (byte) 0);
}
return new PlotBlock((short) block.getTypeId(), block.getData());
}
@Override
public String getMainWorld() {
return Bukkit.getWorlds().get(0).getName();
}
}

View File

@ -52,6 +52,7 @@ import com.intellectualcrafters.configuration.file.YamlConfiguration;
import com.intellectualcrafters.plot.PS;
public class Metrics {
/**
* The current revision number
*/
@ -107,20 +108,20 @@ public class Metrics {
}
this.plugin = plugin;
// load the config
this.configurationFile = getConfigFile();
this.configuration = YamlConfiguration.loadConfiguration(this.configurationFile);
configurationFile = getConfigFile();
configuration = YamlConfiguration.loadConfiguration(configurationFile);
// add some defaults
this.configuration.addDefault("opt-out", false);
this.configuration.addDefault("guid", UUID.randomUUID().toString());
this.configuration.addDefault("debug", false);
configuration.addDefault("opt-out", false);
configuration.addDefault("guid", UUID.randomUUID().toString());
configuration.addDefault("debug", false);
// Do we need to create the file?
if (this.configuration.get("guid", null) == null) {
this.configuration.options().header("http://mcstats.org").copyDefaults(true);
this.configuration.save(this.configurationFile);
if (configuration.get("guid", null) == null) {
configuration.options().header("http://mcstats.org").copyDefaults(true);
configuration.save(configurationFile);
}
// Load the guid then
this.guid = this.configuration.getString("guid");
this.debug = this.configuration.getBoolean("debug", false);
guid = configuration.getString("guid");
debug = configuration.getBoolean("debug", false);
}
/**
@ -158,7 +159,7 @@ public class Metrics {
*
* @throws UnsupportedEncodingException
*/
private static void appendJSONPair(final StringBuilder json, final String key, final String value) throws UnsupportedEncodingException {
private static void appendJSONPair(final StringBuilder json, final String key, final String value) {
boolean isValueNumeric = false;
try {
if (value.equals("0") || !value.endsWith("0")) {
@ -250,7 +251,7 @@ public class Metrics {
// Construct the graph object
final Graph graph = new Graph(name);
// Now we can add our graph
this.graphs.add(graph);
graphs.add(graph);
// and return back
return graph;
}
@ -264,7 +265,7 @@ public class Metrics {
if (graph == null) {
throw new IllegalArgumentException("Graph cannot be null");
}
this.graphs.add(graph);
graphs.add(graph);
}
/**
@ -275,17 +276,17 @@ public class Metrics {
* @return True if statistics measuring is running, otherwise false.
*/
public boolean start() {
synchronized (this.optOutLock) {
synchronized (optOutLock) {
// Did we opt out?
if (isOptOut()) {
return false;
}
// Is metrics already running?
if (this.task != null) {
if (task != null) {
return true;
}
// Begin hitting the server with glorious data
this.task = this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(this.plugin, new Runnable() {
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
private boolean firstPost = true;
@Override
@ -294,16 +295,16 @@ public class Metrics {
// This has to be synchronized or it can collide
// with
// the disable method.
synchronized (Metrics.this.optOutLock) {
synchronized (optOutLock) {
// Disable Task, if it is running and the
// server
// owner decided to opt-out
if (isOptOut() && (Metrics.this.task != null)) {
Metrics.this.task.cancel();
Metrics.this.task = null;
if (isOptOut() && task != null) {
task.cancel();
task = null;
// Tell all plotters to stop gathering
// information.
for (final Graph graph : Metrics.this.graphs) {
for (final Graph graph : graphs) {
graph.onOptOut();
}
}
@ -316,13 +317,13 @@ public class Metrics {
// Each time thereafter it will evaluate to
// TRUE, i.e
// PING!
postPlugin(!this.firstPost);
postPlugin(!firstPost);
// After the first post we set firstPost to
// false
// Each post thereafter will be a ping
this.firstPost = false;
firstPost = false;
} catch (final IOException e) {
if (Metrics.this.debug) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
}
}
@ -338,22 +339,22 @@ public class Metrics {
* @return true if metrics should be opted out of it
*/
public boolean isOptOut() {
synchronized (this.optOutLock) {
synchronized (optOutLock) {
try {
// Reload the metrics file
this.configuration.load(getConfigFile());
configuration.load(getConfigFile());
} catch (final IOException ex) {
if (this.debug) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
} catch (final InvalidConfigurationException ex) {
if (this.debug) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
}
return this.configuration.getBoolean("opt-out", false);
return configuration.getBoolean("opt-out", false);
}
}
@ -365,15 +366,15 @@ public class Metrics {
public void enable() throws IOException {
// This has to be synchronized or it can collide with the check in the
// task.
synchronized (this.optOutLock) {
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set
// it.
if (isOptOut()) {
this.configuration.set("opt-out", false);
this.configuration.save(this.configurationFile);
configuration.set("opt-out", false);
configuration.save(configurationFile);
}
// Enable Task, if it is not running
if (this.task == null) {
if (task == null) {
start();
}
}
@ -387,17 +388,17 @@ public class Metrics {
public void disable() throws IOException {
// This has to be synchronized or it can collide with the check in the
// task.
synchronized (this.optOutLock) {
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set
// it.
if (!isOptOut()) {
this.configuration.set("opt-out", true);
this.configuration.save(this.configurationFile);
configuration.set("opt-out", true);
configuration.save(configurationFile);
}
// Disable Task, if it is running
if (this.task != null) {
this.task.cancel();
this.task = null;
if (task != null) {
task.cancel();
task = null;
}
}
}
@ -414,7 +415,7 @@ public class Metrics {
// plugin.getDataFolder() => base/plugins/PluginA/
// pluginsFolder => base/plugins/
// The base is not necessarily relative to the startup directory.
final File pluginsFolder = this.plugin.getDataFolder().getParentFile();
final File pluginsFolder = plugin.getDataFolder().getParentFile();
// return => base/plugins/PluginMetrics/config.yml
return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
}
@ -424,7 +425,7 @@ public class Metrics {
*/
private void postPlugin(final boolean isPing) throws IOException {
// Server software specific section
final PluginDescriptionFile description = this.plugin.getDescription();
final PluginDescriptionFile description = plugin.getDescription();
final String pluginName = description.getName();
final boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE
// if
@ -437,9 +438,9 @@ public class Metrics {
int playersOnline = 0;
try {
if (Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).getReturnType() == Collection.class) {
playersOnline = ((Collection<?>) Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).invoke(null, new Object[0])).size();
playersOnline = ((Collection<?>) Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).invoke(null)).size();
} else {
playersOnline = ((Player[]) Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).invoke(null, new Object[0])).length;
playersOnline = ((Player[]) Bukkit.class.getMethod("getOnlinePlayers", new Class<?>[0]).invoke(null)).length;
}
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
}
@ -450,7 +451,7 @@ public class Metrics {
json.append('{');
// The plugin's description file containg all of the plugin data such as
// name, version, author, etc
appendJSONPair(json, "guid", this.guid);
appendJSONPair(json, "guid", guid);
appendJSONPair(json, "plugin_version", pluginVersion);
appendJSONPair(json, "server_version", serverVersion);
appendJSONPair(json, "players_online", Integer.toString(playersOnline));
@ -474,8 +475,8 @@ public class Metrics {
if (isPing) {
appendJSONPair(json, "ping", "1");
}
if (this.graphs.size() > 0) {
synchronized (this.graphs) {
if (!graphs.isEmpty()) {
synchronized (graphs) {
json.append(',');
json.append('"');
json.append("graphs");
@ -483,7 +484,7 @@ public class Metrics {
json.append(':');
json.append('{');
boolean firstGraph = true;
for (final Graph graph : this.graphs) {
for (final Graph graph : graphs) {
final StringBuilder graphJson = new StringBuilder();
graphJson.append('{');
for (final Plotter plotter : graph.getPlotters()) {
@ -524,20 +525,19 @@ public class Metrics {
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.setDoOutput(true);
if (this.debug) {
if (debug) {
PS.debug("[Metrics] Prepared request for " + pluginName + " uncompressed=" + uncompressed.length + " compressed=" + compressed.length);
}
// Write the data
final OutputStream os = connection.getOutputStream();
os.write(compressed);
os.flush();
// Now read the response
final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = reader.readLine();
// close resources
os.close();
reader.close();
if ((response == null) || response.startsWith("ERR") || response.startsWith("7")) {
String response;
try (OutputStream os = connection.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
os.write(compressed);
os.flush();
// Now read the response
response = reader.readLine();
}
if (response == null || response.startsWith("ERR") || response.startsWith("7")) {
if (response == null) {
response = "null";
} else if (response.startsWith("7")) {
@ -546,9 +546,9 @@ public class Metrics {
throw new IOException(response);
} else {
// Is this the first update this hour?
if (response.equals("1") || response.contains("This is your first update this hour")) {
synchronized (this.graphs) {
for (final Graph graph : this.graphs) {
if ("1".equals(response) || response.contains("This is your first update this hour")) {
synchronized (graphs) {
for (final Graph graph : graphs) {
for (final Plotter plotter : graph.getPlotters()) {
plotter.reset();
}
@ -567,7 +567,7 @@ public class Metrics {
try {
Class.forName("mineshafter.MineServer");
return true;
} catch (final Exception e) {
} catch (ClassNotFoundException e) {
return false;
}
}
@ -576,6 +576,7 @@ public class Metrics {
* Represents a custom graph on the website
*/
public static class Graph {
/**
* The graph's name, alphanumeric and spaces only :) If it does not comply to the above when submitted, it is
* rejected
@ -584,7 +585,7 @@ public class Metrics {
/**
* The set of plotters that are contained within this graph
*/
private final Set<Plotter> plotters = new LinkedHashSet<Plotter>();
private final Set<Plotter> plotters = new LinkedHashSet<>();
private Graph(final String name) {
this.name = name;
@ -596,7 +597,7 @@ public class Metrics {
* @return the Graph's name
*/
public String getName() {
return this.name;
return name;
}
/**
@ -605,7 +606,7 @@ public class Metrics {
* @param plotter the plotter to add to the graph
*/
public void addPlotter(final Plotter plotter) {
this.plotters.add(plotter);
plotters.add(plotter);
}
/**
@ -614,7 +615,7 @@ public class Metrics {
* @param plotter the plotter to remove from the graph
*/
public void removePlotter(final Plotter plotter) {
this.plotters.remove(plotter);
plotters.remove(plotter);
}
/**
@ -623,12 +624,12 @@ public class Metrics {
* @return an unmodifiable {@link java.util.Set} of the plotter objects
*/
public Set<Plotter> getPlotters() {
return Collections.unmodifiableSet(this.plotters);
return Collections.unmodifiableSet(plotters);
}
@Override
public int hashCode() {
return this.name.hashCode();
return name.hashCode();
}
@Override
@ -637,7 +638,7 @@ public class Metrics {
return false;
}
final Graph graph = (Graph) object;
return graph.name.equals(this.name);
return graph.name.equals(name);
}
/**
@ -651,6 +652,7 @@ public class Metrics {
* Interface used to collect custom data for a plugin
*/
public static abstract class Plotter {
/**
* The plot's name
*/
@ -687,7 +689,7 @@ public class Metrics {
* @return the plotted point's column name
*/
public String getColumnName() {
return this.name;
return name;
}
/**
@ -707,7 +709,7 @@ public class Metrics {
return false;
}
final Plotter plotter = (Plotter) object;
return plotter.name.equals(this.name) && (plotter.getValue() == getValue());
return plotter.name.equals(name) && plotter.getValue() == getValue();
}
}
}

View File

@ -8,15 +8,15 @@ import static com.intellectualcrafters.plot.util.ReflectionUtils.getUtilClass;
import static com.intellectualcrafters.plot.util.ReflectionUtils.makeConstructor;
import static com.intellectualcrafters.plot.util.ReflectionUtils.makeMethod;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.UUID;
public class OfflinePlayerUtil {
public static Player loadPlayer(final String name) {
@ -43,10 +43,11 @@ public class OfflinePlayerUtil {
final Object worldServer = getWorldServer();
final Object profile = newGameProfile(id, name);
final Class<?> entityPlayerClass = getNmsClass("EntityPlayer");
final Constructor entityPlayerConstructor = makeConstructor(entityPlayerClass, getNmsClass("MinecraftServer"), getNmsClass("WorldServer"), getUtilClass("com.mojang.authlib.GameProfile"), getNmsClass("PlayerInteractManager"));
final Constructor entityPlayerConstructor = makeConstructor(entityPlayerClass, getNmsClass("MinecraftServer"), getNmsClass("WorldServer"),
getUtilClass("com.mojang.authlib.GameProfile"),
getNmsClass("PlayerInteractManager"));
final Object entityPlayer = callConstructor(entityPlayerConstructor, server, worldServer, profile, interactManager);
final Player player = (Player) getBukkitEntity(entityPlayer);
return player;
return (Player) getBukkitEntity(entityPlayer);
}
private static Object newGameProfile(final UUID id, final String name) {
@ -54,8 +55,7 @@ public class OfflinePlayerUtil {
if (gameProfileClass == null) { //Before uuids
return name;
}
Constructor gameProfileConstructor = null;
gameProfileConstructor = makeConstructor(gameProfileClass, UUID.class, String.class);
Constructor gameProfileConstructor = makeConstructor(gameProfileClass, UUID.class, String.class);
if (gameProfileConstructor == null) { //Verson has string constructor
gameProfileConstructor = makeConstructor(gameProfileClass, String.class, String.class);
return callConstructor(gameProfileConstructor, id.toString(), name);

View File

@ -0,0 +1,138 @@
package com.plotsquared.bukkit.util;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefConstructor;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefField;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.plotsquared.bukkit.object.BukkitPlayer;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.Map.Entry;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
/**
* An utility that can be used to send chunks, rather than using bukkit code to do so (uses heavy NMS)
*
*/
public class SendChunk {
// // Ref Class
private final RefClass classEntityPlayer = getRefClass("{nms}.EntityPlayer");
private final RefClass classMapChunk = getRefClass("{nms}.PacketPlayOutMapChunk");
private final RefClass classPacket = getRefClass("{nms}.Packet");
private final RefClass classConnection = getRefClass("{nms}.PlayerConnection");
private final RefClass classChunk = getRefClass("{nms}.Chunk");
private final RefClass classCraftPlayer = getRefClass("{cb}.entity.CraftPlayer");
private final RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
private final RefMethod methodGetHandlePlayer;
private final RefMethod methodGetHandleChunk;
private final RefConstructor MapChunk;
private final RefField connection;
private final RefMethod send;
private final RefMethod methodInitLighting;
/**
* Constructor
*/
public SendChunk() {
methodGetHandlePlayer = classCraftPlayer.getMethod("getHandle");
methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
methodInitLighting = classChunk.getMethod("initLighting");
MapChunk = classMapChunk.getConstructor(classChunk.getRealClass(), boolean.class, int.class);
connection = classEntityPlayer.getField("playerConnection");
send = classConnection.getMethod("sendPacket", classPacket.getRealClass());
}
public void sendChunk(final Collection<Chunk> input) {
final HashSet<Chunk> chunks = new HashSet<Chunk>(input);
final HashMap<String, ArrayList<Chunk>> map = new HashMap<>();
final int view = Bukkit.getServer().getViewDistance();
for (final Chunk chunk : chunks) {
final String world = chunk.getWorld().getName();
ArrayList<Chunk> list = map.get(world);
if (list == null) {
list = new ArrayList<>();
map.put(world, list);
}
list.add(chunk);
final Object c = methodGetHandleChunk.of(chunk).call();
methodInitLighting.of(c).call();
}
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
PlotPlayer pp = entry.getValue();
final Plot plot = pp.getCurrentPlot();
Location loc = null;
String world;
if (plot != null) {
world = plot.getArea().worldname;
} else {
loc = pp.getLocation();
world = loc.getWorld();
}
final ArrayList<Chunk> list = map.get(world);
if (list == null) {
continue;
}
if (loc == null) {
loc = pp.getLocation();
}
final int cx = loc.getX() >> 4;
final int cz = loc.getZ() >> 4;
final Player player = ((BukkitPlayer) pp).player;
final Object entity = methodGetHandlePlayer.of(player).call();
for (final Chunk chunk : list) {
final int dx = Math.abs(cx - chunk.getX());
final int dz = Math.abs(cz - chunk.getZ());
if ((dx > view) || (dz > view)) {
continue;
}
final Object c = methodGetHandleChunk.of(chunk).call();
chunks.remove(chunk);
final Object con = connection.of(entity).get();
final Object packet = MapChunk.create(c, true, 65535);
send.of(con).call(packet);
}
}
for (final Chunk chunk : chunks) {
TaskManager.runTask(new Runnable() {
@Override
public void run() {
try {
chunk.unload(true, false);
} catch (final Throwable e) {
final String worldname = chunk.getWorld().getName();
PS.debug("$4Could not save chunk: " + worldname + ";" + chunk.getX() + ";" + chunk.getZ());
PS.debug("$3 - $4File may be open in another process (e.g. MCEdit)");
PS.debug("$3 - $4" + worldname + "/level.dat or " + worldname
+ "/level_old.dat may be corrupt (try repairing or removing these)");
}
}
});
}
}
public void sendChunk(final String worldname, final List<ChunkLoc> locs) {
final World myworld = Bukkit.getWorld(worldname);
final ArrayList<Chunk> chunks = new ArrayList<>();
for (final ChunkLoc loc : locs) {
if (myworld.isChunkLoaded(loc.x, loc.z)) {
chunks.add(myworld.getChunkAt(loc.x, loc.z));
}
}
sendChunk(chunks);
}
}

View File

@ -0,0 +1,57 @@
package com.plotsquared.bukkit.util;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.generator.GeneratorWrapper;
import com.intellectualcrafters.plot.util.SetupUtils;
import com.plotsquared.bukkit.generator.BukkitAugmentedGenerator;
import org.bukkit.World;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
public class SetGenCB {
public static void setGenerator(final World world) throws Exception {
SetupUtils.manager.updateGenerators();
PS.get().removePlotAreas(world.getName());
final ChunkGenerator gen = world.getGenerator();
if (gen == null) {
return;
}
final String name = gen.getClass().getCanonicalName();
boolean set = false;
for (final GeneratorWrapper<?> wrapper : SetupUtils.generators.values()) {
ChunkGenerator newGen = (ChunkGenerator) wrapper.getPlatformGenerator();
if (newGen == null) {
newGen = (ChunkGenerator) wrapper;
}
if (newGen.getClass().getCanonicalName().equals(name)) {
// set generator
final Field generator = world.getClass().getDeclaredField("generator");
final Field populators = world.getClass().getDeclaredField("populators");
generator.setAccessible(true);
populators.setAccessible(true);
// Set populators (just in case)
populators.set(world, new ArrayList<>());
// Set generator
generator.set(world, newGen);
populators.set(world, newGen.getDefaultPopulators(world));
// end
set = true;
break;
}
}
if (!set) {
final Iterator<BlockPopulator> iter = world.getPopulators().iterator();
while (iter.hasNext()) {
if (iter.next() instanceof BukkitAugmentedGenerator) {
iter.remove();
}
}
}
PS.get().loadWorld(world.getName(), PS.get().IMP.getGenerator(world.getName(), null));
}
}

View File

@ -0,0 +1,246 @@
package com.plotsquared.bukkit.util.block;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import com.plotsquared.bukkit.util.BukkitUtil;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import java.util.Arrays;
public class FastChunk_1_8_3 extends PlotChunk<Chunk> {
public char[][] ids;
public short[] count;
public short[] air;
public short[] relight;
public int[][] biomes;
public Chunk chunk;
public FastChunk_1_8_3(final ChunkWrapper chunk) {
super(chunk);
ids = new char[16][];
count = new short[16];
air = new short[16];
relight = new short[16];
}
@Override
public Chunk getChunkAbs() {
ChunkWrapper loc = getChunkWrapper();
return BukkitUtil.getWorld(loc.world).getChunkAt(loc.x, loc.z);
}
@Override
public Chunk getChunk() {
if (chunk == null) {
final ChunkWrapper cl = getChunkWrapper();
chunk = Bukkit.getWorld(cl.world).getChunkAt(cl.x, cl.z);
}
return chunk;
}
@Override
public void setChunkWrapper(final ChunkWrapper loc) {
super.setChunkWrapper(loc);
chunk = null;
}
/**
* Get the number of block changes in a specified section
* @param i
* @return
*/
public int getCount(final int i) {
return count[i];
}
public int getAir(final int i) {
return air[i];
}
public void setCount(int i, short value) {
count[i] = value;
}
/**
* Get the number of block changes in a specified section
* @param i
* @return
*/
public int getRelight(final int i) {
return relight[i];
}
public int getTotalCount() {
int total = 0;
for (int i = 0; i < 16; i++) {
total += count[i];
}
return total;
}
public int getTotalRelight() {
if (getTotalCount() == 0) {
Arrays.fill(count, (short) 1);
Arrays.fill(relight, Short.MAX_VALUE);
return Short.MAX_VALUE;
}
int total = 0;
for (int i = 0; i < 16; i++) {
total += relight[i];
}
return total;
}
/**
* Get the raw data for a section
* @param i
* @return
*/
public char[] getIdArray(final int i) {
return ids[i];
}
@Override
public void setBlock(final int x, final int y, final int z, final int id, byte data) {
final int i = MainUtil.CACHE_I[y][x][z];
final int j = MainUtil.CACHE_J[y][x][z];
char[] vs = ids[i];
if (vs == null) {
vs = ids[i] = new char[4096];
count[i]++;
} else if (vs[j] == 0) {
count[i]++;
}
switch (id) {
case 0:
air[i]++;
vs[j] = (char) 1;
return;
case 10:
case 11:
case 39:
case 40:
case 51:
case 74:
case 89:
case 122:
case 124:
case 138:
case 169:
relight[i]++;
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 30:
case 32:
case 37:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
case 55:
case 56:
case 57:
case 58:
case 60:
case 7:
case 8:
case 9:
case 73:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 121:
case 129:
case 133:
case 165:
case 166:
case 170:
case 172:
case 173:
case 174:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192:
vs[j] = (char) (id << 4);
return;
case 130:
case 76:
case 62:
relight[i]++;
case 54:
case 146:
case 61:
case 65:
case 68:
case 50:
if (data < 2) {
data = 2;
}
default:
vs[j] = (char) ((id << 4) + data);
return;
}
}
@Override
public PlotChunk clone() {
FastChunk_1_8_3 toReturn = new FastChunk_1_8_3(getChunkWrapper());
toReturn.air = air.clone();
toReturn.count = count.clone();
toReturn.relight = relight.clone();
toReturn.ids = new char[ids.length][];
for (int i = 0; i < ids.length; i++) {
char[] matrix = ids[i];
if (matrix != null) {
toReturn.ids[i] = new char[matrix.length];
System.arraycopy(matrix, 0, toReturn.ids[i], 0, matrix.length);
}
}
return toReturn;
}
@Override
public PlotChunk shallowClone() {
FastChunk_1_8_3 toReturn = new FastChunk_1_8_3(getChunkWrapper());
toReturn.air = air;
toReturn.count = count;
toReturn.relight = relight;
toReturn.ids = ids;
return toReturn;
}
@Override
public void setBiome(int x, int z, int biome) {
if (biomes == null) {
biomes = new int[16][16];
}
biomes[x][z] = biome;
}
}

View File

@ -0,0 +1,35 @@
package com.plotsquared.bukkit.util.block;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.SetQueue;
import com.plotsquared.bukkit.util.BukkitUtil;
import org.bukkit.Chunk;
public class FastChunk_1_9 extends PlotChunk<Chunk> {
public FastChunk_1_9(SetQueue.ChunkWrapper wrap) {
super(wrap);
}
@Override
public Chunk getChunkAbs() {
SetQueue.ChunkWrapper loc = getChunkWrapper();
return BukkitUtil.getWorld(loc.world).getChunkAt(loc.x, loc.z);
}
@Override public void setBlock(int x, int y, int z, int id, byte data) {
}
@Override public void setBiome(int x, int z, int biome) {
}
@Override public PlotChunk clone() {
return null;
}
@Override public PlotChunk shallowClone() {
return null;
}
}

View File

@ -0,0 +1,181 @@
package com.plotsquared.bukkit.util.block;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.SendChunk;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Biome;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
public class FastQueue_1_7 extends SlowQueue {
public final RefClass classBlock = getRefClass("{nms}.Block");
public final RefClass classChunk = getRefClass("{nms}.Chunk");
public final RefClass classWorld = getRefClass("{nms}.World");
public final RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
public final RefMethod methodGetHandle;
public final RefMethod methodGetChunkAt;
public final RefMethod methodA;
public final RefMethod methodGetById;
public final RefMethod methodInitLighting;
public final SendChunk chunksender;
public HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
public FastQueue_1_7() throws NoSuchMethodException, RuntimeException {
methodGetHandle = classCraftWorld.getMethod("getHandle");
methodGetChunkAt = classWorld.getMethod("getChunkAt", int.class, int.class);
methodA = classChunk.getMethod("a", int.class, int.class, int.class, classBlock, int.class);
methodGetById = classBlock.getMethod("getById", int.class);
methodInitLighting = classChunk.getMethod("initLighting");
chunksender = new SendChunk();
TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (toUpdate.isEmpty()) {
return;
}
int count = 0;
final ArrayList<Chunk> chunks = new ArrayList<>();
final Iterator<Entry<ChunkWrapper, Chunk>> i = toUpdate.entrySet().iterator();
while (i.hasNext() && (count < 128)) {
chunks.add(i.next().getValue());
i.remove();
count++;
}
if (count == 0) {
return;
}
update(chunks);
}
}, 1);
MainUtil.initCache();
}
public void update(final Collection<Chunk> chunks) {
if (chunks.isEmpty()) {
return;
}
if (!MainUtil.canSendChunk) {
for (final Chunk chunk : chunks) {
chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
chunk.unload(true, false);
chunk.load();
}
return;
}
try {
chunksender.sendChunk(chunks);
} catch (final Throwable e) {
e.printStackTrace();
MainUtil.canSendChunk = false;
}
}
/**
* This should be overridden by any specialized queues
* @param pc
*/
@Override
public void execute(PlotChunk<Chunk> pc) {
SlowChunk sc = (SlowChunk) pc;
Chunk chunk = pc.getChunk();
ChunkWrapper wrapper = pc.getChunkWrapper();
if (!toUpdate.containsKey(wrapper)) {
toUpdate.put(wrapper, chunk);
}
chunk.load(true);
World world = chunk.getWorld();
final Object w = methodGetHandle.of(world).call();
final Object c = methodGetChunkAt.of(w).call(wrapper.x, wrapper.z);
for (int i = 0; i < sc.result.length; i++) {
PlotBlock[] result2 = sc.result[i];
if (result2 == null) {
continue;
}
for (int j = 0; j < 4096; j++) {
final int x = MainUtil.x_loc[i][j];
final int y = MainUtil.y_loc[i][j];
final int z = MainUtil.z_loc[i][j];
PlotBlock newBlock = result2[j];
if (newBlock.id == -1) {
chunk.getBlock(x, y, z).setData(newBlock.data, false);
continue;
}
final Object block = methodGetById.call(newBlock.id);
methodA.of(c).call(x, y, z, block, newBlock.data);
}
}
int[][] biomes = sc.biomes;
Biome[] values = Biome.values();
if (biomes != null) {
for (int x = 0; x < 16; x++) {
int[] array = biomes[x];
if (array == null) {
continue;
}
for (int z = 0; z < 16; z++) {
int biome = array[z];
if (biome == 0) {
continue;
}
chunk.getBlock(x, 0, z).setBiome(values[biome]);
}
}
}
}
/**
* This should be overridden by any specialized queues
* @param wrap
*/
@Override
public PlotChunk<Chunk> getChunk(ChunkWrapper wrap) {
return new SlowChunk(wrap);
}
/**
* This should be overriden by any specialized queues
* @param chunk
* @param fixAll
*/
@Override
public boolean fixLighting(PlotChunk<Chunk> chunk, boolean fixAll) {
Object c = methodGetHandle.of(chunk.getChunk()).call();
methodInitLighting.of(c).call();
return true;
}
/**
* This should be overridden by any specialized queues
* @param world
* @param locs
*/
@Override
public void sendChunk(String world, Collection<ChunkLoc> locs) {
World worldObj = BukkitUtil.getWorld(world);
for (ChunkLoc loc : locs) {
ChunkWrapper wrapper = SetQueue.IMP.new ChunkWrapper(world, loc.x, loc.z);
if (!toUpdate.containsKey(wrapper)) {
toUpdate.put(wrapper, worldObj.getChunkAt(loc.x, loc.z));
}
}
}
}

View File

@ -0,0 +1,384 @@
package com.plotsquared.bukkit.util.block;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefConstructor;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.SendChunk;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
public class FastQueue_1_8 extends SlowQueue {
public final RefMethod methodInitLighting;
private final RefClass classBlock = getRefClass("{nms}.Block");
private final RefClass classBlockPosition = getRefClass("{nms}.BlockPosition");
private final RefClass classIBlockData = getRefClass("{nms}.IBlockData");
private final RefClass classChunk = getRefClass("{nms}.Chunk");
private final RefClass classWorld = getRefClass("{nms}.World");
private final RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
public HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
private RefMethod methodGetHandle;
private RefMethod methodGetChunkAt;
private RefMethod methodA;
private RefMethod methodGetByCombinedId;
private RefConstructor constructorBlockPosition;
private SendChunk chunksender;
public FastQueue_1_8() throws NoSuchMethodException, RuntimeException {
methodInitLighting = classChunk.getMethod("initLighting");
constructorBlockPosition = classBlockPosition.getConstructor(int.class, int.class, int.class);
methodGetByCombinedId = classBlock.getMethod("getByCombinedId", int.class);
methodGetHandle = classCraftWorld.getMethod("getHandle");
methodGetChunkAt = classWorld.getMethod("getChunkAt", int.class, int.class);
methodA = classChunk.getMethod("a", classBlockPosition, classIBlockData);
chunksender = new SendChunk();
TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (toUpdate.isEmpty()) {
return;
}
int count = 0;
final ArrayList<Chunk> chunks = new ArrayList<Chunk>();
final Iterator<Entry<ChunkWrapper, Chunk>> i = toUpdate.entrySet().iterator();
while (i.hasNext() && (count < 128)) {
chunks.add(i.next().getValue());
i.remove();
count++;
}
if (count == 0) {
return;
}
update(chunks);
}
}, 1);
MainUtil.initCache();
}
public void update(final Collection<Chunk> chunks) {
if (chunks.isEmpty()) {
return;
}
if (!MainUtil.canSendChunk) {
for (final Chunk chunk : chunks) {
chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
chunk.unload(true, false);
chunk.load();
}
return;
}
try {
chunksender.sendChunk(chunks);
} catch (final Throwable e) {
e.printStackTrace();
MainUtil.canSendChunk = false;
}
}
/**
* This should be overriden by any specialized queues
* @param pc
*/
@Override
public void execute(PlotChunk<Chunk> pc) {
SlowChunk sc = (SlowChunk) pc;
Chunk chunk = pc.getChunk();
ChunkWrapper wrapper = pc.getChunkWrapper();
if (!toUpdate.containsKey(wrapper)) {
toUpdate.put(wrapper, chunk);
}
chunk.load(true);
World world = chunk.getWorld();
final Object w = methodGetHandle.of(world).call();
final Object c = methodGetChunkAt.of(w).call(wrapper.x, wrapper.z);
for (int i = 0; i < sc.result.length; i++) {
PlotBlock[] result2 = sc.result[i];
if (result2 == null) {
continue;
}
for (int j = 0; j < 4096; j++) {
final int x = MainUtil.x_loc[i][j];
final int y = MainUtil.y_loc[i][j];
final int z = MainUtil.z_loc[i][j];
PlotBlock newBlock = result2[j];
if (newBlock.id == -1) {
chunk.getBlock(x, y, z).setData(newBlock.data, false);
continue;
}
// Start blockstate workaround //
switch (newBlock.id) {
case 54:
case 130:
case 142:
case 132:
case 27:
case 137:
case 52:
case 154:
case 84:
case 25:
case 144:
case 138:
case 176:
case 177:
case 119:
case 63:
case 68:
case 323:
case 117:
case 116:
case 28:
case 66:
case 157:
case 61:
case 62:
case 140:
case 146:
case 149:
case 150:
case 158:
case 23:
case 123:
case 124:
case 29:
case 33:
case 151:
case 178: {
final Block block = world.getBlockAt(x, y, z);
if (block.getData() == newBlock.data) {
if (block.getTypeId() != newBlock.id) {
block.setTypeId(newBlock.id, false);
}
} else {
if (block.getTypeId() == newBlock.id) {
block.setData(newBlock.data, false);
} else {
block.setTypeIdAndData(newBlock.id, newBlock.data, false);
}
}
continue;
}
}
// Start data value shortcut
final Block block = world.getBlockAt(x, y, z);
final int currentId = block.getTypeId();
if (currentId == newBlock.id) {
switch (newBlock.id) {
case 0:
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 25:
case 30:
case 32:
case 37:
case 39:
case 40:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
case 51:
case 52:
case 54:
case 55:
case 56:
case 57:
case 58:
case 60:
case 61:
case 62:
case 7:
case 8:
case 9:
case 10:
case 11:
case 73:
case 74:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 84:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 117:
case 121:
case 122:
case 123:
case 124:
case 129:
case 133:
case 138:
case 137:
case 140:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 176:
case 177:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192: {
continue;
}
}
if (block.getData() == newBlock.data) {
return;
}
block.setData(newBlock.data, false);
return;
}
// blockstate
switch (currentId) {
case 54:
case 130:
case 132:
case 142:
case 27:
case 137:
case 52:
case 154:
case 84:
case 25:
case 144:
case 138:
case 176:
case 177:
case 63:
case 68:
case 323:
case 117:
case 119:
case 116:
case 28:
case 66:
case 157:
case 61:
case 62:
case 140:
case 146:
case 149:
case 150:
case 158:
case 23:
case 123:
case 124:
case 29:
case 33:
case 151:
case 178: {
if (block.getData() == newBlock.data) {
block.setTypeId(newBlock.id, false);
} else {
block.setTypeIdAndData(newBlock.id, newBlock.data, false);
}
continue;
}
}
// End blockstate workaround //
// check sign
final Object pos = constructorBlockPosition.create(x, y, z);
final Object combined = methodGetByCombinedId.call(newBlock.id + (newBlock.data << 12));
methodA.of(chunk).call(pos, combined);
}
}
int[][] biomes = sc.biomes;
Biome[] values = Biome.values();
if (biomes != null) {
for (int x = 0; x < 16; x++) {
int[] array = biomes[x];
if (array == null) {
continue;
}
for (int z = 0; z < 16; z++) {
int biome = array[z];
if (biome == 0) {
continue;
}
chunk.getBlock(x, 0, z).setBiome(values[biome]);
}
}
}
}
/**
* This should be overridden by any specialized queues
* @param wrap
*/
@Override
public PlotChunk<Chunk> getChunk(ChunkWrapper wrap) {
return new SlowChunk(wrap);
}
/**
* This should be overridden by any specialized queues
* @param fixAll
*/
@Override
public boolean fixLighting(PlotChunk<Chunk> chunk, boolean fixAll) {
Object c = methodGetHandle.of(chunk.getChunk()).call();
methodInitLighting.of(c).call();
return true;
}
/**
* This should be overridden by any specialized queues
* @param locs
*/
@Override
public void sendChunk(String world, Collection<ChunkLoc> locs) {
World worldObj = BukkitUtil.getWorld(world);
for (ChunkLoc loc : locs) {
ChunkWrapper wrapper = SetQueue.IMP.new ChunkWrapper(world, loc.x, loc.z);
if (!toUpdate.containsKey(wrapper)) {
toUpdate.put(wrapper, worldObj.getChunkAt(loc.x, loc.z));
}
}
}
}

View File

@ -0,0 +1,415 @@
package com.plotsquared.bukkit.util.block;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.PseudoRandom;
import com.intellectualcrafters.plot.util.ChunkManager;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefConstructor;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefField;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod.RefExecutor;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.SendChunk;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
public class FastQueue_1_8_3 extends SlowQueue {
public final SendChunk chunksender;
private final RefClass classEntityPlayer = getRefClass("{nms}.EntityPlayer");
private final RefClass classMapChunk = getRefClass("{nms}.PacketPlayOutMapChunk");
private final RefClass classPacket = getRefClass("{nms}.Packet");
private final RefClass classConnection = getRefClass("{nms}.PlayerConnection");
private final RefClass classChunk = getRefClass("{nms}.Chunk");
private final RefClass classCraftPlayer = getRefClass("{cb}.entity.CraftPlayer");
private final RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
private final RefClass classWorld = getRefClass("{nms}.World");
private final RefField mustSave = classChunk.getField("mustSave");
private final RefClass classBlockPosition = getRefClass("{nms}.BlockPosition");
private final RefClass classChunkSection = getRefClass("{nms}.ChunkSection");
public HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
private RefMethod methodGetHandleChunk;
private RefConstructor MapChunk;
private RefMethod methodInitLighting;
private RefConstructor classBlockPositionConstructor;
private RefConstructor classChunkSectionConstructor;
private RefMethod methodX;
private RefMethod methodAreNeighborsLoaded;
private RefField fieldSections;
private RefField fieldWorld;
private RefMethod methodGetIdArray;
public FastQueue_1_8_3() throws NoSuchMethodException, RuntimeException {
methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
methodInitLighting = classChunk.getMethod("initLighting");
MapChunk = classMapChunk.getConstructor(classChunk.getRealClass(), boolean.class, int.class);
classBlockPositionConstructor = classBlockPosition.getConstructor(int.class, int.class, int.class);
methodX = classWorld.getMethod("x", classBlockPosition.getRealClass());
fieldSections = classChunk.getField("sections");
fieldWorld = classChunk.getField("world");
methodGetIdArray = classChunkSection.getMethod("getIdArray");
methodAreNeighborsLoaded = classChunk.getMethod("areNeighborsLoaded", int.class);
classChunkSectionConstructor = classChunkSection.getConstructor(int.class, boolean.class, char[].class);
chunksender = new SendChunk();
TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
if (toUpdate.isEmpty()) {
return;
}
int count = 0;
final ArrayList<Chunk> chunks = new ArrayList<Chunk>();
final Iterator<Entry<ChunkWrapper, Chunk>> i = toUpdate.entrySet().iterator();
while (i.hasNext() && (count < 128)) {
chunks.add(i.next().getValue());
i.remove();
count++;
}
if (count == 0) {
return;
}
update(chunks);
}
}, 1);
MainUtil.initCache();
}
public void update(final Collection<Chunk> chunks) {
if (chunks.isEmpty()) {
return;
}
if (!MainUtil.canSendChunk) {
for (final Chunk chunk : chunks) {
chunk.getWorld().refreshChunk(chunk.getX(), chunk.getZ());
chunk.unload(true, false);
chunk.load();
}
return;
}
try {
chunksender.sendChunk(chunks);
} catch (final Throwable e) {
e.printStackTrace();
MainUtil.canSendChunk = false;
}
}
/**
* This should be overridden by any specialized queues
* @param pc
*/
@Override
public void execute(PlotChunk<Chunk> pc) {
FastChunk_1_8_3 fs = (FastChunk_1_8_3) pc;
Chunk chunk = pc.getChunk();
final World world = chunk.getWorld();
ChunkWrapper wrapper = pc.getChunkWrapper();
if (!toUpdate.containsKey(wrapper)) {
toUpdate.put(wrapper, chunk);
}
chunk.load(true);
try {
final boolean flag = world.getEnvironment() == Environment.NORMAL;
// Sections
final Method getHandele = chunk.getClass().getDeclaredMethod("getHandle");
final Object c = getHandele.invoke(chunk);
final Class<? extends Object> clazz = c.getClass();
final Field sf = clazz.getDeclaredField("sections");
sf.setAccessible(true);
final Field tf = clazz.getDeclaredField("tileEntities");
final Field ef = clazz.getDeclaredField("entitySlices");
final Object[] sections = (Object[]) sf.get(c);
final HashMap<?, ?> tiles = (HashMap<?, ?>) tf.get(c);
final List<?>[] entities = (List<?>[]) ef.get(c);
Method xm = null;
Method ym = null;
Method zm = null;
// Trim tiles
final Set<Entry<?, ?>> entryset = (Set<Entry<?, ?>>) (Set<?>) tiles.entrySet();
final Iterator<Entry<?, ?>> iter = entryset.iterator();
while (iter.hasNext()) {
final Entry<?, ?> tile = iter.next();
final Object pos = tile.getKey();
if (xm == null) {
final Class<? extends Object> clazz2 = pos.getClass().getSuperclass();
xm = clazz2.getDeclaredMethod("getX");
ym = clazz2.getDeclaredMethod("getY");
zm = clazz2.getDeclaredMethod("getZ");
}
final int lx = (int) xm.invoke(pos) & 15;
final int ly = (int) ym.invoke(pos);
final int lz = (int) zm.invoke(pos) & 15;
final int j = MainUtil.CACHE_I[ly][lx][lz];
final int k = MainUtil.CACHE_J[ly][lx][lz];
final char[] array = fs.getIdArray(j);
if (array == null) {
continue;
}
if (array[k] != 0) {
iter.remove();
}
}
// Trim entities
for (int i = 0; i < 16; i++) {
if ((entities[i] != null) && (fs.getCount(i) >= 4096)) {
entities[i].clear();
}
}
// Efficiently merge sections
for (int j = 0; j < sections.length; j++) {
if (fs.getCount(j) == 0) {
continue;
}
final char[] newArray = fs.getIdArray(j);
if (newArray == null) {
continue;
}
Object section = sections[j];
if ((section == null) || (fs.getCount(j) >= 4096)) {
section = sections[j] = newChunkSection(j << 4, flag, newArray);
continue;
}
final char[] currentArray = getIdArray(section);
boolean fill = true;
for (int k = 0; k < newArray.length; k++) {
final char n = newArray[k];
switch (n) {
case 0:
fill = false;
continue;
case 1:
fill = false;
currentArray[k] = 0;
continue;
default:
currentArray[k] = n;
continue;
}
}
if (fill) {
fs.setCount(j, Short.MAX_VALUE);
}
}
// Clear
} catch (IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException | InvocationTargetException |
NoSuchFieldException e) {
e.printStackTrace();
}
int[][] biomes = fs.biomes;
Biome[] values = Biome.values();
if (biomes != null) {
for (int x = 0; x < 16; x++) {
int[] array = biomes[x];
if (array == null) {
continue;
}
for (int z = 0; z < 16; z++) {
int biome = array[z];
if (biome == 0) {
continue;
}
chunk.getBlock(x, 0, z).setBiome(values[biome]);
}
}
}
}
public Object newChunkSection(final int i, final boolean flag, final char[] ids) {
return classChunkSectionConstructor.create(i, flag, ids);
}
public char[] getIdArray(final Object obj) {
return (char[]) methodGetIdArray.of(obj).call();
}
/**
* This should be overridden by any specialized queues
* @param wrap
*/
@Override
public PlotChunk<Chunk> getChunk(ChunkWrapper wrap) {
return new FastChunk_1_8_3(wrap);
}
/**
* This should be overridden by any specialized queues
* @param pc
*/
@Override
public boolean fixLighting(PlotChunk<Chunk> pc, boolean fixAll) {
try {
FastChunk_1_8_3 bc = (FastChunk_1_8_3) pc;
final Chunk chunk = bc.getChunk();
if (!chunk.isLoaded()) {
chunk.load(false);
} else {
chunk.unload(true, false);
chunk.load(false);
}
// Initialize lighting
final Object c = methodGetHandleChunk.of(chunk).call();
if (fixAll && !(boolean) methodAreNeighborsLoaded.of(c).call(1)) {
World world = chunk.getWorld();
ChunkWrapper wrapper = bc.getChunkWrapper();
String worldname = wrapper.world;
for (int x = wrapper.x - 1; x <= wrapper.x + 1; x++) {
for (int z = wrapper.z - 1; z <= wrapper.z + 1; z++) {
if (x != 0 && z != 0) {
Chunk other = world.getChunkAt(x, z);
while (!other.isLoaded()) {
other.load(true);
}
ChunkManager.manager.loadChunk(worldname, new ChunkLoc(x, z), true);
}
}
}
if (!(boolean) methodAreNeighborsLoaded.of(c).call(1)) {
return false;
}
}
methodInitLighting.of(c).call();
if ((bc.getTotalRelight() == 0 && !fixAll)) {
return true;
}
final Object[] sections = (Object[]) fieldSections.of(c).get();
final Object w = fieldWorld.of(c).get();
final int X = chunk.getX() << 4;
final int Z = chunk.getZ() << 4;
RefExecutor relight = methodX.of(w);
for (int j = 0; j < sections.length; j++) {
final Object section = sections[j];
if (section == null) {
continue;
}
if ((bc.getRelight(j) == 0 && !fixAll) || bc.getCount(j) == 0 || (bc.getCount(j) >= 4096 && bc.getAir(j) == 0)) {
continue;
}
final char[] array = getIdArray(section);
int l = PseudoRandom.random.random(2);
for (int k = 0; k < array.length; k++) {
final int i = array[k];
if (i < 16) {
continue;
}
final short id = (short) (i >> 4);
switch (id) { // Lighting
default:
if (!fixAll) {
continue;
}
if ((k & 1) == l) {
l = 1 - l;
continue;
}
case 10:
case 11:
case 39:
case 40:
case 50:
case 51:
case 62:
case 74:
case 76:
case 89:
case 122:
case 124:
case 130:
case 138:
case 169:
final int x = MainUtil.x_loc[j][k];
final int y = MainUtil.y_loc[j][k];
final int z = MainUtil.z_loc[j][k];
if (isSurrounded(sections, x, y, z)) {
continue;
}
final Object pos = classBlockPositionConstructor.create(X + x, y, Z + z);
relight.call(pos);
}
}
}
return true;
} catch (final Throwable e) {
e.printStackTrace();
}
return false;
}
public boolean isSurrounded(Object[] sections, int x, int y, int z) {
return isSolid(getId(sections, x, y + 1, z))
&& isSolid(getId(sections, x + 1, y - 1, z))
&& isSolid(getId(sections, x - 1, y, z))
&& isSolid(getId(sections, x, y, z + 1))
&& isSolid(getId(sections, x, y, z - 1));
}
public boolean isSolid(int i) {
return i != 0 && Material.getMaterial(i).isOccluding();
}
public int getId(Object[] sections, int x, int y, int z) {
if (x < 0 || x > 15 || z < 0 || z > 15) {
return 1;
}
if (y < 0 || y > 255) {
return 1;
}
int i = MainUtil.CACHE_I[y][x][z];
Object section = sections[i];
if (section == null) {
return 0;
}
char[] array = getIdArray(section);
int j = MainUtil.CACHE_J[y][x][z];
return array[j] >> 4;
}
/**
* This should be overridden by any specialized queues
* @param world
* @param locs
*/
@Override
public void sendChunk(String world, Collection<ChunkLoc> locs) {
World worldObj = BukkitUtil.getWorld(world);
for (ChunkLoc loc : locs) {
ChunkWrapper wrapper = SetQueue.IMP.new ChunkWrapper(world, loc.x, loc.z);
if (!toUpdate.containsKey(wrapper)) {
toUpdate.put(wrapper, worldObj.getChunkAt(loc.x, loc.z));
}
}
}
}

View File

@ -0,0 +1,12 @@
package com.plotsquared.bukkit.util.block;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.SetQueue;
import org.bukkit.Chunk;
public class FastQueue_1_9 extends SlowQueue {
@Override public PlotChunk<Chunk> getChunk(SetQueue.ChunkWrapper wrap) {
return new FastChunk_1_9(wrap);
}
}

View File

@ -0,0 +1,110 @@
package com.plotsquared.bukkit.util.block;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import com.plotsquared.bukkit.util.BukkitUtil;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.bukkit.generator.ChunkGenerator.ChunkData;
public class GenChunk extends PlotChunk<Chunk> {
public final Biome[] biomes;
public Chunk chunk;
public short[][] result;
public byte[][] result_data;
public ChunkData cd;
public boolean modified = false;
public BiomeGrid grid;
public GenChunk(Chunk chunk, ChunkWrapper wrap) {
super(wrap);
if ((this.chunk = chunk) == null && wrap != null) {
World world = BukkitUtil.getWorld(wrap.world);
if (world != null) {
chunk = world.getChunkAt(wrap.x, wrap.z);
}
}
this.biomes = Biome.values();
}
@Override
public Chunk getChunkAbs() {
ChunkWrapper wrap = getChunkWrapper();
if (chunk == null || wrap.x != chunk.getX() || wrap.z != chunk.getZ()) {
chunk = BukkitUtil.getWorld(wrap.world).getChunkAt(wrap.x, wrap.z);
}
return chunk;
}
@Override
public void setBiome(int x, int z, int biome) {
modified = true;
grid.setBiome(x, z, biomes[biome]);
}
public void setBiome(int x, int z, Biome biome) {
if (grid != null) {
grid.setBiome(x, z, biome);
}
}
@Override
public void setBlock(int x, int y, int z, int id, byte data) {
if (result == null) {
modified = true;
cd.setBlock(x, y, z, id, data);
return;
}
int i = MainUtil.CACHE_I[y][x][z];
short[] v = result[i];
if (v == null) {
modified = true;
result[i] = v = new short[4096];
}
int j = MainUtil.CACHE_J[y][x][z];
v[j] = (short) id;
if (data != 0) {
byte[] vd = result_data[i];
if (vd == null) {
result_data[i] = vd = new byte[4096];
}
vd[j] = data;
}
}
@Override
public PlotChunk clone() {
GenChunk toReturn = new GenChunk(getChunkAbs(), getChunkWrapper());
if (result != null) {
for (int i = 0; i < result.length; i++) {
short[] matrix = result[i];
if (matrix != null) {
toReturn.result[i] = new short[matrix.length];
System.arraycopy(matrix, 0, toReturn.result[i], 0, matrix.length);
}
}
for (int i = 0; i < result_data.length; i++) {
byte[] matrix = result_data[i];
if (matrix != null) {
toReturn.result_data[i] = new byte[matrix.length];
System.arraycopy(matrix, 0, toReturn.result_data[i], 0, matrix.length);
}
}
}
toReturn.cd = cd;
return toReturn;
}
@Override
public PlotChunk shallowClone() {
GenChunk toReturn = new GenChunk(getChunkAbs(), getChunkWrapper());
toReturn.result = result;
toReturn.result_data = result_data;
toReturn.cd = cd;
return toReturn;
}
}

View File

@ -0,0 +1,59 @@
package com.plotsquared.bukkit.util.block;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import com.plotsquared.bukkit.util.BukkitUtil;
import org.bukkit.Chunk;
public class SlowChunk extends PlotChunk<Chunk> {
public PlotBlock[][] result = new PlotBlock[16][];
public int[][] biomes;
public SlowChunk(ChunkWrapper chunk) {
super(chunk);
}
@Override
public Chunk getChunkAbs() {
ChunkWrapper loc = getChunkWrapper();
return BukkitUtil.getWorld(loc.world).getChunkAt(loc.x, loc.z);
}
@Override
public void setBiome(int x, int z, int biome) {
if (biomes == null) {
biomes = new int[16][16];
}
biomes[x][z] = biome;
}
@Override
public void setBlock(int x, int y, int z, int id, byte data) {
if (result[y >> 4] == null) {
result[y >> 4] = new PlotBlock[4096];
}
result[MainUtil.CACHE_I[y][x][z]][MainUtil.CACHE_J[y][x][z]] = new PlotBlock((short) id, data);
}
@Override
public PlotChunk clone() {
SlowChunk toReturn = new SlowChunk(getChunkWrapper());
for (int i = 0; i < result.length; i++) {
PlotBlock[] matrix = result[i];
if (matrix != null) {
toReturn.result[i] = new PlotBlock[matrix.length];
System.arraycopy(matrix, 0, toReturn.result[i], 0, matrix.length);
}
}
return toReturn;
}
@Override
public PlotChunk shallowClone() {
SlowChunk toReturn = new SlowChunk(getChunkWrapper());
toReturn.result = result;
return toReturn;
}
}

View File

@ -0,0 +1,281 @@
package com.plotsquared.bukkit.util.block;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.PlotBlock;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.PlotChunk;
import com.intellectualcrafters.plot.util.PlotQueue;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
import org.bukkit.Chunk;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public class SlowQueue implements PlotQueue<Chunk> {
private final ConcurrentHashMap<ChunkWrapper, PlotChunk<Chunk>> blocks = new ConcurrentHashMap<>();
public SlowQueue() {
MainUtil.initCache();
}
@Override
public boolean setBlock(String world, int x, int y, int z, short id, byte data) {
if (y > 255 || y < 0) {
return false;
}
final ChunkWrapper wrap = SetQueue.IMP.new ChunkWrapper(world, x >> 4, z >> 4);
x = x & 15;
z = z & 15;
PlotChunk<Chunk> result = blocks.get(wrap);
if (result == null) {
result = getChunk(wrap);
result.setBlock(x, y, z, id, data);
final PlotChunk<Chunk> previous = blocks.put(wrap, result);
if (previous == null) {
return true;
}
blocks.put(wrap, previous);
result = previous;
}
result.setBlock(x, y, z, id, data);
return true;
}
@Override
public void setChunk(PlotChunk<Chunk> chunk) {
blocks.put(chunk.getChunkWrapper(), chunk);
}
@Override
public PlotChunk<Chunk> next() {
if (!PS.get().isMainThread(Thread.currentThread())) {
throw new IllegalStateException("Must be called from main thread!");
}
try {
if (blocks.isEmpty()) {
return null;
}
final Iterator<Entry<ChunkWrapper, PlotChunk<Chunk>>> iter = blocks.entrySet().iterator();
final PlotChunk<Chunk> toReturn = iter.next().getValue();
if (SetQueue.IMP.isWaiting()) {
return null;
}
iter.remove();
execute(toReturn);
fixLighting(toReturn, true);
return toReturn;
} catch (final Throwable e) {
e.printStackTrace();
return null;
}
}
@Override
public PlotChunk<Chunk> next(ChunkWrapper wrap, boolean fixLighting) {
if (!PS.get().isMainThread(Thread.currentThread())) {
throw new IllegalStateException("Must be called from main thread!");
}
try {
if (blocks.isEmpty()) {
return null;
}
final PlotChunk<Chunk> toReturn = blocks.remove(wrap);
if (toReturn == null) {
return null;
}
execute(toReturn);
fixLighting(toReturn, fixLighting);
return toReturn;
} catch (final Throwable e) {
e.printStackTrace();
return null;
}
}
@Override
public void clear() {
blocks.clear();
}
/**
* This should be overriden by any specialized queues
* @param pc
*/
public void execute(PlotChunk<Chunk> pc) {
SlowChunk sc = (SlowChunk) pc;
Chunk chunk = pc.getChunk();
chunk.load(true);
for (int i = 0; i < sc.result.length; i++) {
PlotBlock[] result2 = sc.result[i];
if (result2 == null) {
continue;
}
for (int j = 0; j < 4096; j++) {
final int x = MainUtil.x_loc[i][j];
final int y = MainUtil.y_loc[i][j];
final int z = MainUtil.z_loc[i][j];
Block block = chunk.getBlock(x, y, z);
PlotBlock newBlock = result2[j];
if (newBlock == null) {
continue;
}
switch (newBlock.id) {
case -1:
if (block.getData() == newBlock.data) {
continue;
}
block.setData(newBlock.data);
continue;
case 0:
case 2:
case 4:
case 13:
case 14:
case 15:
case 20:
case 21:
case 22:
case 25:
case 30:
case 32:
case 37:
case 39:
case 40:
case 41:
case 42:
case 45:
case 46:
case 47:
case 48:
case 49:
case 51:
case 52:
case 54:
case 55:
case 56:
case 57:
case 58:
case 60:
case 61:
case 62:
case 7:
case 8:
case 9:
case 10:
case 11:
case 73:
case 74:
case 78:
case 79:
case 80:
case 81:
case 82:
case 83:
case 84:
case 85:
case 87:
case 88:
case 101:
case 102:
case 103:
case 110:
case 112:
case 113:
case 117:
case 121:
case 122:
case 123:
case 124:
case 129:
case 133:
case 138:
case 137:
case 140:
case 165:
case 166:
case 169:
case 170:
case 172:
case 173:
case 174:
case 176:
case 177:
case 181:
case 182:
case 188:
case 189:
case 190:
case 191:
case 192:
if (block.getTypeId() == newBlock.id) {
continue;
}
block.setTypeId(newBlock.id, false);
continue;
default:
if (block.getTypeId() == newBlock.id && block.getData() == newBlock.data) {
continue;
}
if (newBlock.data == 0) {
block.setTypeId(newBlock.id, false);
} else {
block.setTypeIdAndData(newBlock.id, newBlock.data, false);
}
continue;
}
}
}
int[][] biomes = sc.biomes;
Biome[] values = Biome.values();
if (biomes != null) {
for (int x = 0; x < 16; x++) {
int[] array = biomes[x];
if (array == null) {
continue;
}
for (int z = 0; z < 16; z++) {
int biome = array[z];
if (biome == 0) {
continue;
}
chunk.getBlock(x, 0, z).setBiome(values[biome]);
}
}
}
}
/**
* This should be overriden by any specialized queues
* @param wrap
*/
@Override
public PlotChunk<Chunk> getChunk(ChunkWrapper wrap) {
return new SlowChunk(wrap);
}
/**
* This should be overriden by any specialized queues
* @param fixAll
*/
@Override
public boolean fixLighting(PlotChunk<Chunk> chunk, boolean fixAll) {
// Do nothing
return true;
}
/**
* This should be overriden by any specialized queues
* @param locs
*/
@Override
public void sendChunk(String world, Collection<ChunkLoc> locs) {
// Do nothing
}
}

View File

@ -34,11 +34,16 @@ public class DefaultUUIDWrapper extends UUIDWrapper {
@Override
public OfflinePlotPlayer[] getOfflinePlayers() {
OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length] ;
final OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
final BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length];
for (int i = 0; i < ops.length; i++) {
toReturn[i] = new BukkitOfflinePlayer(ops[i]);
}
return toReturn;
}
@Override
public OfflinePlotPlayer getOfflinePlayer(String name) {
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(name));
}
}

View File

@ -1,18 +1,7 @@
package com.plotsquared.bukkit.uuid;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.World;
import com.google.common.collect.HashBiMap;
import com.google.common.io.Files;
import com.google.common.io.ByteSource;
import com.google.common.io.InputSupplier;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
@ -21,67 +10,104 @@ import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.object.OfflinePlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.ExpireManager;
import com.intellectualcrafters.plot.util.NbtFactory;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation;
import com.intellectualcrafters.plot.util.*;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
import com.plotsquared.bukkit.util.NbtFactory;
import org.bukkit.Bukkit;
import org.bukkit.World;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
public class FileUUIDHandler extends UUIDHandlerImplementation {
public FileUUIDHandler(UUIDWrapper wrapper) {
public FileUUIDHandler(final UUIDWrapper wrapper) {
super(wrapper);
}
@Override
public boolean startCaching(Runnable whenDone) {
if (!super.startCaching(whenDone)) {
return false;
}
return cache(whenDone);
public boolean startCaching(final Runnable whenDone) {
return super.startCaching(whenDone) && cache(whenDone);
}
public boolean cache(final Runnable whenDone) {
final File container = Bukkit.getWorldContainer();
List<World> worlds = Bukkit.getWorlds();
final List<World> worlds = Bukkit.getWorlds();
final String world;
if (worlds.size() == 0) {
if (worlds.isEmpty()) {
world = "world";
}
else {
} else {
world = worlds.get(0).getName();
}
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
PS.debug(C.PREFIX.s() + "&6Starting player data caching for: " + world);
final File uuidfile = new File(PS.get().IMP.getDirectory(), "uuids.txt");
if (uuidfile.exists()) {
try {
final List<String> lines = Files.readAllLines(uuidfile.toPath(), StandardCharsets.UTF_8);
for (String line : lines) {
try {
line = line.trim();
if (line.isEmpty()) {
continue;
}
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
final String[] split = line.split("\\|");
final String name = split[0];
if ((name.isEmpty()) || (name.length() > 16) || !StringMan.isAlphanumericUnd(name)) {
continue;
}
final UUID uuid = uuidWrapper.getUUID(name);
if (uuid == null) {
continue;
}
UUIDHandler.add(new StringWrapper(name), uuid);
} catch (final Exception e2) {
e2.printStackTrace();
}
}
} catch (final IOException e) {
e.printStackTrace();
}
}
if (Settings.TWIN_MODE_UUID) {
final HashBiMap<StringWrapper, UUID> toAdd = HashBiMap.create(new HashMap<StringWrapper, UUID>());
toAdd.put(new StringWrapper("*"), DBFunc.everyone);
HashSet<UUID> all = UUIDHandler.getAllUUIDS();
final HashSet<UUID> all = UUIDHandler.getAllUUIDS();
PS.debug("&aFast mode UUID caching enabled!");
final File playerdataFolder = new File(container, world + File.separator + "playerdata");
String[] dat = playerdataFolder.list(new FilenameFilter() {
final String[] dat = playerdataFolder.list(new FilenameFilter() {
@Override
public boolean accept(final File f, final String s) {
return s.endsWith(".dat");
}
});
boolean check = all.size() == 0;
final boolean check = all.isEmpty();
if (dat != null) {
for (final String current : dat) {
final String s = current.replaceAll(".dat$", "");
try {
UUID uuid = UUID.fromString(s);
final UUID uuid = UUID.fromString(s);
if (check || all.remove(uuid)) {
File file = new File(playerdataFolder + File.separator + current);
InputSupplier<FileInputStream> is = Files.newInputStreamSupplier(file);
NbtFactory.NbtCompound compound = NbtFactory.fromStream(is, NbtFactory.StreamOptions.GZIP_COMPRESSION);
NbtFactory.NbtCompound bukkit = (NbtFactory.NbtCompound) compound.get("bukkit");
String name = (String) bukkit.get("lastKnownName");
long last = (long) bukkit.get("lastPlayed");
ExpireManager.dates.put(uuid, last);
final File file = new File(playerdataFolder + File.separator + current);
final InputSupplier<FileInputStream> is = com.google.common.io.Files.newInputStreamSupplier(file);
final NbtFactory.NbtCompound compound = NbtFactory.fromStream(is, NbtFactory.StreamOptions.GZIP_COMPRESSION);
final NbtFactory.NbtCompound bukkit = (NbtFactory.NbtCompound) compound.get("bukkit");
final String name = (String) bukkit.get("lastKnownName");
final long last = (long) bukkit.get("lastPlayed");
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
}
toAdd.put(new StringWrapper(name), uuid);
}
} catch (final Exception e) {
@ -91,11 +117,12 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
}
}
add(toAdd);
if (all.size() == 0) {
if (whenDone != null) whenDone.run();
if (all.isEmpty()) {
if (whenDone != null) {
whenDone.run();
}
return;
}
else {
} else {
PS.debug("Failed to cache: " + all.size() + " uuids - slowly processing all files");
}
}
@ -116,7 +143,7 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
return s.endsWith(".dat");
}
});
if (dat != null && dat.length != 0) {
if ((dat != null) && (dat.length != 0)) {
for (final String current : dat) {
final String s = current.replaceAll(".dat$", "");
try {
@ -136,7 +163,7 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
return s.endsWith(".dat");
}
});
if (dat != null && dat.length != 0) {
if ((dat != null) && (dat.length != 0)) {
for (final String current : dat) {
names.add(current.replaceAll(".dat$", ""));
}
@ -145,22 +172,27 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
}
for (UUID uuid : uuids) {
try {
File file = new File(playerdataFolder + File.separator + uuid.toString() + ".dat");
InputSupplier<FileInputStream> is = Files.newInputStreamSupplier(file);
NbtFactory.NbtCompound compound = NbtFactory.fromStream(is, NbtFactory.StreamOptions.GZIP_COMPRESSION);
NbtFactory.NbtCompound bukkit = (NbtFactory.NbtCompound) compound.get("bukkit");
String name = (String) bukkit.get("lastKnownName");
long last = (long) bukkit.get("lastPlayed");
final File file = new File(playerdataFolder + File.separator + uuid.toString() + ".dat");
if (!file.exists()) {
continue;
}
final ByteSource is = com.google.common.io.Files.asByteSource(file);
final NbtFactory.NbtCompound compound = NbtFactory.fromStream(is, NbtFactory.StreamOptions.GZIP_COMPRESSION);
final NbtFactory.NbtCompound bukkit = (NbtFactory.NbtCompound) compound.get("bukkit");
final String name = (String) bukkit.get("lastKnownName");
final long last = (long) bukkit.get("lastPlayed");
if (Settings.OFFLINE_MODE) {
if (Settings.UUID_LOWERCASE && !name.toLowerCase().equals(name)) {
uuid = uuidWrapper.getUUID(name);
} else {
long most = (long) compound.get("UUIDMost");
long least = (long) compound.get("UUIDLeast");
final long most = (long) compound.get("UUIDMost");
final long least = (long) compound.get("UUIDLeast");
uuid = new UUID(most, least);
}
}
ExpireManager.dates.put(uuid, last);
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
}
toAdd.put(new StringWrapper(name), uuid);
} catch (final Throwable e) {
PS.debug(C.PREFIX.s() + "&6Invalid playerdata: " + uuid.toString() + ".dat");
@ -172,20 +204,24 @@ public class FileUUIDHandler extends UUIDHandlerImplementation {
toAdd.put(nameWrap, uuid);
}
if (getUUIDMap().size() == 0) {
for (OfflinePlotPlayer op : uuidWrapper.getOfflinePlayers()) {
long last = op.getLastPlayed();
if (getUUIDMap().isEmpty()) {
for (final OfflinePlotPlayer op : uuidWrapper.getOfflinePlayers()) {
final long last = op.getLastPlayed();
if (last != 0) {
String name = op.getName();
StringWrapper wrap = new StringWrapper(name);
UUID uuid = uuidWrapper.getUUID(op);
final String name = op.getName();
final StringWrapper wrap = new StringWrapper(name);
final UUID uuid = uuidWrapper.getUUID(op);
toAdd.put(wrap, uuid);
ExpireManager.dates.put(uuid, last);
if (ExpireManager.IMP != null) {
ExpireManager.IMP.storeDate(uuid, last);
}
}
}
}
add(toAdd);
if (whenDone != null) whenDone.run();
if (whenDone != null) {
whenDone.run();
}
}
});
return true;

View File

@ -24,10 +24,8 @@ public class LowerOfflineUUIDWrapper extends OfflineUUIDWrapper {
public LowerOfflineUUIDWrapper() {
try {
this.getOnline = Server.class.getMethod("getOnlinePlayers", new Class[0]);
} catch (final NoSuchMethodException e) {
e.printStackTrace();
} catch (final SecurityException e) {
getOnline = Server.class.getMethod("getOnlinePlayers");
} catch (final NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
@ -42,8 +40,9 @@ public class LowerOfflineUUIDWrapper extends OfflineUUIDWrapper {
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + player.getName().toLowerCase()).getBytes(Charsets.UTF_8));
}
@Override
public UUID getUUID(final OfflinePlayer player) {
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + player.getName().toLowerCase() ).getBytes(Charsets.UTF_8));
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + player.getName().toLowerCase()).getBytes(Charsets.UTF_8));
}
@Override
@ -69,23 +68,26 @@ public class LowerOfflineUUIDWrapper extends OfflineUUIDWrapper {
return null;
}
@Override
public Player[] getOnlinePlayers() {
if (this.getOnline == null) {
return Bukkit.getOnlinePlayers().toArray(new Player[0]);
if (getOnline == null) {
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
return onlinePlayers.toArray(new Player[onlinePlayers.size()]);
}
try {
final Object players = this.getOnline.invoke(Bukkit.getServer(), this.arg);
final Object players = getOnline.invoke(Bukkit.getServer(), arg);
if (players instanceof Player[]) {
return (Player[]) players;
} else {
@SuppressWarnings("unchecked")
final Collection<? extends Player> p = (Collection<? extends Player>) players;
return p.toArray(new Player[0]);
return p.toArray(new Player[p.size()]);
}
} catch (final Exception e) {
PS.debug("Failed to resolve online players");
this.getOnline = null;
return Bukkit.getOnlinePlayers().toArray(new Player[0]);
getOnline = null;
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
return onlinePlayers.toArray(new Player[onlinePlayers.size()]);
}
}
@ -96,8 +98,8 @@ public class LowerOfflineUUIDWrapper extends OfflineUUIDWrapper {
@Override
public OfflinePlotPlayer[] getOfflinePlayers() {
OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length] ;
final OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
final BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length];
for (int i = 0; i < ops.length; i++) {
toReturn[i] = new BukkitOfflinePlayer(ops[i]);
}

View File

@ -25,10 +25,8 @@ public class OfflineUUIDWrapper extends UUIDWrapper {
public OfflineUUIDWrapper() {
try {
this.getOnline = Server.class.getMethod("getOnlinePlayers", new Class[0]);
} catch (final NoSuchMethodException e) {
e.printStackTrace();
} catch (final SecurityException e) {
getOnline = Server.class.getMethod("getOnlinePlayers");
} catch (final NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
@ -71,22 +69,24 @@ public class OfflineUUIDWrapper extends UUIDWrapper {
}
public Player[] getOnlinePlayers() {
if (this.getOnline == null) {
return Bukkit.getOnlinePlayers().toArray(new Player[0]);
if (getOnline == null) {
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
return onlinePlayers.toArray(new Player[onlinePlayers.size()]);
}
try {
final Object players = this.getOnline.invoke(Bukkit.getServer(), this.arg);
final Object players = getOnline.invoke(Bukkit.getServer(), arg);
if (players instanceof Player[]) {
return (Player[]) players;
} else {
@SuppressWarnings("unchecked")
final Collection<? extends Player> p = (Collection<? extends Player>) players;
return p.toArray(new Player[0]);
return p.toArray(new Player[p.size()]);
}
} catch (final Exception e) {
PS.debug("Failed to resolve online players");
this.getOnline = null;
return Bukkit.getOnlinePlayers().toArray(new Player[0]);
getOnline = null;
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
return onlinePlayers.toArray(new Player[onlinePlayers.size()]);
}
}
@ -97,11 +97,16 @@ public class OfflineUUIDWrapper extends UUIDWrapper {
@Override
public OfflinePlotPlayer[] getOfflinePlayers() {
OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length] ;
final OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
final BukkitOfflinePlayer[] toReturn = new BukkitOfflinePlayer[ops.length];
for (int i = 0; i < ops.length; i++) {
toReturn[i] = new BukkitOfflinePlayer(ops[i]);
}
return toReturn;
}
@Override
public OfflinePlotPlayer getOfflinePlayer(String name) {
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(name));
}
}

View File

@ -0,0 +1,295 @@
package com.plotsquared.bukkit.uuid;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayDeque;
import java.util.Collections;
import java.util.HashMap;
import java.util.UUID;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import com.google.common.collect.HashBiMap;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.database.SQLite;
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.object.StringWrapper;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation;
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
public class SQLUUIDHandler extends UUIDHandlerImplementation {
final String PROFILE_URL = "https://sessionserver.mojang.com/session/minecraft/profile/";
final int MAX_REQUESTS = 500;
final int INTERVAL = 12000;
final JSONParser jsonParser = new JSONParser();
private final SQLite _sqLite;
public SQLUUIDHandler(final UUIDWrapper wrapper) {
super(wrapper);
_sqLite = new SQLite("./plugins/PlotSquared/usercache.db");
try {
_sqLite.openConnection();
} catch (final Exception e) {
e.printStackTrace();
}
try {
final PreparedStatement stmt = getConnection().prepareStatement(
"CREATE TABLE IF NOT EXISTS `usercache` (uuid VARCHAR(32) NOT NULL, username VARCHAR(32) NOT NULL, PRIMARY KEY (uuid, username))");
stmt.execute();
stmt.close();
} catch (final SQLException e) {
e.printStackTrace();
}
startCaching(null);
}
private Connection getConnection() {
synchronized (_sqLite) {
return _sqLite.getConnection();
}
}
@Override
public boolean startCaching(final Runnable whenDone) {
if (!super.startCaching(whenDone)) {
return false;
}
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
try {
final HashBiMap<StringWrapper, UUID> toAdd = HashBiMap.create(new HashMap<StringWrapper, UUID>());
final PreparedStatement statement = getConnection().prepareStatement("SELECT `uuid`, `username` FROM `usercache`");
final ResultSet resultSet = statement.executeQuery();
StringWrapper username;
UUID uuid;
while (resultSet.next()) {
username = new StringWrapper(resultSet.getString("username"));
uuid = UUID.fromString(resultSet.getString("uuid"));
toAdd.put(new StringWrapper(username.value), uuid);
}
statement.close();
add(toAdd);
add(new StringWrapper("*"), DBFunc.everyone);
// This should be called as long as there are some unknown plots
final ArrayDeque<UUID> toFetch = new ArrayDeque<>();
for (final UUID u : UUIDHandler.getAllUUIDS()) {
if (!uuidExists(u)) {
toFetch.add(u);
}
}
if (toFetch.isEmpty()) {
if (whenDone != null) {
whenDone.run();
}
return;
}
final FileUUIDHandler fileHandler = new FileUUIDHandler(SQLUUIDHandler.this.uuidWrapper);
fileHandler.startCaching(new Runnable() {
@Override
public void run() {
// If the file based UUID handler didn't cache it, then we can't cache offline mode
// Also, trying to cache based on files again, is useless as that's what the file based uuid cacher does
if (Settings.OFFLINE_MODE) {
if (whenDone != null) {
whenDone.run();
}
return;
}
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
try {
if (toFetch.isEmpty()) {
if (whenDone != null) {
whenDone.run();
}
return;
}
for (int i = 0; i < Math.min(500, toFetch.size()); i++) {
UUID uuid = toFetch.pop();
HttpURLConnection connection = (HttpURLConnection) new URL(PROFILE_URL + uuid.toString().replace("-", "")).openConnection();
InputStreamReader reader = new InputStreamReader(connection.getInputStream());
JSONObject response = (JSONObject) jsonParser.parse(reader);
String name = (String) response.get("name");
if (name != null) {
add(new StringWrapper(name), uuid);
}
}
} catch (Exception e) {
e.printStackTrace();
}
TaskManager.runTaskLaterAsync(this, INTERVAL);
}
});
/*
* This API is no longer accessible.
*/
// if (!Settings.OFFLINE_MODE) {
// PS.debug(C.PREFIX.s() + "&cWill fetch &6" + toFetch.size() + "&c from mojang!");
//
// int i = 0;
// final Iterator<UUID> iterator = toFetch.iterator();
// while (iterator.hasNext()) {
// final StringBuilder url = new StringBuilder("http://api.intellectualsites.com/uuid/?user=");
// final List<UUID> currentIteration = new ArrayList<>();
// while ((i++ <= 15) && iterator.hasNext()) {
// final UUID _uuid = iterator.next();
// url.append(_uuid.toString());
// if (iterator.hasNext()) {
// url.append(",");
// }
// currentIteration.add(_uuid);
// }
// PS.debug(C.PREFIX.s() + "&cWill attempt to fetch &6" + currentIteration.size() + "&c uuids from: &6" + url.toString());
// try {
// final HttpURLConnection connection = (HttpURLConnection) new URL(url.toString()).openConnection();
// connection.setRequestProperty("User-Agent", "Mozilla/5.0");
// final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// String line;
// final StringBuilder rawJSON = new StringBuilder();
// while ((line = reader.readLine()) != null) {
// rawJSON.append(line);
// }
// reader.close();
// final JSONObject object = new JSONObject(rawJSON.toString());
// for (final UUID _u : currentIteration) {
// final Object o = object.getJSONObject(_u.toString().replace("-", "")).get("username");
// if ((o == null) || !(o instanceof String)) {
// continue;
// }
// add(new StringWrapper(o.toString()), _u);
// }
// } catch (final Exception e) {
// e.printStackTrace();
// }
// i = 0;
// }
// }
// if (whenDone != null) {
// whenDone.run();
// }
}
});
} catch (final SQLException e) {
throw new SQLUUIDHandlerException("Couldn't select :s", e);
}
}
});
return true;
}
@Override
public void fetchUUID(final String name, final RunnableVal<UUID> ifFetch) {
PS.debug(C.PREFIX.s() + "UUID for '" + name + "' was null. We'll cache this from the mojang servers!");
if (ifFetch == null) {
return;
}
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(PROFILE_URL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
String body = JSONArray.toJSONString(Collections.singletonList(name));
OutputStream stream = connection.getOutputStream();
stream.write(body.getBytes());
stream.flush();
stream.close();
JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream()));
JSONObject jsonProfile = (JSONObject) array.get(0);
String id = (String) jsonProfile.get("id");
String name = (String) jsonProfile.get("name");
ifFetch.value = UUID.fromString(id.substring(0, 8) + "-" + id.substring(8, 12) + "-" + id.substring(12, 16) + "-" + id.substring(16, 20) + "-" + id.substring(20, 32));
} catch (Exception e) {
e.printStackTrace();
}
TaskManager.runTask(ifFetch);
}
});
}
@Override
public void handleShutdown() {
super.handleShutdown();
try {
getConnection().close();
} catch (final SQLException e) {
throw new SQLUUIDHandlerException("Couldn't close database connection", e);
}
}
@Override
public boolean add(final StringWrapper name, final UUID uuid) {
// Ignoring duplicates
if (super.add(name, uuid)) {
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
try {
final PreparedStatement statement = getConnection().prepareStatement("REPLACE INTO usercache (`uuid`, `username`) VALUES(?, ?)");
statement.setString(1, uuid.toString());
statement.setString(2, name.toString());
statement.execute();
PS.debug(C.PREFIX.s() + "&cAdded '&6" + uuid + "&c' - '&6" + name + "&c'");
} catch (final SQLException e) {
e.printStackTrace();
}
}
});
return true;
}
return false;
}
/**
* This is useful for name changes
*/
@Override
public void rename(final UUID uuid, final StringWrapper name) {
super.rename(uuid, name);
TaskManager.runTaskAsync(new Runnable() {
@Override
public void run() {
try {
final PreparedStatement statement = getConnection().prepareStatement("UPDATE usercache SET `username`=? WHERE `uuid`=?");
statement.setString(1, name.value);
statement.setString(2, uuid.toString());
statement.execute();
PS.debug(C.PREFIX.s() + "Name change for '" + uuid + "' to '" + name.value + "'");
} catch (final SQLException e) {
e.printStackTrace();
}
}
});
}
private class SQLUUIDHandlerException extends RuntimeException {
SQLUUIDHandlerException(final String s, final Throwable c) {
super("SQLUUIDHandler caused an exception: " + s, c);
}
}
}

View File

@ -1,6 +1,6 @@
name: ${project.name}
name: ${name}
main: com.plotsquared.bukkit.BukkitMain
version: ${project.version}
version: ${version}
load: STARTUP
description: >
Easy, yet powerful Plot World generation and management.
@ -15,10 +15,6 @@ commands:
permission: plots.use
permission-message: "You are lacking the permission node 'plots.use'"
permissions:
plots.admin:
children:
plots.*: true
default: op
plots.use:
default: true
plots.permpack.basicflags:
@ -26,43 +22,51 @@ permissions:
children:
plots.set.flag: true
plots.flag: true
plots.set.flag.titles: true
plots.set.flag.greeting: true
plots.set.flag.farewell: true
plots.set.flag.notify-enter: true
plots.set.flag.notify-leave: true
plots.set.flag.feed: true
plots.set.flag.heal: true
plots.set.flag.invincible: true
plots.set.flag.instabreak: true
plots.set.flag.fly: true
plots.flag.add: true
plots.flag.remove: true
plots.flag.list: true
plots.flag.info: true
plots.set.flag.titles.*: true
plots.set.flag.greeting.*: true
plots.set.flag.farewell.*: true
plots.set.flag.notify-enter.*: true
plots.set.flag.notify-leave.*: true
plots.set.flag.feed.*: true
plots.set.flag.heal.*: true
plots.set.flag.invincible.*: true
plots.set.flag.instabreak.*: true
plots.set.flag.fly.*: true
plots.set.flag.gamemode: true
plots.set.flag.time: true
plots.set.flag.weather: true
plots.set.flag.music: true
plots.set.flag.disable-physics: true
plots.set.flag.pve: true
plots.set.flag.pvp: true
plots.set.flag.explosion: true
plots.set.flag.hostile-interact: true
plots.set.flag.hostile-attack: true
plots.set.flag.animal-interact: true
plots.set.flag.animal-attack: true
plots.set.flag.tamed-interact: true
plots.set.flag.tamed-attack: true
plots.set.flag.misc-interact: true
plots.set.flag.hanging-place: true
plots.set.flag.hanging-break: true
plots.set.flag.vehicle-use: true
plots.set.flag.vehicle-place: true
plots.set.flag.vehicle-break: true
plots.set.flag.player-interact: true
plots.set.flag.place: true
plots.set.flag.break: true
plots.set.flag.use: true
plots.set.flag.forcefield: true
plots.set.flag.price: true
plots.set.flag.no-worldedit: true
plots.set.flag.gamemode.creative: true
plots.set.flag.gamemode.survival: true
plots.set.flag.gamemode.adventure: true
plots.set.flag.time.*: true
plots.set.flag.weather.*: true
plots.set.flag.music.*: true
plots.set.flag.disable-physics.*: true
plots.set.flag.pve.*: true
plots.set.flag.pvp.*: true
plots.set.flag.explosion.*: true
plots.set.flag.hostile-interact.*: true
plots.set.flag.hostile-attack.*: true
plots.set.flag.player-interact.*: true
plots.set.flag.animal-interact.*: true
plots.set.flag.animal-attack.*: true
plots.set.flag.tamed-interact.*: true
plots.set.flag.tamed-attack.*: true
plots.set.flag.misc-interact.*: true
plots.set.flag.hanging-place.*: true
plots.set.flag.hanging-break.*: true
plots.set.flag.vehicle-use.*: true
plots.set.flag.vehicle-place.*: true
plots.set.flag.vehicle-break.*: true
plots.set.flag.player-interact.*: true
plots.set.flag.place.*: true
plots.set.flag.break.*: true
plots.set.flag.use.*: true
plots.set.flag.forcefield.*: true
plots.set.flag.price.*: true
plots.set.flag.no-worldedit.*: true
plots.permpack.basicinbox:
default: op
children:
@ -81,6 +85,15 @@ permissions:
plots.inbox.read.owner: true
plots.comment: true
plots.inbox: true
plots.permpack.wilderness:
default: op
children:
plots.admin.interact.unowned: true
plots.admin.destroy.unowned: true
plots.admin.build.unowned: true
plots.projectile.unowned: true
plots.admin.vehicle.break.unowned: true
plots.admin.pve.unowned: true
plots.permpack.basic:
default: op
children:
@ -104,6 +117,10 @@ permissions:
plots.visit.owned: true
plots.visit.shared: true
plots.set.flag: true
plots.flag.add: true
plots.flag.remove: true
plots.flag.list: true
plots.flag.info: true
plots.flag: true
plots.buy: true
plots.chat: true
@ -115,6 +132,7 @@ permissions:
plots.set.home: true
plots.merge: true
plots.merge.other: true
plots.merge.4: true
plots.unlink: true
plots.denied: true
plots.add: true
@ -128,6 +146,7 @@ permissions:
plots.save: true
plots.done: true
plots.continue: true
plots.middle: true
plots.worldedit.bypass:
default: false
plots.gamemode.bypass:

11
Core/build.gradle Normal file
View File

@ -0,0 +1,11 @@
dependencies {
testCompile 'junit:junit:4.12'
compile 'org.yaml:snakeyaml:1.16'
compile 'com.google.code.gson:gson:2.2.4'
}
sourceCompatibility = 1.7
targetCompatibility = 1.7
jar.archiveName="PlotSquared-API-${parent.version}.jar"
jar.destinationDir = file '../target'

View File

@ -20,7 +20,7 @@ public interface Configuration extends ConfigurationSection {
* @param value Value to set the default to.
* @throws IllegalArgumentException Thrown if path is null.
*/
public void addDefault(String path, Object value);
@Override void addDefault(final String path, final Object value);
/**
* Sets the default values of the given paths as provided.
@ -32,7 +32,7 @@ public interface Configuration extends ConfigurationSection {
* @param defaults A map of Path->Values to add to defaults.
* @throws IllegalArgumentException Thrown if defaults is null.
*/
public void addDefaults(Map<String, Object> defaults);
void addDefaults(final Map<String, Object> defaults);
/**
* Sets the default values of the given paths as provided.
@ -49,7 +49,7 @@ public interface Configuration extends ConfigurationSection {
* @param defaults A configuration holding a list of defaults to copy.
* @throws IllegalArgumentException Thrown if defaults is null or this.
*/
public void addDefaults(Configuration defaults);
void addDefaults(final Configuration defaults);
/**
* Sets the source of all default values for this {@link Configuration}.
@ -60,7 +60,7 @@ public interface Configuration extends ConfigurationSection {
* @param defaults New source of default values for this configuration.
* @throws IllegalArgumentException Thrown if defaults is null or this.
*/
public void setDefaults(Configuration defaults);
void setDefaults(final Configuration defaults);
/**
* Gets the source {@link Configuration} for this configuration.
@ -71,7 +71,7 @@ public interface Configuration extends ConfigurationSection {
*
* @return Configuration source for default values, or null if none exist.
*/
public Configuration getDefaults();
Configuration getDefaults();
/**
* Gets the {@link ConfigurationOptions} for this {@link Configuration}.
@ -80,5 +80,5 @@ public interface Configuration extends ConfigurationSection {
*
* @return Options for this configuration
*/
public ConfigurationOptions options();
ConfigurationOptions options();
}

View File

@ -9,7 +9,7 @@ public class ConfigurationOptions {
private boolean copyDefaults = false;
private final Configuration configuration;
protected ConfigurationOptions(Configuration configuration) {
protected ConfigurationOptions(final Configuration configuration) {
this.configuration = configuration;
}
@ -45,8 +45,8 @@ public class ConfigurationOptions {
* @param value Path separator
* @return This object, for chaining
*/
public ConfigurationOptions pathSeparator(char value) {
this.pathSeparator = value;
public ConfigurationOptions pathSeparator(final char value) {
pathSeparator = value;
return this;
}
@ -83,8 +83,8 @@ public class ConfigurationOptions {
* @param value Whether or not defaults are directly copied
* @return This object, for chaining
*/
public ConfigurationOptions copyDefaults(boolean value) {
this.copyDefaults = value;
public ConfigurationOptions copyDefaults(final boolean value) {
copyDefaults = value;
return this;
}
}

View File

@ -22,7 +22,7 @@ public interface ConfigurationSection {
* list.
* @return Set of keys contained within this ConfigurationSection.
*/
public Set<String> getKeys(boolean deep);
Set<String> getKeys(final boolean deep);
/**
* Gets a Map containing all keys and their values for this section.
@ -38,7 +38,7 @@ public interface ConfigurationSection {
* list.
* @return Map of keys and values of this section.
*/
public Map<String, Object> getValues(boolean deep);
Map<String, Object> getValues(final boolean deep);
/**
* Checks if this {@link ConfigurationSection} contains the given path.
@ -51,7 +51,7 @@ public interface ConfigurationSection {
* default or being set.
* @throws IllegalArgumentException Thrown when path is null.
*/
public boolean contains(String path);
boolean contains(final String path);
/**
* Checks if this {@link ConfigurationSection} has a value set for the
@ -65,7 +65,7 @@ public interface ConfigurationSection {
* having a default.
* @throws IllegalArgumentException Thrown when path is null.
*/
public boolean isSet(String path);
boolean isSet(final String path);
/**
* Gets the path of this {@link ConfigurationSection} from its root {@link
@ -82,7 +82,7 @@ public interface ConfigurationSection {
*
* @return Path of this section relative to its root
*/
public String getCurrentPath();
String getCurrentPath();
/**
* Gets the name of this individual {@link ConfigurationSection}, in the
@ -93,7 +93,7 @@ public interface ConfigurationSection {
*
* @return Name of this section
*/
public String getName();
String getName();
/**
* Gets the root {@link Configuration} that contains this {@link
@ -107,7 +107,7 @@ public interface ConfigurationSection {
*
* @return Root configuration containing this section.
*/
public Configuration getRoot();
Configuration getRoot();
/**
* Gets the parent {@link ConfigurationSection} that directly contains
@ -120,7 +120,7 @@ public interface ConfigurationSection {
*
* @return Parent section containing this section.
*/
public ConfigurationSection getParent();
ConfigurationSection getParent();
/**
* Gets the requested Object by path.
@ -132,7 +132,7 @@ public interface ConfigurationSection {
* @param path Path of the Object to get.
* @return Requested Object.
*/
public Object get(String path);
Object get(final String path);
/**
* Gets the requested Object by path, returning a default value if not
@ -146,7 +146,7 @@ public interface ConfigurationSection {
* @param def The default value to return if the path is not found.
* @return Requested Object.
*/
public Object get(String path, Object def);
Object get(final String path, final Object def);
/**
* Sets the specified path to the given value.
@ -155,14 +155,14 @@ public interface ConfigurationSection {
* replaced, regardless of what the new value is.
* <p>
* Some implementations may have limitations on what you may store. See
* their individual javadocs for details. No implementations should allow
* their individual javadoc for details. No implementations should allow
* you to store {@link Configuration}s or {@link ConfigurationSection}s,
* please use {@link #createSection(java.lang.String)} for that.
* please use {@link #createSection(String)} for that.
*
* @param path Path of the object to set.
* @param value New value to set the path to.
*/
public void set(String path, Object value);
void set(final String path, final Object value);
/**
* Creates an empty {@link ConfigurationSection} at the specified path.
@ -174,7 +174,7 @@ public interface ConfigurationSection {
* @param path Path to create the section at.
* @return Newly created section
*/
public ConfigurationSection createSection(String path);
ConfigurationSection createSection(final String path);
/**
* Creates a {@link ConfigurationSection} at the specified path, with
@ -188,7 +188,7 @@ public interface ConfigurationSection {
* @param map The values to used.
* @return Newly created section
*/
public ConfigurationSection createSection(String path, Map<?, ?> map);
ConfigurationSection createSection(final String path, final Map<?, ?> map);
// Primitives
/**
@ -201,7 +201,7 @@ public interface ConfigurationSection {
* @param path Path of the String to get.
* @return Requested String.
*/
public String getString(String path);
String getString(final String path);
/**
* Gets the requested String by path, returning a default value if not
@ -216,7 +216,7 @@ public interface ConfigurationSection {
* not a String.
* @return Requested String.
*/
public String getString(String path, String def);
String getString(final String path, final String def);
/**
* Checks if the specified path is a String.
@ -229,7 +229,7 @@ public interface ConfigurationSection {
* @param path Path of the String to check.
* @return Whether or not the specified path is a String.
*/
public boolean isString(String path);
boolean isString(final String path);
/**
* Gets the requested int by path.
@ -241,7 +241,7 @@ public interface ConfigurationSection {
* @param path Path of the int to get.
* @return Requested int.
*/
public int getInt(String path);
int getInt(final String path);
/**
* Gets the requested int by path, returning a default value if not found.
@ -255,7 +255,7 @@ public interface ConfigurationSection {
* not an int.
* @return Requested int.
*/
public int getInt(String path, int def);
int getInt(final String path, final int def);
/**
* Checks if the specified path is an int.
@ -268,7 +268,7 @@ public interface ConfigurationSection {
* @param path Path of the int to check.
* @return Whether or not the specified path is an int.
*/
public boolean isInt(String path);
boolean isInt(final String path);
/**
* Gets the requested boolean by path.
@ -280,7 +280,7 @@ public interface ConfigurationSection {
* @param path Path of the boolean to get.
* @return Requested boolean.
*/
public boolean getBoolean(String path);
boolean getBoolean(final String path);
/**
* Gets the requested boolean by path, returning a default value if not
@ -295,7 +295,7 @@ public interface ConfigurationSection {
* not a boolean.
* @return Requested boolean.
*/
public boolean getBoolean(String path, boolean def);
boolean getBoolean(final String path, final boolean def);
/**
* Checks if the specified path is a boolean.
@ -308,7 +308,7 @@ public interface ConfigurationSection {
* @param path Path of the boolean to check.
* @return Whether or not the specified path is a boolean.
*/
public boolean isBoolean(String path);
boolean isBoolean(final String path);
/**
* Gets the requested double by path.
@ -320,7 +320,7 @@ public interface ConfigurationSection {
* @param path Path of the double to get.
* @return Requested double.
*/
public double getDouble(String path);
double getDouble(final String path);
/**
* Gets the requested double by path, returning a default value if not
@ -335,7 +335,7 @@ public interface ConfigurationSection {
* not a double.
* @return Requested double.
*/
public double getDouble(String path, double def);
double getDouble(final String path, final double def);
/**
* Checks if the specified path is a double.
@ -348,7 +348,7 @@ public interface ConfigurationSection {
* @param path Path of the double to check.
* @return Whether or not the specified path is a double.
*/
public boolean isDouble(String path);
boolean isDouble(final String path);
/**
* Gets the requested long by path.
@ -360,7 +360,7 @@ public interface ConfigurationSection {
* @param path Path of the long to get.
* @return Requested long.
*/
public long getLong(String path);
long getLong(final String path);
/**
* Gets the requested long by path, returning a default value if not
@ -375,7 +375,7 @@ public interface ConfigurationSection {
* not a long.
* @return Requested long.
*/
public long getLong(String path, long def);
long getLong(final String path, final long def);
/**
* Checks if the specified path is a long.
@ -388,7 +388,7 @@ public interface ConfigurationSection {
* @param path Path of the long to check.
* @return Whether or not the specified path is a long.
*/
public boolean isLong(String path);
boolean isLong(final String path);
// Java
/**
@ -401,7 +401,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List.
*/
public List<?> getList(String path);
List<?> getList(final String path);
/**
* Gets the requested List by path, returning a default value if not
@ -416,7 +416,7 @@ public interface ConfigurationSection {
* not a List.
* @return Requested List.
*/
public List<?> getList(String path, List<?> def);
List<?> getList(final String path, final List<?> def);
/**
* Checks if the specified path is a List.
@ -429,7 +429,7 @@ public interface ConfigurationSection {
* @param path Path of the List to check.
* @return Whether or not the specified path is a List.
*/
public boolean isList(String path);
boolean isList(final String path);
/**
* Gets the requested List of String by path.
@ -444,7 +444,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of String.
*/
public List<String> getStringList(String path);
List<String> getStringList(final String path);
/**
* Gets the requested List of Integer by path.
@ -459,7 +459,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of Integer.
*/
public List<Integer> getIntegerList(String path);
List<Integer> getIntegerList(final String path);
/**
* Gets the requested List of Boolean by path.
@ -474,7 +474,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of Boolean.
*/
public List<Boolean> getBooleanList(String path);
List<Boolean> getBooleanList(final String path);
/**
* Gets the requested List of Double by path.
@ -489,7 +489,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of Double.
*/
public List<Double> getDoubleList(String path);
List<Double> getDoubleList(final String path);
/**
* Gets the requested List of Float by path.
@ -504,7 +504,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of Float.
*/
public List<Float> getFloatList(String path);
List<Float> getFloatList(final String path);
/**
* Gets the requested List of Long by path.
@ -519,7 +519,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of Long.
*/
public List<Long> getLongList(String path);
List<Long> getLongList(final String path);
/**
* Gets the requested List of Byte by path.
@ -534,7 +534,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of Byte.
*/
public List<Byte> getByteList(String path);
List<Byte> getByteList(final String path);
/**
* Gets the requested List of Character by path.
@ -549,7 +549,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of Character.
*/
public List<Character> getCharacterList(String path);
List<Character> getCharacterList(final String path);
/**
* Gets the requested List of Short by path.
@ -564,7 +564,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of Short.
*/
public List<Short> getShortList(String path);
List<Short> getShortList(final String path);
/**
* Gets the requested List of Maps by path.
@ -579,7 +579,7 @@ public interface ConfigurationSection {
* @param path Path of the List to get.
* @return Requested List of Maps.
*/
public List<Map<?, ?>> getMapList(String path);
List<Map<?, ?>> getMapList(final String path);
/**
* Gets the requested ConfigurationSection by path.
@ -592,7 +592,7 @@ public interface ConfigurationSection {
* @param path Path of the ConfigurationSection to get.
* @return Requested ConfigurationSection.
*/
public ConfigurationSection getConfigurationSection(String path);
ConfigurationSection getConfigurationSection(final String path);
/**
* Checks if the specified path is a ConfigurationSection.
@ -606,7 +606,7 @@ public interface ConfigurationSection {
* @param path Path of the ConfigurationSection to check.
* @return Whether or not the specified path is a ConfigurationSection.
*/
public boolean isConfigurationSection(String path);
boolean isConfigurationSection(final String path);
/**
* Gets the equivalent {@link ConfigurationSection} from the default
@ -618,7 +618,7 @@ public interface ConfigurationSection {
*
* @return Equivalent section in root configuration
*/
public ConfigurationSection getDefaultSection();
ConfigurationSection getDefaultSection();
/**
* Sets the default value in the root at the given path as provided.
@ -638,5 +638,5 @@ public interface ConfigurationSection {
* @param value Value to set the default to.
* @throws IllegalArgumentException Thrown if path is null.
*/
public void addDefault(String path, Object value);
void addDefault(final String path, final Object value);
}

View File

@ -18,7 +18,7 @@ public class InvalidConfigurationException extends Exception {
*
* @param msg The details of the exception.
*/
public InvalidConfigurationException(String msg) {
public InvalidConfigurationException(final String msg) {
super(msg);
}
@ -28,7 +28,7 @@ public class InvalidConfigurationException extends Exception {
*
* @param cause The cause of the exception.
*/
public InvalidConfigurationException(Throwable cause) {
public InvalidConfigurationException(final Throwable cause) {
super(cause);
}
@ -39,7 +39,7 @@ public class InvalidConfigurationException extends Exception {
* @param cause The cause of the exception.
* @param msg The details of the exception.
*/
public InvalidConfigurationException(String msg, Throwable cause) {
public InvalidConfigurationException(final String msg, final Throwable cause) {
super(msg, cause);
}
}

View File

@ -23,13 +23,15 @@ public class MemoryConfiguration extends MemorySection implements Configuration
* @param defaults Default value provider
* @throws IllegalArgumentException Thrown if defaults is null
*/
public MemoryConfiguration(Configuration defaults) {
public MemoryConfiguration(final Configuration defaults) {
this.defaults = defaults;
}
@Override
public void addDefault(String path, Object value) {
if (path == null) throw new NullPointerException("Path may not be null");
public void addDefault(final String path, final Object value) {
if (path == null) {
throw new NullPointerException("Path may not be null");
}
if (defaults == null) {
defaults = new MemoryConfiguration();
}
@ -37,26 +39,36 @@ public class MemoryConfiguration extends MemorySection implements Configuration
defaults.set(path, value);
}
public void addDefaults(Map<String, Object> defaults) {
if (defaults == null) throw new NullPointerException("Defaults may not be null");
@Override
public void addDefaults(final Map<String, Object> defaults) {
if (defaults == null) {
throw new NullPointerException("Defaults may not be null");
}
for (Map.Entry<String, Object> entry : defaults.entrySet()) {
for (final Map.Entry<String, Object> entry : defaults.entrySet()) {
addDefault(entry.getKey(), entry.getValue());
}
}
public void addDefaults(Configuration defaults) {
if (defaults == null) throw new NullPointerException("Defaults may not be null");
@Override
public void addDefaults(final Configuration defaults) {
if (defaults == null) {
throw new NullPointerException("Defaults may not be null");
}
addDefaults(defaults.getValues(true));
}
public void setDefaults(Configuration defaults) {
if (defaults == null) throw new NullPointerException("Defaults may not be null");
@Override
public void setDefaults(final Configuration defaults) {
if (defaults == null) {
throw new NullPointerException("Defaults may not be null");
}
this.defaults = defaults;
}
@Override
public Configuration getDefaults() {
return defaults;
}
@ -66,6 +78,7 @@ public class MemoryConfiguration extends MemorySection implements Configuration
return null;
}
@Override
public MemoryConfigurationOptions options() {
if (options == null) {
options = new MemoryConfigurationOptions(this);

View File

@ -5,7 +5,7 @@ package com.intellectualcrafters.configuration;
* MemoryConfiguration}
*/
public class MemoryConfigurationOptions extends ConfigurationOptions {
protected MemoryConfigurationOptions(MemoryConfiguration configuration) {
protected MemoryConfigurationOptions(final MemoryConfiguration configuration) {
super(configuration);
}
@ -15,13 +15,13 @@ public class MemoryConfigurationOptions extends ConfigurationOptions {
}
@Override
public MemoryConfigurationOptions copyDefaults(boolean value) {
public MemoryConfigurationOptions copyDefaults(final boolean value) {
super.copyDefaults(value);
return this;
}
@Override
public MemoryConfigurationOptions pathSeparator(char value) {
public MemoryConfigurationOptions pathSeparator(final char value) {
super.pathSeparator(value);
return this;
}

Some files were not shown because too many files have changed in this diff Show More