Compare commits

...
306 Commits
Author SHA1 Message Date
md678685 f57557b43a Bump version to 2.16.1 2019-03-01 22:45:25 +00:00
md678685 0711fd6f9e Add #version line to allow automatic items.json updates 2019-03-01 12:04:08 +00:00
md678685 b5ecbd1739 Remove Vault repo
Fixes Travis builds and slow builds - Maven pauses while trying to reach the repo and so Travis assumes that the build has failed.
2019-03-01 11:41:29 +00:00
md678685 dda5e4e333 Merge pull request #2402 from Techno3600/patch-1
Pull Request for #2282
2019-03-01 11:32:46 +00:00
md678685 dde4a36df0 Economy API: Attempt to find users by UUID if username not present (#2432)
Attempt to find user by UUID if username not present. Fixes (maybe) #2400.

https://github.com/EssentialsX/Essentials/issues/2400#issuecomment-466043896
2019-02-22 18:10:36 +00:00
triagonal 31b98fb9f3 allow console to use color codes when sending mail (#2435) @triagonal 2019-02-22 14:34:56 +00:00
kashike 289d34d96c Relocate PaperLib in EssentialsXSpawn too
fixes #2433
2019-02-22 09:58:02 +00:00
md678685 eafd110ed0 Update items.json
Add spawner aliases that end in "spawner".
2019-02-20 14:50:43 +00:00
md678685 e72644abf4 Update items.json
* Add mooshroom spawners
* Add new aliases for red sandstone, sandstone, stone and prismarine variants
2019-02-20 14:42:22 +00:00
md678685 b267103274 Remove getMap(short) method from FakeServer 2019-02-20 12:45:37 +00:00
DoNotSpamPls 3856a690eb Use PaperLib to load chunks and teleport players async (#2409)
* Remove outdated permission plugin handlers, minor test fixes

* Re-add PermissionEX handler

* Use PaperLib to load chunks async whenever possible

* Revert "Use PaperLib to load chunks async whenever possible"

This reverts commit db4df6f3cf.

* Use PaperLib to load chunks and teleport players async

* Resolve some PR issues

* Update PaperLib, return teleport causes

* Remove useless PaperLib usage in LocationUtil

* Fix FakeServer spacing
2019-02-20 12:25:05 +00:00
md678685 f214696664 Check Protect/AntiBuild config materials against Material enum (#2431) 2019-02-20 12:24:30 +00:00
md678685 9e73c29b40 Fix creating and using kits on legacy versions (#2428)
* Attempt to look up legacy items in Material enum
* Use name method when serializing ItemStacks
* Make name uppercase before looking up in Material enum
2019-02-20 12:24:07 +00:00
md678685 aca83bd462 Switch Vault dependency to VaultAPI (#2430)
* Switch Vault dependency to VaultAPI
* Remove direct Vault class usage from VaultEco
2019-02-20 11:28:20 +00:00
md678685 189d6a23c6 Add README section about depending on EssX 2019-02-19 21:58:43 +00:00
md678685 441f88deea Implement missing FakeServer methods 2019-02-17 19:01:47 +00:00
Wiz_Techno 6d6666dace Pull Request for #2282
"Obsolete entries in items.csv should be removed"
2019-01-31 23:14:21 -05:00
Rafał Pokrywka fb779533e6 Replace nbsp with a space when formatting messages (#2394) @ravkr 2019-01-27 12:15:03 +00:00
DoNotSpamPls 7325113a8c Remove outdated permission plugin handlers, minor test fixes (#2367) @DoNotSpamPls
* Remove outdated permission plugin handlers, minor test fixes

* Re-add PermissionEX handler

* Use PaperLib to load chunks async whenever possible

* Revert "Use PaperLib to load chunks async whenever possible"

This reverts commit db4df6f3cf.
2019-01-27 12:14:16 +00:00
Glare Masters 827217823e Add the ability to make spectator gamemode signs (#2386) @darbyjack
Fixes #2383.
2019-01-20 10:14:20 +00:00
md678685 060dfc69f4 Update items.json
Fixed regression of unspawnable items not being marked as such, impacting the alias generation process. This fix also retains the ability to specify non-item blocks in the EssentialsX Protect material lists.
2019-01-12 22:07:03 +00:00
md678685 b831713737 Check whether item is spawnable in FlatItemDb 2019-01-12 21:43:36 +00:00
md678685 7da90b3a6b Load item spawn blacklist after item DB
Partially resolves #2360.
2019-01-12 21:43:36 +00:00
md678685 32540c23ab Add IItemDb#isReady to check if item database is available 2019-01-12 21:43:36 +00:00
md678685 d24b0616f8 Hide ServerListPingEvent exceptions thrown by CB's LegacyPingHandler (#2378)
Fixes #2327.
2019-01-12 17:19:11 +00:00
md678685 9aef2ef883 Update items.json
Add several new aliases. Closes #2348.
2019-01-09 15:10:38 +00:00
md678685 727d473319 Fix Enchantments on 1.12.2 and lower 2019-01-09 14:23:55 +00:00
md678685 8225e51867 Fix XMPP metrics reporting
The XMPP config was being reported as valid when it wasn't valid.
2019-01-09 13:57:18 +00:00
md678685 1ba6c2a596 Properly fix language mappings 2019-01-08 22:19:16 +00:00
md678685 60a166aeb0 Fix language mapping in Crowdin config 2019-01-08 21:45:46 +00:00
md678685 65c2155bca Update Crowdin config
Map most locales to the existing locale files.
2019-01-08 21:36:16 +00:00
md678685 6031c01584 Update Crowdin config
Fix file placement and map locale codes to existing translations
2019-01-08 21:21:35 +00:00
md678685 da8e8c8a25 Update Crowdin config
Crowdin should only use `messages.properties` as the "source" and this file will get copied to all the other language files like `messages_de.properties` for the German translation, `messages_ro.properties` for the Romanian translation etc.
2019-01-08 21:14:56 +00:00
Trent Hensler 70a750a32d Update Crowdin configuration file 2019-01-08 12:48:25 -08:00
md678685 7c63324504 Fix allow-old-id-signs allowing creation of signs with IDs 2019-01-07 22:38:13 +00:00
md678685 dd41b10522 attempt to fix Essentials overriding Skulls (#2356) @kennyrkun 2019-01-05 18:48:33 +00:00
triagonal 7948e764d4 disallow setting bed homes in non-overworld dimensions (#2335) @triagonal 2019-01-05 18:43:27 +00:00
DoNotSpamPls 82ede4530a Lots of little fixes in the Essentials modules (#2337) @DoNotSpamPls
Look at changed files for the changes
2019-01-05 18:42:09 +00:00
md678685 e8ab2db8e8 Improve ServerListPingEvent warning handling 2019-01-05 18:12:04 +00:00
md678685 8882e0214c Add bStats metrics for each EssentialsX module (#2333)
Does what it says on the tin.
2019-01-05 17:48:44 +00:00
md678685 4adb669cdd Add support for spawners with entities on 1.13+ 2019-01-05 17:35:29 +00:00
md678685 7e1d258dd3 Cache BukkitVersion in getServerBukkitVersion 2019-01-05 16:29:11 +00:00
md678685 417fe29e21 Remove duplicated item IDs in messages 2019-01-05 16:28:53 +00:00
md678685 bd8ef2a25d Only show available warps in tab complete
Fixes #2353 by only displaying warps where the player has the permission `essentials.warps.<warp>`.
2019-01-05 15:45:34 +00:00
md678685 fd01b75c33 Wrap UnsafeValues.fromLegacy() in try/catch for older versions
Should address #2352.
2019-01-05 15:27:07 +00:00
md678685 1388755d2a Wrap Enchantment.getByKey in try/catch for older versions
Should address #2351.
2019-01-05 15:17:58 +00:00
md678685 97cc3d0066 Update items.json
* Fix wrong harming potion mapping (fixes #2349)
* Add mob spawner aliases (not complete, related to #2347)
* Closes #2348:
  - Fix log aliases mistakenly pointing to stripped logs
  - Fix sandstone alias
  - Add shorter concrete powder aliases
2019-01-05 15:04:59 +00:00
md678685 694cf7a79e Revert 1.13 API hacks in LegacyItemDb
Earlier changes broke the items.csv database on older versions - this should now be fixed.
2019-01-04 15:01:18 +00:00
md678685 da89efb79f Make VersionUtil not explode when patch is not present 2019-01-03 22:16:14 +00:00
md678685 04ec013407 Update README to reflect 1.13 support 2019-01-03 21:25:48 +00:00
md678685 023cf6a1aa Merge pull request #2278 from EssentialsX/1.13
Full 1.13 support + 2.16.0 release
2019-01-03 20:56:14 +00:00
md678685 f7cbb141f8 Release 2.16.0
🎉
2019-01-03 20:47:24 +00:00
md678685 5690952516 Implement missing OfflinePlayer methods 2019-01-03 20:42:03 +00:00
md678685 e94202c55a Use 1.8-friendly User#getItemInHand method in commands 2019-01-03 20:33:08 +00:00
md678685 aa6ad271a0 Remove redundant metricsEnabled field from Settings 2019-01-03 20:33:08 +00:00
md678685 3b41bb47b6 Improve Travis build script (#2338)
I've added a new script at `scripts/buildtools.sh` that is responsible for:
* Checking whether CraftBukkit 1.8 and 1.8.3 are already available in the local Maven repo
* Downloading BuildTools if not already present
* Running BuildTools if necessary

This improves Travis build times as it now doesn't run BuildTools twice for *every single build*, instead running it only if the Travis cache fails and CraftBukkit is missing for some other reason.
2019-01-01 16:13:50 +00:00
md678685 e7bdb7fabc Improve the wording of the README's "Building" section 2019-01-01 15:42:45 +00:00
md678685 110698223d Travis: make build prep script executable 2019-01-01 15:23:35 +00:00
md678685 437be593b9 Add new build preparation script 2019-01-01 15:10:59 +00:00
md678685 502d37b574 Update Lombok to compile on Java 9+ 2018-12-31 17:44:08 +00:00
md678685 df59f9f859 Merge remote-tracking branch 'origin/2.x' into 1.13 2018-12-31 14:59:12 +00:00
md678685 f436fbab6b Remove redundant BuildTools runs 2018-12-31 14:54:59 +00:00
seema84 8404720501 change typos (#2328) @seema84
* change typos

* format text

* remove double color
2018-12-31 13:08:57 +00:00
md678685 4431d452f1 Bump to 2.16-pre4
Pretty much there now.
2018-12-31 13:02:08 +00:00
md678685 6a529d6671 Update EssentialsX Protect with cross-version enum lookups 2018-12-31 12:54:43 +00:00
md678685 78fca9a67a Updates signs with cross-version enum lookups 2018-12-31 12:53:41 +00:00
md678685 0114b5e4f6 Update several commands with cross-version enum lookups 2018-12-31 12:53:23 +00:00
md678685 5a14a64b6c Add cross-version support to SpawnMob 2018-12-31 12:24:41 +00:00
md678685 b555ea6350 Add cross-version support to MobData 2018-12-31 12:20:05 +00:00
md678685 361ae1dd16 Use constant field for "harp"/"piano" sound 2018-12-31 12:19:22 +00:00
md678685 58117eba88 Remove redundant BuildTools instructions 2018-12-31 12:18:45 +00:00
md678685 6260b49b4f Restore item ID messages in /itemdb 2018-12-31 11:57:15 +00:00
md678685 988239267b Restore durability permissions checks in AntiBuild 2018-12-31 11:56:50 +00:00
md678685 19cffe3872 Restore ID-based charges in /repair 2018-12-31 11:39:08 +00:00
md678685 3b1cef918e Simplify item spawn permission checks; restore ID-based item spawn perms 2018-12-31 11:29:27 +00:00
md678685 3553328f7a Bump to 2.16-pre3 2018-12-29 21:22:08 +00:00
md678685 0202271f00 Add missing FakeWorld methods 2018-12-29 21:16:17 +00:00
md678685 d91d6a419c Update items.json
* Fix incorrect "cobblestone" and "stone" aliases
* Fix stripped log aliases not appearing
* Fix meat/fish aliases pointing to spawn eggs
2018-12-28 16:40:39 +00:00
md678685 5173090474 Update items.json
Adds more minecart, meat, fish and hay aliases.
2018-12-26 21:05:48 +00:00
md678685 c26df8318f Update items.json
* Add more shorter spawn egg aliases
* Add new trapdoor aliases
* Add new infested block aliases and stone brick variants
2018-12-26 19:24:50 +00:00
md678685 7b44f0088a Update items.json
* Add spawn eggs aliases
* Add new aliases for several items and blocks like beetroot, pumpkins and crafting tables
* Remove `WALL_` materials (these are unspawnable)
2018-12-26 18:05:55 +00:00
md678685 aa4d3cc9fd Bump to 2.16-pre2 2018-12-25 00:27:54 +00:00
md678685 246fd03265 Fix typo in README 2018-12-23 23:33:46 +00:00
md678685 55074872fe Add setting to enable item ID recognition on signs
Item IDs can now be enabled for existing signs by manually changing a config option, but there is no facility to create new signs with item IDs.
2018-12-23 23:02:36 +00:00
md678685 28559dda3a Lowercase the provided ID in FlatItemDb#get 2018-12-23 19:45:23 +00:00
md678685 cbcfad5b2e Merge branch '2.x' into 1.13 2018-12-23 19:33:20 +00:00
md678685 a9ad440860 Overhaul AbstractItemDb.serialize to use MaterialUtil methods 2018-12-23 19:32:10 +00:00
md678685 5104463593 Add MaterialUtil.getColorOf 2018-12-23 19:31:33 +00:00
md678685 4b1c51c21d Reword IItemDb#serialize docs 2018-12-23 18:02:38 +00:00
md678685 236ef52980 Improved README (#2293)
I've made several improvements to the README, including:
* Overall rewording to make phrasing feel less awkward
* Added links to Patreon
* More consistent images for links at top
* Consolidated "Why you should use it" and "Other info" into "Why use EssentialsX?"
* More specific about version support
* Moved "Support" section above "Building" and added explanation
* Removed redundant "Commit Guidelines" section
  - It has been totally ignored for years, and it doesn't make much sense to keep it
* Added a new "Contributing" section near the bottom
2018-12-23 17:21:31 +00:00
md678685 f220c5b406 Update Estonian sudoExempt message
Thanks to @Madis0 for [pointing this out and translating it](https://github.com/EssentialsX/Essentials/pull/2228#issuecomment-449586891).
2018-12-22 17:47:39 +00:00
Thomas 9415582fe1 Update messages_nl.properties (#2129) @DutchUser
* Update messages_nl.properties

* Update messages_nl.properties

* Update messages_nl.properties

* Update messages_nl.properties

* Update messages_nl.properties
2018-12-22 17:42:42 +00:00
Sprungente a5a3630727 [Finish] Improving German localization (#2198) @Sprungente
* Improving 

I found some stuff to improve the translation. I'm not done yet but i think it's ready to get an eye on it. 

Hope it will be used :)

Greets Sprungente/enterih

* mistake^^

^

* Part 2

Adding more Improvements
Hope it helps other serverowners^^

* Part 2 fixes

* Part 3 



Notice for me 
a-d finished
\u00f6 ö    \u00e4 ä  \u00fc ü

* Part 4

Notice for me 
a-i finished
\u00f6 ö    \u00e4 ä  \u00fc ü

* Last part 

is line 456
requiredBukkit=\u00a76* \! * Du brauchst mindestens CraftBukkit Build \#{0}, lade es von http\://dl.bukkit.org/downloads/craftbukkit/
still exist? If yes, could a reference to spigot be added?

It's ready to merge. Can i take care on it in the future?

* small polishing

* Update messages_de.properties

* Update messages_de.properties

* Adding new strings 

added strings from #2278
2018-12-22 17:39:44 +00:00
Madis f4c36d9c43 Estonian translation update (#2228)
* Initial improvements

* Half done

* Almost done

* Translation done

* Encode umlauts

* Additional refinements

* Minor fix

* Some more tweaks

* Minor wording change

* 1.13 strings
2018-12-22 17:36:47 +00:00
md678685 492005d00a Fix LegacyItemID method override 2018-12-15 19:11:41 +00:00
md678685 149d9b61cc Add methods to facilitate conversion from IDs to new Materials 2018-12-15 18:54:01 +00:00
md678685 77ffb6a3d5 Slightly simplify FlatItemDb 2018-12-15 18:53:06 +00:00
md678685 d95b632884 Merge branch '2.x' into 1.13 2018-12-11 14:31:42 +00:00
md678685 579f554edb Update nickname again after toggling AFK status 2018-12-11 13:26:15 +00:00
md678685 050287f306 Add 1.13 enchantments
Fixes #2254.
2018-12-11 10:04:38 +00:00
md678685 dafe156212 Merge branch '2.x' into 1.13 2018-12-09 15:25:31 +00:00
md678685 48bf264178 Fix discrepancies between default and EN locale 2018-12-09 15:21:07 +00:00
md678685 769dbe8852 Fix BukkitVersion's toString and equals 2018-12-09 15:16:44 +00:00
md678685 67bccb865a Remove colour codes from serverUnsupported in EN locale 2018-12-09 15:16:18 +00:00
md678685 d1e60de04a Ignore kits.yml created during tests 2018-12-09 15:15:55 +00:00
md678685 89d592ce43 Improve item-spawn-blacklist load logging 2018-12-09 14:58:56 +00:00
md678685 c06dda886d Actually use the force-enable-recipe option from the config 2018-12-09 14:58:36 +00:00
md678685 23d92fac63 Bump version to 2.16.0 and release 2.16-pre1 2018-12-09 14:33:53 +00:00
md678685 5922b85290 Move SHIELD to from MetaItemStack to MaterialUtil 2018-12-09 13:47:52 +00:00
md678685 814e5a643e Add SIGNS and SPAWNER to MaterialUtil 2018-12-09 13:47:22 +00:00
md678685 3db3a272d5 Update default kits.yml file
Item IDs are no longer supported in 1.13+, so remove them from the default kits section.
2018-12-09 13:07:11 +00:00
md678685 2d703fbc80 Add damage value support to FlatItemDb
...in case you wanted to give players broken swords, or something?
2018-12-09 13:04:21 +00:00
md678685 b49d3cc21c Remove unnecessary kits file
This is a leftover from dev environments and is *not* the one copied into the jar during build.
2018-12-09 13:02:44 +00:00
md678685 02b5d2357a Add missing FakeServer methods 2018-12-09 12:29:28 +00:00
md678685 1206178eca Use utility methods in MetaItemStack 2018-12-09 12:17:13 +00:00
md678685 3df3f8a812 Add several cross-version item type checks to MaterialUtil 2018-12-09 12:17:13 +00:00
md678685 7049952b07 Load forceEnableRecipe during Settings.reloadConfig 2018-12-09 12:17:13 +00:00
Mark Vadeika a18ce40921 Hiding display names (#2248) @AllTheMegahertz
Prevents a user's nickname from appearing if they are hidden, if `hide-displayname-in-vanish: true` in the config. Closes #2221.

* Does not return display name if user is hidden

* Added hide-displayname-in-vanish field

* Added hideDisplayNameInVanish()

* Changed to only hide display name if specified in config

* Changed hideDisplayNameInVanish to default to false if not specified in config.yml
2018-12-09 11:02:45 +00:00
md678685 6a6383462d Allow admins to force enable /recipe if they want
Add `force-enable-recipe`, which allows server admins to manually enable `/recipe` despite potential duplication exploits. Use this at your own risk!

Related: #1397
2018-12-08 16:41:24 +00:00
md678685 44301fae4f Fix Worth.setPrice on 1.13+; add Javadocs to Worth 2018-12-08 16:32:09 +00:00
md678685 6ee84510ea Update bStats-Metrics 2018-12-06 17:49:08 +00:00
md678685 6ecdc8d7fc Enu-moo-til 2018-12-06 17:44:22 +00:00
md678685 35a2a4d803 Add several version warning messages 2018-12-06 17:41:32 +00:00
md678685 7b67b3b858 Don't send empty line join/quit messages
GitHub meta: fixes #991 fixes #2289
2018-12-06 14:06:25 +00:00
md678685 4011810536 Correctly use LegacyItemDb after detecting version < 1.13 2018-11-19 22:51:07 +00:00
md678685 85ea07c97e Fix VersionUtil regex matching and BukkitVersion.toString 2018-11-19 22:48:33 +00:00
md678685 41b2449cdd Change /enchant's default level from -1 to 1 2018-11-19 21:11:25 +00:00
md678685 ec83a5fff2 Add EntityPickupItemEvent listener to AntiBuild 2018-11-19 20:20:10 +00:00
md678685 ded6f06ed2 Merge remote-tracking branch 'origin/2.x' into 1.13 2018-11-19 19:48:38 +00:00
md678685 2605e050a0 Deduplicate ItemDb code 2018-11-19 19:41:01 +00:00
md678685 19b1e19e42 Remove extraneous imports 2018-11-19 19:30:35 +00:00
md678685 f7a1149cac Port old ItemDb back 2018-11-19 14:13:05 +00:00
md678685 7dd52dab32 Add non-NMS VersionUtil
*Should* work on Glowstone. TODO: use this instead of ReflUtil where appropriate.
2018-11-19 14:12:10 +00:00
md678685 937aec600a Implement more FakeServer methods 2018-11-19 12:52:19 +00:00
md678685 4802053da6 Rename en-GB to en_GB for consistency 2018-11-19 12:51:26 +00:00
md678685 0105dff7ac Update AntiBuild default entries to enum names 2018-11-19 12:49:34 +00:00
md678685 8cc448efcf Remove meta/durability checks from AntiBuild 2018-11-19 11:38:50 +00:00
md678685 982b358bf8 Bump AntiBuild and Protect to api-version: 1.13 2018-11-19 11:28:31 +00:00
md678685 ffc80d61af Implement missing FakeWorld and OfflinePlayer methods 2018-11-19 11:26:05 +00:00
md678685 f55956612c Add messages_en-GB.properties (#2206)
Tins what it does on the say.
2018-11-19 08:38:37 +00:00
md678685 cd3b342d74 Target Bukkit 1.13.2 2018-10-31 15:00:54 +00:00
md678685 ba959586e2 Merge remote-tracking branch 'games647/java9' into 1.13 2018-10-31 14:53:49 +00:00
md678685 4c07e584b7 Default to max stack size 2018-10-31 14:47:45 +00:00
Banbeucmas 280d1215de Adding EssentialsWarpEvent (#1921) @Banbeucmas
* Adding EssentialsWarpEvent for checking if player is wrapping

* Spacing

* Adding Trade parameter

* Refactoring

* Adding #setWarp() to the Event

* Spacing

* Documenting the purpose of the Event

* Javadoc?
2018-10-28 18:53:52 +00:00
montlikadani a2a95ed840 Added acacia and dark oak tree types (#2001) @montlikadani
* Update Commandbigtree.java

* Update Commandbigtree.java

* Update Commandtree.java
2018-10-28 18:41:46 +00:00
md678685 4bd9461282 Rename help-.md to help.md 2018-10-28 10:54:01 +00:00
md678685 96adef5269 Update issue templates (#2045)
* Update issue templates

Add new issue templates - I didn't even know GitHub had these now

* Remove duplicate bug template

* Remove duplicate feature template

* Update help-.md

* Update report-a-bug.md

* Update request-a-feature.md

* Delete ISSUE_TEMPLATE.md
2018-10-27 15:42:56 +01:00
md678685 9576ea25a6 Use reflection-based detection for pickup listener in player listener (#2151)
Allows the plugin to start up on Glowstone correctly.

Tested on Spigot 1.12.2, Spigot 1.9.4 and Glowstone 2018.7.0, works correctly on all.
2018-10-27 15:37:29 +01:00
md678685 a7fcafb245 Filter out comment lines when loading items.json 2018-10-27 15:00:04 +01:00
md678685 73bb41d579 Merge branch '1.13-items' into 1.13 2018-10-26 15:59:51 +01:00
md678685 0a90d76493 Remove item IDs from Worth 2018-10-15 13:56:36 +01:00
md678685 010981d3c8 Remove ID-based charges in /repair 2018-10-15 13:51:04 +01:00
md678685 3353061e76 Remove ID-based permission checks in /more 2018-10-15 13:49:16 +01:00
md678685 79bc34047b Allow multiple item names in /clearinventory
Allow a comma-separated list of item names in /clearinventory.
2018-10-15 13:46:12 +01:00
md678685 60c90408e7 Remove ID-based permission checks in /give and /item 2018-10-15 13:16:10 +01:00
md678685 1218c3e226 Merge branch '1.13' into 1.13-items 2018-10-13 18:23:58 +01:00
md678685 a05fc9d08e Remove duplicated OfflinePlayer method 2018-10-13 17:14:10 +01:00
md678685 6906ef2154 Merge branch '1.13' into 1.13-items 2018-10-13 16:59:57 +01:00
md678685 7d25e84ebc Merge branch '2.x' into 1.13 2018-10-13 16:59:44 +01:00
md678685 121d935315 Implement missing FakeServer methods 2018-10-13 16:55:49 +01:00
md678685 2f66a866d8 Implement missing FakeWorld and OfflinePlayer methods 2018-10-13 16:55:42 +01:00
md678685 0e088c17a8 Remove IdProvider dependency 2018-10-13 16:45:20 +01:00
md678685 4cd8a6636b Log invalid JSON entries 2018-10-13 16:44:50 +01:00
md678685 5c7fc763fc Formatting 2018-10-13 16:44:24 +01:00
md678685 1e381a59be Throw meaningful exception when item not found 2018-10-13 16:32:21 +01:00
md678685 85111f25cb Use ItemData#equals when finding item name
Avoids accidentally causing an NPE while comparing potion data.
2018-10-13 16:09:45 +01:00
md678685 f78887a02e Remove item IDs from /itemdb 2018-10-13 15:59:25 +01:00
md678685 feba535637 Actually assign the ManagedFile to file 2018-10-13 15:38:45 +01:00
md678685 3262143c73 Implement missing FakeServer methods 2018-10-13 15:30:27 +01:00
md678685 18feb7967a Implement missing FakeWorld and OfflinePlayer methods 2018-10-13 15:26:58 +01:00
md678685 e9b1511117 Remove item ID support in Worth 2018-10-12 17:26:41 +01:00
md678685 177e5f62f7 Remove providers; move JSON support into ItemDb 2018-10-12 17:26:22 +01:00
md678685 f3f4395da7 Reset BuildTools work directory on Travis 2018-10-09 20:32:40 +01:00
md678685 442e46b012 Return to root after BuildTools on Travis 2018-10-09 20:25:36 +01:00
md678685 37d699d05b mkdir -p in Travis 2018-10-09 19:54:31 +01:00
md678685 77ed1e1d4a Ensure Travis runs BuildTools before mvn install 2018-10-09 19:52:42 +01:00
md678685 50e4cd67b5 Fix typo in Travis config 2018-10-09 19:47:57 +01:00
md678685 83a90eb553 Update .travis.yml 2018-10-09 19:45:28 +01:00
md678685 c29599d39a Create .travis.yml 2018-10-09 19:34:07 +01:00
md678685 692e0adde4 Use MONSTER_EGG in SpawnEggRefl 2018-09-09 16:37:02 +01:00
md678685 cdba518bae Revert "Implement 1.13 item support (#2153)" 2018-09-09 16:35:20 +01:00
md678685 b70b67fa1f Remove unnecessary CraftBukkit dependency 2018-09-09 16:34:15 +01:00
md678685 ff0ca9bc7b Remove unnecessary CraftBukkit dependency 2018-09-05 19:20:18 +01:00
md678685 320bc25d94 Implement 1.13 item support (#2153)
Uses two distinct providers to support items on 1.13 while falling back to `items.csv` for previous versions of Minecraft.
2018-09-05 14:23:16 +01:00
md678685 425e955b5d Update items.json
Add some more aliases to the file
2018-09-05 14:19:09 +01:00
pop4959 33ae9a2597 Fix TropicalFish spawning (#2159)
The name can't have a space in it or it won't be matched by any commands.
2018-09-05 13:26:33 +01:00
pop4959 19913d3612 Implement abstract method Entity::getFacing in OfflinePlayer (#2157) @pop4959
Allows EssentialsX to compile against the latest Spigot version.

Reference: [https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/8ab814cd5c415258aa0ab7617051ee4ea9f4e7bd](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/8ab814cd5c415258aa0ab7617051ee4ea9f4e7bd)
2018-09-05 11:00:27 +01:00
pop4959 a3eb58724f Add a way to use unsafe nicknames (#2152) @pop4959
Pretty much what the title says. Closes #1630.

This is a fun little feature that I'm sure many people have always wanted. I can understand that the original authors of Essentials were probably concerned about users entering names that cannot display correctly in the chat, and that is understandable.

I have added a new permission "essentials.nick.allowunsafe", which must be given to anyone who is allowed to use characters outside of the alphanumeric set. The name of the permission is inspired from "essentials.enchantments.allowunsafe", which allows unsafe enchantment levels to be applied to items without guaranteed behaviour. Similarly, the permission "essentials.nick.allowunsafe" allows unsafe characters to be entered for the user's nickname without making any guarantee that those characters will show up in chat correctly.
2018-09-02 12:14:26 +01:00
md678685 0afa00779c Add some comments to LegacyItemDbProvider 2018-09-01 19:31:32 +01:00
md678685 17d5545804 Update items.json
Fix incorrect type for Uncraftable Potions
2018-09-01 16:46:55 +01:00
md678685 cd70662f01 Update items.json
Fixes some potions spawning incorrectly where the vanilla name didn't match the Bukkit enum name
2018-09-01 16:27:28 +01:00
md678685 a89c97409b Use potion data when looking up items 2018-09-01 15:48:14 +01:00
md678685 102cb6d949 Merge branch '1.13' into 1.13-items 2018-09-01 10:46:27 +01:00
md678685 6c9c9ad42a Use enum methods throughout plugin for cross-version enum lookups 2018-09-01 10:35:08 +01:00
md678685 acbc96fd55 Add enum utility helpers for Statistic and Material 2018-09-01 10:34:11 +01:00
md678685 ca721c1acb Add V1_13_R2 to ReflUtil 2018-08-27 21:29:30 +01:00
md678685 3bf669c42a ItemDbProvider#resolve returns ItemData
More useful than just returning the Material.
2018-08-27 21:21:06 +01:00
md678685 cdc5f75fcb Remove unnecessary equals method on abstract ItemData 2018-08-27 21:19:36 +01:00
md678685 d74f19970b Strip out legacy ItemDb code, pt 1928371236123897 2018-08-27 21:19:15 +01:00
md678685 2ddde37771 Improve FlatItemData#equals 2018-08-27 21:02:27 +01:00
md678685 c1c422e03d Update items.json 2018-08-27 21:00:57 +01:00
md678685 7608b7d658 Merge branch '1.13' into 1.13-items 2018-08-27 20:01:48 +01:00
md678685 d1d5ae814f Merge branch '2.x' into 1.13 2018-08-27 20:01:01 +01:00
md678685 452fa61717 Change tryProvider test values 2018-08-27 19:58:19 +01:00
md678685 825f697fd2 Update items.json 2018-08-27 19:30:05 +01:00
md678685 4ea71ae88e Implement missing methods in FakeWorld 2018-08-27 14:10:06 +01:00
md678685 bdb32f5878 Bump Bukkit version to 1.13.1 2018-08-27 13:10:15 +01:00
md678685 e3c726b8f6 Log total loaded items on reload 2018-08-27 13:06:27 +01:00
md678685 96c6c7b1ca Add per-provider implementations of ItemData 2018-08-27 11:23:47 +01:00
md678685 634d62f9ef Fix typo in /kickall 2018-08-27 10:30:29 +01:00
md678685 2806156cf4 Add "allow-world-in-broadcastworld" option
Allows players to send broadcasts to a specified world by running `/broadcastworld [world] <message>` if enabled.

This is disabled by default in old configs to avoid confusion between updates.
2018-08-27 10:26:54 +01:00
md678685 e642192461 Kick players in /banip
The four-year-old to-do has finally been done!

Closes #2143.
2018-08-26 22:54:00 +01:00
md678685 959c788f22 Don't kick exempt players when running /kickall 2018-08-26 21:03:17 +01:00
montlikadani cda520589a Revert "Doesn't kick all players if the player has permission (#2145) @montlikadani"
This reverts commit 5c1db129d3.
2018-08-26 20:59:46 +01:00
montlikadani 5c1db129d3 Doesn't kick all players if the player has permission (#2145) @montlikadani
So, if a player has permission (eg, an operator or more), they will not kick them out because of permission.
2018-08-26 20:13:05 +01:00
Leomixer17 c718962426 Update messages_it.properties (#2144) @Leomixer17 2018-08-26 17:07:05 +01:00
Thomas 575a11b645 Updated "createKitSuccess=" (#2133) @DutchUser
* Updated "createKitSuccess="

They have the old one, its now in the "kits.yml" not in "config.yml"

* Update messages_da.properties

* Update messages_de.properties

* Update messages_es.properties

* Update messages_en.properties

* Update messages_et.properties

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess=

* Updated "createKitSuccess=

* Updated "createKitSuccess=

* Updated "createKitSuccess=

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Update messages_vi.properties

Going add the other later today, 

* invalidItemFlagMeta
* noJailsDefined
* openingDisposal
* socialSpyMsgFormat
* socialSpyMutedPrefix
* tempbanJoin
* whoisUuid

* Update messages_vi.properties

* Update messages_vi.properties @md678685

I have no idea why this whole file is in `\u` codes

* Update messages.properties @md678685
2018-08-26 16:12:13 +01:00
Xeyame f97c5fc1ff Make /realname configurable (#1952) @Xeyame
Closes #1810.

@md678685: I've added colour codes to the `realName` messages by default, which was not originally part of this PR.
2018-08-26 15:39:37 +01:00
montlikadani 81397d98b8 Added editable messages (#2072) @montlikadani
**If it is accepted then I will add it to the other message files.**
2018-08-26 15:17:07 +01:00
Leomixer17 82b2ff0b3f Update messages_it.properties (#2142) @Leomixer17 2018-08-26 15:13:33 +01:00
md678685 05fcb7b1aa Refactor to allow items to be added after first load 2018-08-25 18:38:50 +01:00
md678685 c79db98978 Add more debug logging to Settings (#2140)
Adds debug logging for `getChatFormat` and `getCommandCooldownEntry`, which makes it much easier to track down issues with group formats in EssentialsX Chat and command cooldowns respectively.
2018-08-25 18:09:08 +01:00
md678685 303aa77901 Add missing import 2018-08-25 16:55:12 +01:00
md678685 65a4ef7ee5 Use items that actually exist in tryProvider 2018-08-25 16:54:50 +01:00
md678685 1be7fbd8a6 Remove hash comment when rebuilding JSON database 2018-08-25 16:54:09 +01:00
Max Roncace 935b5cfe0f Fix unbreakable attribute for kits (#2071) @caseif
This PR fixes the `unbreakable` attribute on kit items. Previously, Essentials was exclusively using an internal Spigot method to set this on `ItemMeta` objects; however, this solution seems to be non-functional on more recent Spigot builds (1.12.2).

I have altered the `MetaItemStack#setUnbreakable` method to use the native Bukkit method, available for [some time now](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/d986a3f), by default. Essentials will still use the old solution as a fallback in case of an older Bukkit version which does not have native support for the attribute.
2018-08-25 11:33:17 +01:00
md678685 bad02729db Allow /eco take to subtract a user's exact balance 2018-08-24 15:42:17 +01:00
md678685 80f7ded687 SPECTATOR mode is safe for teleporting everywhere. (#2049)
Teleporting in spectator mode is as safe as creative mode for every target.
2018-08-24 15:24:26 +01:00
Max Lee f569b89d8f Round down balance when converting to double (#2135) 2018-08-21 23:45:58 +01:00
md678685 fec655a29c Implement ItemDbProviders, pt 7
Implement getStack and resolve for FlatItemDbProvider
2018-08-19 23:12:27 +01:00
md678685 610774b0b9 Remove default getStack implementation 2018-08-19 23:11:30 +01:00
md678685 9487665fae Use Bukkit PotionData instead of our own 2018-08-19 23:10:23 +01:00
md678685 d5b43b7162 Include JSON files in jar at build time 2018-08-19 23:09:02 +01:00
md678685 718d9d9d3a Initialise provider and file during first reload 2018-08-19 21:55:29 +01:00
md678685 3705dbdd2b Add items.json
TODO: should we auto-download from the CI on build?
2018-08-19 21:43:53 +01:00
md678685 c37d516980 Use MONSTER_EGG in SpawnEggRefl 2018-08-19 21:16:16 +01:00
md678685 b27a6b5b8e Add additional timer marks 2018-08-19 21:11:51 +01:00
md678685 98809fafd7 Strip out legacy ItemDb code, pt 4 2018-08-19 21:10:54 +01:00
md678685 dd9a0de98d Implement ItemDbProviders, pt 6 2018-08-19 20:58:45 +01:00
md678685 de2298cf0a Strip out legacy ItemDb code, pt 3 2018-08-19 20:58:23 +01:00
md678685 56fb8b06cd Add listNames to abstract ItemDbProvider 2018-08-19 20:55:56 +01:00
md678685 3b1eb683e1 Merge branch 'patch-20' into 2.x @montlikadani 2018-08-19 20:17:32 +01:00
md678685 1029305382 Implement ItemDbProviders, pt 5 2018-08-19 19:23:20 +01:00
md678685 9b39509e88 Misc changes 2018-08-19 18:30:44 +01:00
md678685 9da58dde5c Strip out legacy ItemDb code, pt 2 2018-08-19 18:04:13 +01:00
md678685 e2507d2ff1 Implement ItemDbProviders, pt 4 2018-08-19 18:03:53 +01:00
md678685 b867f121c9 Implement ItemDbProviders, pt 3 2018-08-19 17:49:34 +01:00
montlikadani 3c6a869336 Fix iron armor bug (#2054) 2018-08-19 16:57:14 +01:00
RikoDEV f357e76980 Small corrections in the Polish translation (#2103) 2018-08-19 16:56:16 +01:00
gb2233 946a1fbb7c Fixed unicode characters in HU locale (#2130) 2018-08-19 16:55:14 +01:00
Oliver Ni 37acdc18f2 Fix Easter egg config typo (#2124) @oliver-ni
Left clicking mobs with a milk bucket turns them into a baby, not right clicking.
2018-08-16 20:24:53 +01:00
Ali Moghnieh 4dc1d2c50e Merge branch '2.x' into 1.13 2018-08-16 17:47:37 +01:00
Aerodog ed72d117a5 Add {ONLINE} variable to custom join message (#2043) 2018-08-16 17:42:14 +01:00
md678685 a302913130 Clean up unused files 2018-08-15 20:08:22 +01:00
md678685 659f1a271a Merge branch '1.13' into 1.13-items 2018-08-15 19:51:35 +01:00
md678685 3fb4b7958d Strip out legacy ItemDb code, pt 1 2018-08-15 19:50:15 +01:00
md678685 3ef0f20b0d Add tipped arrows support on 1.9/1.10
On a side note, need to investigate why the potion provider is only needed on 1.10 and below - I don't remember what changed in 1.11?
2018-08-15 19:42:12 +01:00
md678685 340baa9703 Add IEssentials#getItemDbProvider method 2018-08-15 19:40:35 +01:00
md678685 0e9232ba81 Remove breaking import 2018-08-15 19:40:08 +01:00
md678685 299afdc6a1 Add V1_13_R1 to ReflUtil 2018-08-15 18:05:44 +01:00
md678685 04feed8524 Add 1.13+ spawn egg provider
Not sure how necessary this is, but I've done it anyway
2018-08-15 17:46:55 +01:00
md678685 773979cb37 Provide ItemDb provider with other providers
Provide providers to the provider that needs the providers. Provider provider provider provide provider.
2018-08-15 16:56:46 +01:00
md678685 c27d05fd4b Fix dependency on IdProvider 2018-08-15 16:40:01 +01:00
md678685 52d814f2cc Properly fix inaccurate playtime measurement
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/b848d8ce633871b52115247b089029749c02f579
2018-08-15 15:26:11 +01:00
md678685 5009b3b545 Revert "Fix playtime calculation"
This reverts commit 4e165d375c.
2018-08-15 15:15:30 +01:00
md678685 4e165d375c Fix playtime calculation 2018-08-14 19:29:28 +01:00
md678685 306f7a7872 Merge pull request #2119 from lagnat/1.13
Add missing methods for OfflinePlayer, FakeWorld, and FakeServer.
2018-08-14 19:20:21 +01:00
md678685 6c11569ac9 Merge branch '2.x' into 1.13 2018-08-14 18:58:06 +01:00
md678685 4be28ba193 Implement ItemDbProviders, pt 2 2018-08-14 18:57:47 +01:00
Steve Green a1e98f898b Add missing methods for OfflinePlayer, FakeWorld, and FakeServer. 2018-08-14 08:35:33 -04:00
md678685 c5376d3088 Implement ItemDbProviders, pt 1 2018-08-10 22:07:02 +01:00
md678685 3e1857b966 Add module for FlattenedProvider 2018-08-08 15:42:29 +01:00
md678685 b8a8232bc3 Wrap all constructScalar calls with reflection
Allows configs to function with both SnakeYAML 1.19 and 1.21.
2018-08-06 18:19:30 +01:00
md678685 504a7aef0f Add 1.13 mobs 2018-08-06 17:09:50 +01:00
md678685 1ddb1822ef Merge branch '2.x' into 1.13 2018-08-05 23:02:11 +01:00
md678685 d3cd4e356d Add missing OfflinePlayer 1.13 methods 2018-08-05 20:51:39 +01:00
md678685 bef440760a Remove deprecated economy libs and support
None of these economy plugins are supported any more, and removing these allows EssentialsX to be used as a dependency without locally `mvn install`ing the plugin.
2018-08-05 20:51:19 +01:00
Ali Moghnieh 768b92749f update bukkit to 1.13-R0.1-SNAPSHOT.
This commit just fixes compilation errors.
2018-07-29 17:39:32 +01:00
DoNotSpamPls 03b25a0f06 Set target to Java 8 (for 1.13) & update Maven plugins (#1922) @DoNotSpamPls
This is the same PR as the last one (PR #1823), but I messed that one up accidently, sorry for that!
2018-07-17 09:38:01 +01:00
md678685 a44775cafb Prevent users being duplicated in the ignore list
Fixes #2064, as well as alleviating the issue encountered in kangarko/ChatControl-Pro#627 for EssentialsX users.
2018-07-17 07:33:14 +01:00
montlikadani 187c4eb371 Update messages_hu.properties 2018-06-28 18:27:02 +02:00
montlikadani 49201b9945 Update messages_hu.properties 2018-06-28 17:48:27 +02:00
montlikadani 6225dc8ed1 Update messages_hu.properties 2018-06-21 14:39:25 +02:00
Brokkonaut aa622f8d27 SPECTATOR mode is safe for teleporting everywhere. 2018-06-18 23:38:54 +02:00
md678685 849efa9756 Merge branch '2.x' of https://github.com/EssentialsX/Essentials into 2.x-upstream 2018-06-15 19:44:45 +01:00
md678685 8aa764f69f Check whether nick equals "off" before formatting
Fixes #1910.
2018-06-15 19:41:56 +01:00
md678685 de57a8c602 Disable EssProtect emergency mode when Ess loads late (#1954)
Related: EssentialsX/Essentials#1951.
2018-06-15 19:21:18 +01:00
md678685 4873beb100 Allow updating the compass target to be optional (#1937)
If `compass-towards-home-perm` is enabled in the EssentialsX config, then the permission `essentials.home.compass` is checked before changing the player's compass target.

Closes #1918.
2018-06-15 19:20:06 +01:00
md678685 27d9f3725a Wrap constructScalar for SnakeYAML 1.21 (#2040)
In theory, fixes #1974, fixes #1975 and fixes #1976, and also means that
Spigot are free to upgrade SnakeYAML to 1.21 again when ready.
2018-06-15 19:18:55 +01:00
md678685 16b2c3dee3 Reset pending confirmations on login (#2033)
On login, resets any pending confirmations for the user. Fixes #2021,
closes #2023.
2018-06-15 19:09:27 +01:00
BaoKunVN 2ced9469d7 Vietnamese Translation (#1824) @BauKunVN 2018-06-13 21:23:00 +01:00
montlikadani 45c806128a Updated the messages_hu.properties file 2018-05-31 20:23:48 +02:00
md678685 3d60aa1747 Fix build errors (#2018)
Fixes build errors caused by the warp owner PRs (#1961 and #2017)
2018-05-28 12:21:23 -07:00
FlashLight34 967bb44d94 Update IWarps.java (#2017) @FlashLight34
Maybe the compilation fails because that :P
2018-05-27 07:33:37 +01:00
Xeyame 7298393ec9 Add permission to bypass other's msgtoggle (#1955) @Xeyame
* Add permission to bypass other's msgtoggle

Also thanks to MD for helping me with the code :)

* Correct comment

* Remove checking for console in favour of the already existing IUser check

* Fix comments, again

* Re add isIgnoreMsg() check

Accidently removed it, sorry

* Combine 2 checks
2018-05-26 20:43:31 +01:00
FlashLight34 817caf299f setwarp owner uuid in yml file (#1961) @FlashLight34
* Update Warps.java

its not a real change i dont know if user.getuuid() exist or onother possible cmd maybe

* Update Warps.java

* Update Commandsetwarp.java

* Update Warps.java

* Update Warps.java

* Update Commandsetwarp.java

* Update Warps.java

* Update Warps.java

* Update Commandsetwarp.java

* Update Warps.java
2018-05-26 20:42:51 +01:00
montlikadani 2ff29dab80 Update Commanddeljail.java (#2002) @montlikadani
When the user entered a word to delete the jail, deleted it, but removed anything because no jail existed.
2018-05-26 20:40:45 +01:00
Brokkonaut 030eb3375b Block ignite only for PvP, not for PvE (#1967) @Brokkonaut
Players with god mode enabled could not ignite mobs with bows while only igniting players should be blocked.
2018-05-26 20:34:31 +01:00
md678685 3237632eb4 Fix versioning of NMS modules (#1971)
Resolves numerous build errors that emerged in 613e852ffd and for some reason didn't cause a build error on ender.zone, but did everywhere else.

Fixes #1970
2018-05-18 01:23:20 -07:00
Joseph Hirschfeld b29f98c525 [Feature] Add world specific /back dest. perms (#1948) @Ichbinjoe
Adds world specific perms for whether a player may use /back to teleport
back to a given world. Adds logic to default
essentials.back.into.<world> permissions for loaded worlds to true to
maintain backwards compatibility.
2018-04-29 15:49:49 +01:00
md678685 b2a5280971 Avoid build version being overridden by Jenkins (#1936) 2018-03-29 14:19:19 -07:00
games647 c7000846cd Replace Reflection with setter implementation 2018-03-21 11:16:27 +01:00
games647 d24fbc9f55 Remove final modifier to fix illegal reflective access warning
Java 9 runtimes report warnings for reflective access on JRE
classes (in this case Field.modifiers). Future versions of Java
may deny the access completely.

Since we access our own code here, we could just remove the final modifier.
With it's current visibility (of private) it's unlikely that it will be
modified from somewhere else except our Settings class.
2018-03-13 16:46:25 +01:00
games647 7e40d13947 Update lombok and remove antrun to fix compiling with JDK9
* Lombok: Older version resulted in NoSuchFieldEx: pid (fixed since 1.16.8)

* JDK9 no longer has a tools.jar because of it's modular system, but ant is
no longer required. It was introduced in 3e9a2377a8
for GroupManager. Now GM is no longer maintained and removed in
    * 5ca02e6596 (calling the build.xml)
    * fa0bbde236 (removing the remaining module)
2018-03-13 16:06:39 +01:00
Trent Hensler ace361af60 Compile against 1.13 preview.
Still a lot of work to do. One thing to note is that I used LEGACY materials in a few spots where I didn't know what the new ones are as I'm not very familiar with the 1.13 update and what it changes.
2018-01-18 17:52:44 -08:00
Trent Hensler 1a820ad9b7 Initial removal of item IDs.
We do not rely on Bukkit's item ids anymore, though we still support them in commands via a mapping built off of the items.csv.
2017-12-12 22:06:25 -08:00
217 changed files with 29564 additions and 7160 deletions

No files matched your search

-41
View File
@@ -1,41 +0,0 @@
<!--
Don't put anything inside this block, as it won't be included in the issue.
If you have a question about using EssentialsX, it may be more helpful to ask
in our Discord server: https://discord.gg/F7gexAQ
If you have a feature suggestion for EssentialsX, please delete the template.
Otherwise, if you are reporting a bug, read on:
1. Fill out the template, running the commands either in the console or
as a player. Don't simply put "latest" or we will ignore it.
2. When linking files, do not attach them to the post! Paste them on
https://gist.github.com/, then paste a link to them in the relevant parts
of the template. Avoid using Hastebin or Pastebin, as files are deleted
after a period of time.
3. If you are reporting an issue with lag, please include a timings report.
4. If you are reporting an issue with messages or in-game behaviour, please
include screenshots detailing the problem.
5. Include a description and any other details that may be helpful under the
Details section.
6. Delete this line and all above lines before posting your issue! -->
### Information
Full output of `/ess version`:
Server log (upload `logs/latest.log` to [Gist](https://gist.github.com/)):
EssentialsX config (upload `plugins/Essentials/config.yml` to [Gist](https://gist.github.com/)):
### Details
Describe your issue here.
+45
View File
@@ -0,0 +1,45 @@
---
name: Help!
about: Encountered a problem with EssentialsX? Not sure how to fix it?
---
<!-- EssentialsX help guide
Don't write inside the arrows as they will be hidden when you post your issue.
Want faster support? Come join our Discord server to get help sooner:
https://discord.gg/F7gexAQ
If you're happy to wait (or you were sent here from Discord), read on:
1. Fill out the template.
This will help us understand what problem you've encountered and help us
find a solution.
2. Check the Common Issues page.
Read through the wiki page to see if you've encountered a regular issue:
https://essentialsx.github.io/#/Common-Issues
3. Delete this line and all above lines before posting your issue! -->
### Information
Full output of `/ess version`:
<!-- Replace this with the command output -->
**Server log:** <!-- Upload `logs/latest.log` to https://gist.github.com/ -->
**EssentialsX config** <!-- Upload `plugins/Essentials/config.yml` to https://gist.github.com/ -->
### Help request
**Problem**
<!-- What problem did you encounter? -->
**What I have tried**
<!-- What have you tried so far? -->
**Screenshots**
<!-- If relevant, include any screenshots here. -->
+58
View File
@@ -0,0 +1,58 @@
---
name: Report a bug
about: Report an EssentialsX bug. Only use this if you're 100% sure there's something wrong with EssentialsX - otherwise, try "Help!".
---
<!-- EssentialsX bug reporting guide
Don't put anything inside this block, as it won't be included in the issue.
If you are reporting a bug, please follow the following steps:
1. Fill out the template in full.
Run the commands in the console. Don't just put "latest" as a version,
or we will ignore it.
2. When linking files, do not attach them to the post!
Copy and paste any logs into https://gist.github.com/, then paste a
link to them in the relevant parts of the template. Avoid using
Hastebin or Pastebin, as this makes providing support more difficult.
**DO NOT drag files into this box!**
3. If you are reporting a performance issue, please include a link to a
Timings and/or profiler report.
4. If you are reporting a bug with commands or something else in-game,
please include screenshots to help us diagnose the problem.
5. Make sure not to write between the arrows, as anything there will be
hidden.
6. Delete this line and all above lines before posting your issue! -->
### Information
**Full output of `/ess version`**:
```
<!-- Run the command in your console, and copy and paste the whole output here -->
```
**Server log**: <!-- Upload `logs/latest.log` to https://gist.github.com/, replace this with link -->
**EssentialsX config**: <!-- Upload `plugins/Essentials/config.yml` to https://gist.github.com/, replace this with link -->
### Details
**Description**
<!-- Replace this with a brief summary of the bug. -->
**Steps to reproduce**
<!-- Replace this with exactly what you did to cause the bug. -->
**Expected behavior**
<!-- Replace this with what you expected to happen. -->
**Screenshots**
<!-- Replace this with screenshots, if necessary. -->
@@ -0,0 +1,45 @@
---
name: Request a feature
about: Suggest a feature you want to see in EssentialsX!
---
<!-- EssentialsX feature request guide
Fill out the template. Don't write inside the arrows as they will be hidden
when you post your issue.
Not sure if your feature fits in EssentialsX? Feel free to ask on our Discord
server: https://discord.gg/F7gexAQ
If you have a feature suggestion for EssentialsX, read the following tips:
1. Fill out the template.
This will help us understand what you're requesting and why you want us
to add it.
2. Keep it simple.
Make sure it's easy to understand what you're requesting. A good way is
to keep it to one request per GitHub issue, as we can then easily track
feature requests.
3. Check whether it has already been asked or added.
You can search the issue tracker to see if your feature has already been
requested at https://github.com/EssentialsX/Essentials/issues. You can
also check the wiki at https://essentialsx.github.io/ to see if the
feature was recently added.
4. Ask yourself: "Does this belong in EssentialsX?"
There are lots of features that we reject because most servers won't
need or use them. If your feature is very specific or already exists in
another plugin, it might not be a good fit for EssentialsX.
5. Delete this line and all above lines before posting your issue! -->
### Feature request
**Feature description**
<!-- What feature are you suggesting? -->
**How the feature is useful**
<!-- How is the feature useful to players, server owners and/or developers? -->
+18 -52
View File
@@ -1,52 +1,18 @@
.DS_Store
/BuildAll/nbproject/private/
/EssentialsProtect/nbproject/private/
/EssentialsChat/nbproject/private/
/EssentialsGroupBridge/nbproject/private/
/EssentialsGeoIP/nbproject/private/
/EssentialsSpawn/nbproject/private/
/EssentialsXMPP/nbproject/private/
/BuildAll/build/
/EssentialsGroupBridge/dist/
/EssentialsGroupBridge/build/
/EssentialsGeoIP/dist/
/EssentialsGeoIP/build/
/BuildAll/dist/
/EssentialsChat/build/
/EssentialsChat/dist/
/EssentialsSpawn/build/
/EssentialsSpawn/dist/
/EssentialsXMPP/dist/
/EssentialsXMPP/build/
/EssentialsProtect/dist/
/EssentialsProtect/build/
/EssentialsPermissionsCommands/nbproject/private/
/EssentialsPermissionsCommands/build/
/EssentialsPermissionsCommands/dist/
/Essentials/nbproject/private/
/Essentials/dist/
/Essentials/build/
/YamlAnnotations/
/EssentialsUpdate/nbproject/private/
/EssentialsRelease/
/EssentialsUpdate/dist/
/EssentialsUpdate/build/
/WebPush/apikey.php
/WebPush/nbproject/private
/EssentialsAntiBuild/nbproject/private/
/EssentialsAntiBuild/dist/
/EssentialsAntiBuild/build/
/jars
/out
.idea/
*.iml
*.classpath
*.project
*.settings/
target/
dependency-reduced-pom.xml
/Essentials/config.yml
/Essentials/userdata/testplayer1.yml
/Essentials/usermap.csv
/Essentials/userdata
/EssentialsGroupManager/target/
# IDE files
*.classpath
*.project
*.settings/
.idea/
*.iml
.DS_Store
# Essentials files
/Essentials/userdata
/Essentials/config.yml
/Essentials/kits.yml
/Essentials/userdata/testplayer1.yml
/Essentials/usermap.csv
# Build files
target/
jars/
+10
View File
@@ -0,0 +1,10 @@
language: java
cache:
directories:
- .buildtools
- $HOME/.m2
before_install:
- chmod +x scripts/buildtools.sh
- scripts/buildtools.sh
-39
View File
@@ -1,39 +0,0 @@
# EssentialsX new Kit configuration.
# If you don't have any kits defined in this file, the plugin will try to copy them from the config.yml
# Note: All items MUST be followed by a quantity!
# All kit names should be lower case, and will be treated as lower in permissions/costs.
# Syntax: - itemID[:DataValue/Durability] Amount [Enchantment:Level].. [itemmeta:value]...
# For Item Meta information visit http://wiki.ess3.net/wiki/Item_Meta
# 'delay' refers to the cooldown between how often you can use each kit, measured in seconds.
# Set delay to -1 for a one time kit.
# For more information, visit http://wiki.ess3.net/wiki/Kits
kits:
tools:
delay: 10
items:
- 272 1
- 273 1
- 274 1
- 275 1
dtools:
delay: 600
items:
- 278 1 efficiency:1 durability:1 fortune:1 name:&4Gigadrill lore:The_drill_that_&npierces|the_heavens
- 277 1 digspeed:3 name:Dwarf lore:Diggy|Diggy|Hole
- 298 1 color:255,255,255 name:Top_Hat lore:Good_day,_Good_day
- 279:780 1
notch:
delay: 6000
items:
- 397:3 1 player:Notch
color:
delay: 6000
items:
- 387 1 title:&4Book_&9o_&6Colors author:KHobbits lore:Ingame_color_codes book:Colors
firework:
delay: 6000
items:
- 401 1 name:Angry_Creeper color:red fade:green type:creeper power:1
- 401 1 name:Starry_Night color:yellow,orange fade:blue type:star effect:trail,twinkle power:1
- 401 2 name:Solar_Wind color:yellow,orange fade:red shape:large effect:twinkle color:yellow,orange fade:red shape:ball effect:trail color:red,purple fade:pink shape:star effect:trail power:1
+32 -58
View File
@@ -6,25 +6,18 @@
<parent>
<groupId>net.ess3</groupId>
<artifactId>EssentialsXParent</artifactId>
<version>2.15.0</version>
<version>2.16.1</version>
</parent>
<artifactId>EssentialsX</artifactId>
<licenses>
<license>
<name>GPLv3</name>
<url>http://www.gnu.org/copyleft/gpl.html</url>
</license>
</licenses>
<build>
<finalName>EssentialsX-${full.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<version>3.8.0</version>
<configuration>
<showDeprecation>false</showDeprecation>
</configuration>
@@ -32,7 +25,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
@@ -41,61 +34,48 @@
</goals>
</execution>
</executions>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>io.papermc.lib</pattern>
<shadedPattern>com.earth2me.essentials.paperlib</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>BOSEconomy</groupId>
<artifactId>BOSEconomy</artifactId>
<version>v0.7.8.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/../lib/BOSEconomy.jar</systemPath>
</dependency>
<dependency>
<groupId>iConomy</groupId>
<artifactId>iConomy5</artifactId>
<version>5</version>
<scope>system</scope>
<systemPath>${project.basedir}/../lib/iCo5.jar</systemPath>
</dependency>
<dependency>
<groupId>iConomy</groupId>
<artifactId>iConomy6</artifactId>
<version>6</version>
<scope>system</scope>
<systemPath>${project.basedir}/../lib/iCo6.jar</systemPath>
</dependency>
<dependency>
<groupId>MultiCurrency</groupId>
<artifactId>MultiCurrency</artifactId>
<version>2.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/../lib/MultiCurrency.jar</systemPath>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>Vault</artifactId>
<version>1.5.6</version>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>NMSProvider</artifactId>
<version>2.0.1</version>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>UpdatedMetaProvider</artifactId>
<version>2.0.1</version>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>1_8_R1Provider</artifactId>
<version>2.0.1</version>
<version>2.16.1</version>
<scope>compile</scope>
<exclusions>
<exclusion>
@@ -107,7 +87,7 @@
<dependency>
<groupId>net.ess3</groupId>
<artifactId>1_8_R2Provider</artifactId>
<version>2.0.1</version>
<version>2.16.1</version>
<scope>compile</scope>
<exclusions>
<exclusion>
@@ -119,26 +99,20 @@
<dependency>
<groupId>net.ess3</groupId>
<artifactId>LegacyProvider</artifactId>
<version>2.0.1</version>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>ReflectionProvider</artifactId>
<version>2.0.1</version>
<version>2.16.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>FlattenedProvider</artifactId>
<version>2.16.1</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<repositories>
<repository>
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
</repositories>
</project>
@@ -1,6 +1,6 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import java.util.HashMap;
@@ -13,6 +13,7 @@ import java.util.Set;
public class Enchantments {
private static final Map<String, Enchantment> ENCHANTMENTS = new HashMap<String, Enchantment>();
private static final Map<String, Enchantment> ALIASENCHANTMENTS = new HashMap<String, Enchantment>();
private static boolean isFlat;
static {
ENCHANTMENTS.put("alldamage", Enchantment.DAMAGE_ALL);
@@ -197,14 +198,57 @@ public class Enchantments {
ALIASENCHANTMENTS.put("sweeping", sweeping);
}
} catch (IllegalArgumentException ignored) {}
try { // 1.13
Enchantment loyalty = Enchantment.getByName("LOYALTY");
if (loyalty != null) {
ENCHANTMENTS.put("loyalty", loyalty);
ALIASENCHANTMENTS.put("loyal", loyalty);
ALIASENCHANTMENTS.put("return", loyalty);
}
Enchantment impaling = Enchantment.getByName("IMPALING");
if (impaling != null) {
ENCHANTMENTS.put("impaling", impaling);
ALIASENCHANTMENTS.put("impale", impaling);
ALIASENCHANTMENTS.put("oceandamage", impaling);
ALIASENCHANTMENTS.put("oceandmg", impaling);
}
Enchantment riptide = Enchantment.getByName("RIPTIDE");
if (riptide != null) {
ENCHANTMENTS.put("riptide", riptide);
ALIASENCHANTMENTS.put("rip", riptide);
ALIASENCHANTMENTS.put("tide", riptide);
ALIASENCHANTMENTS.put("launch", riptide);
}
Enchantment channelling = Enchantment.getByName("CHANNELING");
if (channelling != null) {
ENCHANTMENTS.put("channelling", channelling);
ALIASENCHANTMENTS.put("chanelling", channelling);
ALIASENCHANTMENTS.put("channeling", channelling);
ALIASENCHANTMENTS.put("chaneling", channelling);
ALIASENCHANTMENTS.put("channel", channelling);
}
} catch (IllegalArgumentException ignored) {}
try {
Class<?> namespacedKeyClass = Class.forName("org.bukkit.NamespacedKey");
Class<?> enchantmentClass = Class.forName("org.bukkit.enchantments.Enchantment");
enchantmentClass.getDeclaredMethod("getByKey", namespacedKeyClass);
isFlat = true;
} catch (ClassNotFoundException | NoSuchMethodException e) {
isFlat = false;
}
}
public static Enchantment getByName(String name) {
Enchantment enchantment;
if (NumberUtil.isInt(name)) {
enchantment = Enchantment.getById(Integer.parseInt(name));
} else {
enchantment = Enchantment.getByName(name.toUpperCase(Locale.ENGLISH));
Enchantment enchantment = null;
if (isFlat) { // 1.13+ only
enchantment = Enchantment.getByKey(NamespacedKey.minecraft(name.toLowerCase()));
}
if (enchantment == null) {
enchantment = Enchantment.getByName(name.toUpperCase());
}
if (enchantment == null) {
enchantment = ENCHANTMENTS.get(name.toLowerCase(Locale.ENGLISH));
@@ -18,6 +18,9 @@
package com.earth2me.essentials;
import com.earth2me.essentials.commands.*;
import com.earth2me.essentials.items.AbstractItemDb;
import com.earth2me.essentials.items.FlatItemDb;
import com.earth2me.essentials.items.LegacyItemDb;
import com.earth2me.essentials.metrics.Metrics;
import com.earth2me.essentials.perm.PermissionsHandler;
import com.earth2me.essentials.register.payment.Methods;
@@ -28,6 +31,7 @@ import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.textreader.KeywordReplacer;
import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.VersionUtil;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
@@ -37,17 +41,17 @@ import net.ess3.api.ISettings;
import net.ess3.nms.PotionMetaProvider;
import net.ess3.nms.SpawnEggProvider;
import net.ess3.nms.SpawnerProvider;
import net.ess3.nms.flattened.FlatSpawnEggProvider;
import net.ess3.nms.legacy.LegacyPotionMetaProvider;
import net.ess3.nms.legacy.LegacySpawnEggProvider;
import net.ess3.nms.legacy.LegacySpawnerProvider;
import net.ess3.nms.refl.ReflSpawnEggProvider;
import net.ess3.nms.updatedmeta.BasePotionDataProvider;
import net.ess3.nms.updatedmeta.BlockMetaSpawnerProvider;
import net.ess3.nms.legacy.LegacySpawnEggProvider;
import net.ess3.nms.legacy.LegacySpawnerProvider;
import net.ess3.nms.v1_8_R1.v1_8_R1SpawnerProvider;
import net.ess3.nms.v1_8_R2.v1_8_R2SpawnerProvider;
import net.ess3.providers.ProviderFactory;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.block.Block;
@@ -60,6 +64,8 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.InvalidDescriptionException;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
@@ -90,7 +96,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
private transient Worth worth;
private transient List<IConf> confList;
private transient Backup backup;
private transient ItemDb itemDb;
private transient AbstractItemDb itemDb;
private transient final Methods paymentMethod = new Methods();
private transient PermissionsHandler permissionsHandler;
private transient AlternativeCommandsHandler alternativeCommandsHandler;
@@ -166,6 +172,10 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
Console.setInstance(this);
if (!VersionUtil.isServerSupported()) {
getLogger().severe(tl("serverUnsupported"));
}
final PluginManager pm = getServer().getPluginManager();
for (Plugin plugin : pm.getPlugins()) {
if (plugin.getDescription().getName().startsWith("Essentials") && !plugin.getDescription().getVersion().equals(this.getDescription().getVersion()) && !plugin.getDescription().getName().equals("EssentialsAntiCheat")) {
@@ -186,29 +196,38 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
final EssentialsUpgrade upgrade = new EssentialsUpgrade(this);
upgrade.beforeSettings();
execTimer.mark("Upgrade");
confList = new ArrayList<>();
settings = new Settings(this);
confList.add(settings);
execTimer.mark("Settings");
userMap = new UserMap(this);
confList.add(userMap);
execTimer.mark("Init(Usermap)");
kits = new Kits(this);
confList.add(kits);
upgrade.convertKits();
execTimer.mark("Kits");
upgrade.afterSettings();
execTimer.mark("Upgrade2");
warps = new Warps(getServer(), this.getDataFolder());
confList.add(warps);
execTimer.mark("Init(Spawn/Warp)");
worth = new Worth(this.getDataFolder());
confList.add(worth);
itemDb = new ItemDb(this);
itemDb = getItemDbFromConfig();
confList.add(itemDb);
execTimer.mark("Init(Worth/ItemDB)");
jails = new Jails(this);
confList.add(jails);
execTimer.mark("Init(Jails)");
spawnerProvider = new ProviderFactory<>(getLogger(),
Arrays.asList(
BlockMetaSpawnerProvider.class,
@@ -218,6 +237,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
), "mob spawner").getProvider();
spawnEggProvider = new ProviderFactory<>(getLogger(),
Arrays.asList(
FlatSpawnEggProvider.class,
ReflSpawnEggProvider.class,
LegacySpawnEggProvider.class
), "spawn egg").getProvider();
@@ -226,7 +246,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
BasePotionDataProvider.class,
LegacyPotionMetaProvider.class
), "potion meta").getProvider();
execTimer.mark("Init(Providers)");
reload();
// The item spawn blacklist is loaded with all other settings, before the item
// DB, but it depends on the item DB, so we need to reload it again here:
((Settings) settings)._lateLoadItemSpawnBlacklist();
} catch (YAMLException exception) {
if (pm.getPlugin("EssentialsUpdate") != null) {
LOGGER.log(Level.SEVERE, tl("essentialsHelp2"));
@@ -246,8 +271,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
Economy.setEss(this);
execTimer.mark("RegHandler");
for (World w : Bukkit.getWorlds())
addDefaultBackPermissionsToWorld(w);
metrics = new Metrics(this);
if (!metrics.isOptOut()) {
if (metrics.isEnabled()) {
getLogger().info("Starting Metrics. Opt-out using the global bStats config.");
} else {
getLogger().info("Metrics disabled per bStats config.");
@@ -441,7 +469,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
return pc.execute(cSender, commandLabel, args);
} catch (final Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
cSender.sendMessage(ChatColor.RED + "An internal error occurred while attempting to perform this command");
cSender.sendMessage(tl("internalError"));
return true;
}
}
@@ -867,6 +895,18 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
return potionMetaProvider;
}
private static void addDefaultBackPermissionsToWorld(World w) {
String permName = "essentials.back.into." + w.getName();
Permission p = Bukkit.getPluginManager().getPermission(permName);
if (p == null) {
p = new Permission(permName,
"Allows access to /back when the destination location is within world " + w.getName(),
PermissionDefault.TRUE);
Bukkit.getPluginManager().addPermission(p);
}
}
private static class EssentialsWorldListener implements Listener, Runnable {
private transient final IEssentials ess;
@@ -876,6 +916,8 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
@EventHandler(priority = EventPriority.LOW)
public void onWorldLoad(final WorldLoadEvent event) {
addDefaultBackPermissionsToWorld(event.getWorld());
ess.getJails().onReload();
ess.getWarps().reloadConfig();
for (IConf iConf : ((Essentials) ess).confList) {
@@ -901,4 +943,22 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
ess.reload();
}
}
private AbstractItemDb getItemDbFromConfig() {
final String setting = settings.getItemDbType();
if (setting.equalsIgnoreCase("json")) {
return new FlatItemDb(this);
} else if (setting.equalsIgnoreCase("csv")) {
return new LegacyItemDb(this);
} else {
VersionUtil.BukkitVersion version = VersionUtil.getServerBukkitVersion();
if (version.isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) {
return new FlatItemDb(this);
} else {
return new LegacyItemDb(this);
}
}
}
}
@@ -1,6 +1,8 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import net.ess3.api.IEssentials;
import org.bukkit.GameMode;
import org.bukkit.Material;
@@ -28,11 +30,12 @@ public class EssentialsBlockListener implements Listener {
// Do not rely on getItemInHand();
// http://leaky.bukkit.org/issues/663
final ItemStack is = LocationUtil.convertBlockToItem(event.getBlockPlaced());
if (is == null) {
return;
}
if (is.getType() == Material.MOB_SPAWNER && event.getItemInHand() != null && event.getPlayer() != null && event.getItemInHand().getType() == Material.MOB_SPAWNER) {
if (is.getType() == MaterialUtil.SPAWNER && event.getItemInHand() != null && event.getPlayer() != null && event.getItemInHand().getType() == MaterialUtil.SPAWNER) {
final BlockState blockState = event.getBlockPlaced().getState();
if (blockState instanceof CreatureSpawner) {
final CreatureSpawner spawner = (CreatureSpawner) blockState;
@@ -124,7 +124,7 @@ public class EssentialsEntityListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onEntityCombustByEntity(final EntityCombustByEntityEvent event) {
if (event.getCombuster() instanceof Arrow) {
if (event.getCombuster() instanceof Arrow && event.getEntity() instanceof Player) {
Arrow combuster = (Arrow) event.getCombuster();
if (combuster.getShooter() instanceof Player) {
final User srcCombuster = ess.getUser(((Player) combuster.getShooter()).getUniqueId());
@@ -6,14 +6,16 @@ import com.earth2me.essentials.textreader.TextInput;
import com.earth2me.essentials.textreader.TextPager;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import io.papermc.lib.PaperLib;
import net.ess3.api.IEssentials;
import net.ess3.nms.refl.ReflUtil;
import org.bukkit.BanEntry;
import org.bukkit.BanList;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
@@ -57,10 +59,10 @@ public class EssentialsPlayerListener implements Listener {
public void registerEvents() {
ess.getServer().getPluginManager().registerEvents(this, ess);
if (ReflUtil.getNmsVersionObject().isLowerThan(ReflUtil.V1_12_R1)) {
ess.getServer().getPluginManager().registerEvents(new PlayerListenerPre1_12(), ess);
} else {
if (isEntityPickupEvent()) {
ess.getServer().getPluginManager().registerEvents(new PlayerListener1_12(), ess);
} else {
ess.getServer().getPluginManager().registerEvents(new PlayerListenerPre1_12(), ess);
}
}
@@ -138,10 +140,10 @@ public class EssentialsPlayerListener implements Listener {
}
return;
}
final Location afk = user.getAfkPosition();
if (afk == null || !event.getTo().getWorld().equals(afk.getWorld()) || afk.distanceSquared(event.getTo()) > 9) {
user.updateActivityOnMove(true);
}
final Location afk = user.getAfkPosition();
if (afk == null || !event.getTo().getWorld().equals(afk.getWorld()) || afk.distanceSquared(event.getTo()) > 9) {
user.updateActivityOnMove(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
@@ -152,7 +154,12 @@ public class EssentialsPlayerListener implements Listener {
event.setQuitMessage(null);
} else if (ess.getSettings().isCustomQuitMessage() && event.getQuitMessage() != null) {
final Player player = event.getPlayer();
event.setQuitMessage(ess.getSettings().getCustomQuitMessage().replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName()));
final String msg = ess.getSettings().getCustomQuitMessage()
.replace("{PLAYER}", player.getDisplayName())
.replace("{USERNAME}", player.getName())
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()));
event.setQuitMessage(msg.isEmpty() ? null : msg);
}
user.startTransaction();
@@ -258,8 +265,11 @@ public class EssentialsPlayerListener implements Listener {
} else if (ess.getSettings().isCustomJoinMessage()) {
String msg = ess.getSettings().getCustomJoinMessage()
.replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName())
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers()));
ess.getServer().broadcastMessage(msg);
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers()))
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()));
if (!msg.isEmpty()) {
ess.getServer().broadcastMessage(msg);
}
} else if (ess.getSettings().allowSilentJoinQuit()) {
ess.getServer().broadcastMessage(message);
}
@@ -308,6 +318,9 @@ public class EssentialsPlayerListener implements Listener {
user.setGodModeEnabled(false);
ess.getLogger().log(Level.INFO, "Set god mode to false for {0} because they had it enabled without permission.", user.getName());
}
user.setConfirmingClearCommand(null);
user.getConfirmingPayments().clear();
user.stopTransaction();
}
@@ -350,7 +363,10 @@ public class EssentialsPlayerListener implements Listener {
}
// Makes the compass item ingame always point to the first essentials home. #EasterEgg
// EssentialsX: This can now optionally require a permission to enable, if set in the config.
private void updateCompass(final User user) {
if (ess.getSettings().isCompassTowardsHomePerm() && !user.isAuthorized("essentials.home.compass")) return;
Location loc = user.getHome(user.getLocation());
if (loc == null) {
loc = user.getBase().getBedSpawnLocation();
@@ -457,8 +473,7 @@ public class EssentialsPlayerListener implements Listener {
if (spyer.isSocialSpyEnabled() && !player.equals(spyer.getBase())) {
if (user.isMuted() && ess.getSettings().getSocialSpyListenMutedPlayers()) {
spyer.sendMessage(tl("socialSpyMutedPrefix") + player.getDisplayName() + ": " + event.getMessage());
}
else {
} else {
spyer.sendMessage(tl("socialSpyPrefix") + player.getDisplayName() + ": " + event.getMessage());
}
}
@@ -586,9 +601,9 @@ public class EssentialsPlayerListener implements Listener {
public void onPlayerInteract(final PlayerInteractEvent event) {
switch (event.getAction()) {
case RIGHT_CLICK_BLOCK:
if (!event.isCancelled() && event.getClickedBlock().getType() == Material.BED_BLOCK && ess.getSettings().getUpdateBedAtDaytime()) {
if (!event.isCancelled() && MaterialUtil.isBed(event.getClickedBlock().getType()) && ess.getSettings().getUpdateBedAtDaytime()) {
User player = ess.getUser(event.getPlayer());
if (player.isAuthorized("essentials.sethome.bed")) {
if (player.isAuthorized("essentials.sethome.bed") && player.getWorld().getEnvironment().equals(World.Environment.NORMAL)) {
player.getBase().setBedSpawnLocation(event.getClickedBlock().getLocation());
player.sendMessage(tl("bedSet", player.getLocation().getWorld().getName(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()));
}
@@ -605,7 +620,7 @@ public class EssentialsPlayerListener implements Listener {
case LEFT_CLICK_BLOCK:
if (event.getItem() != null && event.getItem().getType() != Material.AIR) {
final User user = ess.getUser(event.getPlayer());
if (user.hasPowerTools() && user.arePowerToolsEnabled() && usePowertools(user, event.getItem().getTypeId())) {
if (user.hasPowerTools() && user.arePowerToolsEnabled() && usePowertools(user, event.getItem().getType())) {
event.setCancelled(true);
}
}
@@ -628,7 +643,7 @@ public class EssentialsPlayerListener implements Listener {
while (LocationUtil.isBlockDamaging(loc.getWorld(), loc.getBlockX(), loc.getBlockY() - 1, loc.getBlockZ())) {
loc.setY(loc.getY() + 1d);
}
user.getBase().teleport(loc, TeleportCause.PLUGIN);
PaperLib.teleportAsync(user.getBase(), loc, TeleportCause.PLUGIN);
}
}
ess.scheduleSyncDelayedTask(new DelayedClickJumpTask());
@@ -639,8 +654,8 @@ public class EssentialsPlayerListener implements Listener {
}
}
private boolean usePowertools(final User user, final int id) {
final List<String> commandList = user.getPowertool(id);
private boolean usePowertools(final User user, final Material material) {
final List<String> commandList = user.getPowertool(material);
if (commandList == null || commandList.isEmpty()) {
return false;
}
@@ -714,6 +729,7 @@ public class EssentialsPlayerListener implements Listener {
} else if (clickedInventory != null && clickedInventory.getType() == InventoryType.PLAYER) {
if (ess.getSettings().isDirectHatAllowed() && event.getClick() == ClickType.LEFT && event.getSlot() == 39
&& event.getCursor().getType() != Material.AIR && event.getCursor().getType().getMaxDurability() == 0
&& !MaterialUtil.isSkull(event.getCursor().getType())
&& ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat")) {
event.setCancelled(true);
final PlayerInventory inv = (PlayerInventory) clickedInventory;
@@ -779,7 +795,16 @@ public class EssentialsPlayerListener implements Listener {
final User user = ess.getUser(event.getPlayer());
user.updateActivityOnInteract(true);
}
private static boolean isEntityPickupEvent() {
try {
Class.forName("org.bukkit.event.entity.EntityPickupItemEvent");
return true;
} catch (ClassNotFoundException ignored) {
return false;
}
}
private final class PlayerListenerPre1_12 implements Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
@@ -791,7 +816,7 @@ public class EssentialsPlayerListener implements Listener {
}
}
}
private final class PlayerListener1_12 implements Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
@@ -10,12 +10,17 @@ import org.bukkit.event.server.ServerListPingEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
public class EssentialsServerListener implements Listener {
private static List<String> ignoredSLPECallers = Arrays.asList(
".LegacyPingHandler.channelRead(" // CB responding to pings from pre-Netty clients
);
private final transient IEssentials ess;
private boolean unsupportedLogged = false;
private boolean npeWarned = false;
@@ -31,13 +36,13 @@ public class EssentialsServerListener implements Listener {
setSampleText = ReflUtil.getMethodCached(ServerListPingEvent.class, "setSampleText", List.class);
getSampleText = ReflUtil.getMethodCached(ServerListPingEvent.class, "getSampleText");
if (setSampleText != null && getSampleText != null) {
ess.getLogger().info("Using Paper 1.12+ ServerListPingEvent methods");
ess.getLogger().info("ServerListPingEvent: Paper 1.12.2 setSampleText API");
isPaperSample = true;
return;
}
}
ess.getLogger().info("Using Spigot 1.7.10+ ServerListPingEvent iterator");
ess.getLogger().info("ServerListPingEvent: Spigot iterator API");
isPaperSample = false;
}
@@ -46,22 +51,16 @@ public class EssentialsServerListener implements Listener {
if (isPaperSample) {
try {
List<String> playerNames = (List<String>) getSampleText.invoke(event, null);
Iterator<String> iterator = playerNames.iterator();
while (iterator.hasNext()) {
String player = iterator.next();
if (ess.getUser(player).isVanished()) {
iterator.remove();
}
}
playerNames.removeIf(player -> ess.getUser(player).isVanished());
setSampleText.invoke(event, playerNames);
} catch (IllegalAccessException | InvocationTargetException | ClassCastException e) {
if (!unsupportedLogged) {
if (!unsupportedLogged && shouldWarnSLPECaller(e)) {
ess.getLogger().log(Level.WARNING, "Unable to hide players from server list ping "
+ "using Paper 1.12+ method!", e);
+ "using Paper 1.12 method!", e);
unsupportedLogged = true;
}
} catch (NullPointerException e) {
if (!npeWarned) {
if (!npeWarned && shouldWarnSLPECaller(e)) {
npeWarned = true;
Exception ex = new Exception("A plugin has fired a ServerListPingEvent "
+ "without implementing Paper's methods. Point the author to https://git.io/v7Xzl.");
@@ -79,12 +78,38 @@ public class EssentialsServerListener implements Listener {
}
}
} catch (UnsupportedOperationException e) {
if (!unsupportedLogged) {
ess.getLogger().warning("Current server implementation does not support "
+ "hiding players from server list ping. Update or contact the maintainers.");
if (!unsupportedLogged && shouldWarnSLPECaller(e)) {
ess.getLogger().log(Level.WARNING, "Could not hide vanished players while handling " + event.getClass().getName(), e);
unsupportedLogged = true;
}
}
}
}
/**
* Should we warn about this SLPE caller, or should we silently ignore it?
* This checks against the ignoredSLPECallers strings, and if it matches one of those, we
* return false.
*
* @param throwable A throwable caught by a catch block
* @return Whether or not to send a warning about this particular caller
*/
private boolean shouldWarnSLPECaller(Throwable throwable) {
final int maxStackDepth = 20; // Limit the depth when searching through the stack trace
int depth = 0;
for (StackTraceElement element : throwable.getStackTrace()) {
depth++;
if (depth > maxStackDepth) {
break;
}
for (String ignoredString : ignoredSLPECallers) {
if (element.toString().contains(ignoredString)) {
return false; // We know about this error and should ignore it, so don't warn
}
}
}
return true; // We don't know for certain that we can ignore this, so warn just to be safe
}
}
@@ -93,7 +93,7 @@ public class I18n implements net.ess3.api.II18n {
}
messageFormatCache.put(format, messageFormat);
}
return messageFormat.format(objects);
return messageFormat.format(objects).replace(' ', ' '); // replace nbsp with a space
}
public void updateLocale(final String loc) {
@@ -5,6 +5,7 @@ import com.earth2me.essentials.signs.EssentialsSign;
import com.earth2me.essentials.textreader.IText;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.EventPriority;
@@ -95,7 +96,7 @@ public interface ISettings extends IConf {
int getProtectCreeperMaxHeight();
List<Integer> getProtectList(final String configName);
List<Material> getProtectList(final String configName);
boolean getProtectPreventSpawn(final String creatureName);
@@ -133,9 +134,12 @@ public interface ISettings extends IConf {
boolean isEcoDisabled();
@Deprecated
boolean isTradeInStacks(int id);
List<Integer> itemSpawnBlacklist();
boolean isTradeInStacks(Material type);
List<Material> itemSpawnBlacklist();
List<EssentialsSign> enabledSigns();
@@ -239,6 +243,8 @@ public interface ISettings extends IConf {
boolean ignoreColorsInMaxLength();
boolean hideDisplayNameInVanish();
int getMaxUserCacheCount();
boolean allowSilentJoinQuit();
@@ -306,4 +312,14 @@ public interface ISettings extends IConf {
List<String> getDefaultEnabledConfirmCommands();
boolean isConfirmCommandEnabledByDefault(String commandName);
boolean isCompassTowardsHomePerm();
boolean isAllowWorldInBroadcastworld();
String getItemDbType();
boolean isForceEnableRecipe();
boolean allowOldIdSigns();
}
@@ -4,6 +4,7 @@ import com.earth2me.essentials.commands.IEssentialsCommand;
import net.ess3.api.ITeleport;
import net.ess3.api.MaxMoneyException;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.math.BigDecimal;
@@ -35,7 +36,7 @@ public interface IUser {
boolean canAfford(BigDecimal value);
Boolean canSpawnItem(final int itemId);
Boolean canSpawnItem(final Material material);
void setLastLocation();
@@ -1,484 +0,0 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.IEssentials;
import net.ess3.nms.refl.ReflUtil;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.Material;
import org.bukkit.block.Banner;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.*;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.earth2me.essentials.I18n.tl;
public class ItemDb implements IConf, net.ess3.api.IItemDb {
private final transient IEssentials ess;
private final transient Map<String, Integer> items = new HashMap<>();
private final transient Map<ItemData, List<String>> names = new HashMap<>();
private final transient Map<ItemData, String> primaryName = new HashMap<>();
private final transient Map<String, Short> durabilities = new HashMap<>();
private final transient Map<String, String> nbtData = new HashMap<>();
private final transient ManagedFile file;
private final transient Pattern splitPattern = Pattern.compile("((.*)[:+',;.](\\d+))");
private final transient Pattern csvSplitPattern = Pattern.compile("(\"([^\"]*)\"|[^,]*)(,|$)");
public ItemDb(final IEssentials ess) {
this.ess = ess;
file = new ManagedFile("items.csv", ess);
}
@Override
public void reloadConfig() {
final List<String> lines = file.getLines();
if (lines.isEmpty()) {
return;
}
durabilities.clear();
items.clear();
names.clear();
primaryName.clear();
for (String line : lines) {
if (line.length() > 0 && line.charAt(0) == '#') {
continue;
}
String itemName = null;
int numeric = -1;
short data = 0;
String nbt = null;
int col = 0;
Matcher matcher = csvSplitPattern.matcher(line);
while (matcher.find()) {
String match = matcher.group(1);
if (StringUtils.stripToNull(match) == null) {
continue;
}
match = StringUtils.strip(match.trim(), "\"");
switch (col) {
case 0:
itemName = match.toLowerCase(Locale.ENGLISH);
break;
case 1:
numeric = Integer.parseInt(match);
break;
case 2:
data = Short.parseShort(match);
break;
case 3:
nbt = StringUtils.stripToNull(match);
break;
default:
continue;
}
col++;
}
// Invalid row
if (itemName == null || numeric < 0) {
continue;
}
durabilities.put(itemName, data);
items.put(itemName, numeric);
if (nbt != null) {
nbtData.put(itemName, nbt);
}
ItemData itemData = new ItemData(numeric, data);
if (names.containsKey(itemData)) {
List<String> nameList = names.get(itemData);
nameList.add(itemName);
} else {
List<String> nameList = new ArrayList<>();
nameList.add(itemName);
names.put(itemData, nameList);
primaryName.put(itemData, itemName);
}
}
for (List<String> nameList : names.values()) {
Collections.sort(nameList, LengthCompare.INSTANCE);
}
}
@Override
public ItemStack get(final String id, final int quantity) throws Exception {
final ItemStack retval = get(id.toLowerCase(Locale.ENGLISH));
retval.setAmount(quantity);
return retval;
}
@Override
public ItemStack get(final String id) throws Exception {
int itemid = 0;
String itemname;
short metaData = 0;
Matcher parts = splitPattern.matcher(id);
if (parts.matches()) {
itemname = parts.group(2);
metaData = Short.parseShort(parts.group(3));
} else {
itemname = id;
}
if (NumberUtil.isInt(itemname)) {
itemid = Integer.parseInt(itemname);
} else if (NumberUtil.isInt(id)) {
itemid = Integer.parseInt(id);
} else {
itemname = itemname.toLowerCase(Locale.ENGLISH);
}
if (itemid < 1) {
if (items.containsKey(itemname)) {
itemid = items.get(itemname);
if (durabilities.containsKey(itemname) && metaData == 0) {
metaData = durabilities.get(itemname);
}
} else if (Material.getMaterial(itemname.toUpperCase(Locale.ENGLISH)) != null) {
Material bMaterial = Material.getMaterial(itemname.toUpperCase(Locale.ENGLISH));
itemid = bMaterial.getId();
} else {
try {
Material bMaterial = Bukkit.getUnsafe().getMaterialFromInternalName(itemname.toLowerCase(Locale.ENGLISH));
itemid = bMaterial.getId();
} catch (Throwable throwable) {
throw new Exception(tl("unknownItemName", itemname), throwable);
}
}
}
if (itemid < 1) {
throw new Exception(tl("unknownItemName", itemname));
}
final Material mat = Material.getMaterial(itemid);
if (mat == null) {
throw new Exception(tl("unknownItemId", itemid));
}
ItemStack retval = new ItemStack(mat);
if (nbtData.containsKey(itemname)) {
String nbt = nbtData.get(itemname);
if (nbt.startsWith("*")) {
nbt = nbtData.get(nbt.substring(1));
}
retval = ess.getServer().getUnsafe().modifyItemStack(retval, nbt);
}
if (mat == Material.MOB_SPAWNER) {
if (metaData == 0) metaData = EntityType.PIG.getTypeId();
try {
retval = ess.getSpawnerProvider().setEntityType(retval, EntityType.fromId(metaData));
} catch (IllegalArgumentException e) {
throw new Exception("Can't spawn entity ID " + metaData + " from mob spawners.");
}
} else if (mat == Material.MONSTER_EGG) {
EntityType type;
try {
type = EntityType.fromId(metaData);
} catch (IllegalArgumentException e) {
throw new Exception("Can't spawn entity ID " + metaData + " from spawn eggs.");
}
retval = ess.getSpawnEggProvider().createEggItem(type);
} else if (mat.name().endsWith("POTION")
&& ReflUtil.getNmsVersionObject().isLowerThan(ReflUtil.V1_11_R1)) { // Only apply this to pre-1.11 as items.csv might only work in 1.11
retval = ess.getPotionMetaProvider().createPotionItem(mat, metaData);
} else {
retval.setDurability(metaData);
}
retval.setAmount(mat.getMaxStackSize());
return retval;
}
@Override
public List<ItemStack> getMatching(User user, String[] args) throws Exception {
List<ItemStack> is = new ArrayList<>();
if (args.length < 1) {
is.add(user.getItemInHand().clone());
} else if (args[0].equalsIgnoreCase("hand")) {
is.add(user.getItemInHand().clone());
} else if (args[0].equalsIgnoreCase("inventory") || args[0].equalsIgnoreCase("invent") || args[0].equalsIgnoreCase("all")) {
for (ItemStack stack : user.getBase().getInventory().getContents()) {
if (stack == null || stack.getType() == Material.AIR) {
continue;
}
is.add(stack.clone());
}
} else if (args[0].equalsIgnoreCase("blocks")) {
for (ItemStack stack : user.getBase().getInventory().getContents()) {
if (stack == null || stack.getTypeId() > 255 || stack.getType() == Material.AIR) {
continue;
}
is.add(stack.clone());
}
} else {
is.add(get(args[0]));
}
if (is.isEmpty() || is.get(0).getType() == Material.AIR) {
throw new Exception(tl("itemSellAir"));
}
return is;
}
@Override
public String names(ItemStack item) {
ItemData itemData = new ItemData(item.getTypeId(), item.getDurability());
List<String> nameList = names.get(itemData);
if (nameList == null) {
itemData = new ItemData(item.getTypeId(), (short) 0);
nameList = names.get(itemData);
if (nameList == null) {
return null;
}
}
if (nameList.size() > 15) {
nameList = nameList.subList(0, 14);
}
return StringUtil.joinList(", ", nameList);
}
@Override
public String name(ItemStack item) {
ItemData itemData = new ItemData(item.getTypeId(), item.getDurability());
String name = primaryName.get(itemData);
if (name == null) {
itemData = new ItemData(item.getTypeId(), (short) 0);
name = primaryName.get(itemData);
if (name == null) {
return null;
}
}
return name;
}
@Override
public String serialize(ItemStack is) {
String mat = is.getType().name();
if (is.getData().getData() != 0) {
mat = mat + ":" + is.getData().getData();
}
int quantity = is.getAmount();
StringBuilder sb = new StringBuilder(); // Add space AFTER you add something. We can trim at end.
sb.append(mat).append(" ").append(quantity).append(" ");
// ItemMeta applies to anything.
if (is.hasItemMeta()) {
ItemMeta meta = is.getItemMeta();
if (meta.hasDisplayName()) {
sb.append("name:").append(meta.getDisplayName().replaceAll(" ", "_")).append(" ");
}
if (meta.hasLore()) {
sb.append("lore:");
boolean first = true;
for (String s : meta.getLore()) {
// Add | before the line if it's not the first one. Easy but weird way
// to do this since we need each line separated by |
if (!first) {
sb.append("|");
}
first = false;
sb.append(s.replaceAll(" ", "_"));
}
sb.append(" ");
}
if (meta.hasEnchants()) {
for (Enchantment e : meta.getEnchants().keySet()) {
sb.append(e.getName().toLowerCase()).append(":").append(meta.getEnchantLevel(e)).append(" ");
}
}
Set<ItemFlag> flags = meta.getItemFlags();
if (flags != null && !flags.isEmpty()) {
sb.append("itemflags:");
boolean first = true;
for (ItemFlag flag : flags) {
if (!first) {
sb.append(",");
}
sb.append(flag.name());
first = false;
}
}
}
switch (is.getType()) {
case WRITTEN_BOOK:
// Everything from http://wiki.ess3.net/wiki/Item_Meta#Books in that order.
// Interesting as I didn't see a way to do pages or chapters.
BookMeta bookMeta = (BookMeta) is.getItemMeta();
if (bookMeta.hasTitle()) {
sb.append("title:").append(bookMeta.getTitle()).append(" ");
}
if (bookMeta.hasAuthor()) {
sb.append("author:").append(bookMeta.getAuthor()).append(" ");
}
// Only other thing it could have is lore but that's done up there ^^^
break;
case ENCHANTED_BOOK:
EnchantmentStorageMeta enchantmentStorageMeta = (EnchantmentStorageMeta) is.getItemMeta();
for (Enchantment e : enchantmentStorageMeta.getStoredEnchants().keySet()) {
sb.append(e.getName().toLowerCase()).append(":").append(enchantmentStorageMeta.getStoredEnchantLevel(e)).append(" ");
}
break;
case FIREWORK:
// Everything from http://wiki.ess3.net/wiki/Item_Meta#Fireworks in that order.
FireworkMeta fireworkMeta = (FireworkMeta) is.getItemMeta();
if (fireworkMeta.hasEffects()) {
for (FireworkEffect effect : fireworkMeta.getEffects()) {
if (effect.getColors() != null && !effect.getColors().isEmpty()) {
sb.append("color:");
boolean first = true;
for (Color c : effect.getColors()) {
if (!first) {
sb.append(","); // same thing as above.
}
sb.append(c.toString());
first = false;
}
sb.append(" ");
}
sb.append("shape: ").append(effect.getType().name()).append(" ");
if (effect.getFadeColors() != null && !effect.getFadeColors().isEmpty()) {
sb.append("fade:");
boolean first = true;
for (Color c : effect.getFadeColors()) {
if (!first) {
sb.append(","); // same thing as above.
}
sb.append(c.toString());
first = false;
}
sb.append(" ");
}
}
sb.append("power: ").append(fireworkMeta.getPower()).append(" ");
}
break;
case POTION:
Potion potion = Potion.fromItemStack(is);
for (PotionEffect e : potion.getEffects()) {
// long but needs to be effect:speed power:2 duration:120 in that order.
sb.append("splash:").append(potion.isSplash()).append(" ").append("effect:").append(e.getType().getName().toLowerCase()).append(" ").append("power:").append(e.getAmplifier()).append(" ").append("duration:").append(e.getDuration() / 20).append(" ");
}
break;
case SKULL_ITEM:
// item stack with meta
SkullMeta skullMeta = (SkullMeta) is.getItemMeta();
if (skullMeta != null && skullMeta.hasOwner()) {
sb.append("player:").append(skullMeta.getOwner()).append(" ");
}
break;
case LEATHER_HELMET:
case LEATHER_CHESTPLATE:
case LEATHER_LEGGINGS:
case LEATHER_BOOTS:
LeatherArmorMeta leatherArmorMeta = (LeatherArmorMeta) is.getItemMeta();
int rgb = leatherArmorMeta.getColor().asRGB();
sb.append("color:").append(rgb).append(" ");
break;
case BANNER:
BannerMeta bannerMeta = (BannerMeta) is.getItemMeta();
if (bannerMeta != null) {
int basecolor = bannerMeta.getBaseColor().getColor().asRGB();
sb.append("basecolor:").append(basecolor).append(" ");
for (org.bukkit.block.banner.Pattern p : bannerMeta.getPatterns()) {
String type = p.getPattern().getIdentifier();
int color = p.getColor().getColor().asRGB();
sb.append(type).append(",").append(color).append(" ");
}
}
break;
case SHIELD:
// Hacky fix for accessing Shield meta - https://github.com/drtshock/Essentials/pull/745#issuecomment-234843795
BlockStateMeta shieldMeta = (BlockStateMeta) is.getItemMeta();
Banner shieldBannerMeta = (Banner) shieldMeta.getBlockState();
int basecolor = shieldBannerMeta.getBaseColor().getColor().asRGB();
sb.append("basecolor:").append(basecolor).append(" ");
for (org.bukkit.block.banner.Pattern p : shieldBannerMeta.getPatterns()) {
String type = p.getPattern().getIdentifier();
int color = p.getColor().getColor().asRGB();
sb.append(type).append(",").append(color).append(" ");
}
break;
}
return sb.toString().trim().replaceAll("§", "&");
}
@Override
public Collection<String> listNames() {
return primaryName.values();
}
static class ItemData {
final private int itemNo;
final private short itemData;
ItemData(final int itemNo, final short itemData) {
this.itemNo = itemNo;
this.itemData = itemData;
}
public int getItemNo() {
return itemNo;
}
public short getItemData() {
return itemData;
}
@Override
public int hashCode() {
return (31 * itemNo) ^ itemData;
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (!(o instanceof ItemData)) {
return false;
}
ItemData pairo = (ItemData) o;
return this.itemNo == pairo.getItemNo() && this.itemData == pairo.getItemData();
}
}
static class LengthCompare implements java.util.Comparator<String> {
private static final LengthCompare INSTANCE = new LengthCompare();
public LengthCompare() {
super();
}
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
}
@@ -3,7 +3,9 @@ package com.earth2me.essentials;
import com.earth2me.essentials.textreader.BookInput;
import com.earth2me.essentials.textreader.BookPager;
import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.google.common.base.Joiner;
import net.ess3.api.IEssentials;
@@ -33,8 +35,8 @@ import static com.earth2me.essentials.I18n.tl;
public class MetaItemStack {
private static final Map<String, DyeColor> colorMap = new HashMap<String, DyeColor>();
private static final Map<String, FireworkEffect.Type> fireworkShape = new HashMap<String, FireworkEffect.Type>();
private static final Map<String, DyeColor> colorMap = new HashMap<>();
private static final Map<String, FireworkEffect.Type> fireworkShape = new HashMap<>();
static {
for (DyeColor color : DyeColor.values()) {
@@ -97,10 +99,6 @@ public class MetaItemStack {
completePotion = true;
}
private boolean isPotion(Material type) {
return type.name().endsWith("POTION");
}
public boolean canSpawn(final IEssentials ess) {
try {
ess.getServer().getUnsafe().modifyItemStack(stack.clone(), "{}");
@@ -158,16 +156,7 @@ public class MetaItemStack {
return;
}
Material banner = null;
Material shield = null;
try {
// 1.8
banner = Material.valueOf("BANNER");
// 1.9
shield = Material.valueOf("SHIELD");
} catch(IllegalArgumentException ignored){}
Material WRITTEN_BOOK = EnumUtil.getMaterial("WRITTEN_BOOK");
if (split.length > 1 && split[0].equalsIgnoreCase("name") && hasMetaPermission(sender, "name", false, true, ess)) {
final String displayName = FormatUtil.replaceFormat(split[1].replace('_', ' '));
@@ -183,18 +172,18 @@ public class MetaItemStack {
meta.setLore(lore);
stack.setItemMeta(meta);
} else if (split[0].equalsIgnoreCase("unbreakable") && hasMetaPermission(sender, "unbreakable", false, true, ess)) {
boolean value = split.length > 1 ? Boolean.valueOf(split[1]) : true;
boolean value = split.length > 1 ? Boolean.valueOf(split[1]) : true;
setUnbreakable(stack, value);
} else if (split.length > 1 && (split[0].equalsIgnoreCase("player") || split[0].equalsIgnoreCase("owner")) && stack.getType() == Material.SKULL_ITEM && hasMetaPermission(sender, "head", false, true, ess)) {
if (stack.getDurability() == 3) {
} else if (split.length > 1 && (split[0].equalsIgnoreCase("player") || split[0].equalsIgnoreCase("owner")) && hasMetaPermission(sender, "head", false, true, ess)) {
if (MaterialUtil.isPlayerHead(stack.getType(), stack.getDurability())) {
final String owner = split[1];
final SkullMeta meta = (SkullMeta) stack.getItemMeta();
meta.setOwner(owner);
meta.setOwningPlayer(ess.getServer().getOfflinePlayer(owner));
stack.setItemMeta(meta);
} else {
throw new Exception(tl("onlyPlayerSkulls"));
}
} else if (split.length > 1 && split[0].equalsIgnoreCase("book") && stack.getType() == Material.WRITTEN_BOOK && (hasMetaPermission(sender, "book", true, true, ess) || hasMetaPermission(sender, "chapter-" + split[1].toLowerCase(Locale.ENGLISH), true, true, ess))) {
} else if (split.length > 1 && split[0].equalsIgnoreCase("book") && stack.getType() == WRITTEN_BOOK && (hasMetaPermission(sender, "book", true, true, ess) || hasMetaPermission(sender, "chapter-" + split[1].toLowerCase(Locale.ENGLISH), true, true, ess))) {
final BookMeta meta = (BookMeta) stack.getItemMeta();
final IText input = new BookInput("book", true, ess);
final BookPager pager = new BookPager(input);
@@ -202,42 +191,42 @@ public class MetaItemStack {
List<String> pages = pager.getPages(split[1]);
meta.setPages(pages);
stack.setItemMeta(meta);
} else if (split.length > 1 && split[0].equalsIgnoreCase("author") && stack.getType() == Material.WRITTEN_BOOK && hasMetaPermission(sender, "author", false, true, ess)) {
} else if (split.length > 1 && split[0].equalsIgnoreCase("author") && stack.getType() == WRITTEN_BOOK && hasMetaPermission(sender, "author", false, true, ess)) {
final String author = FormatUtil.replaceFormat(split[1]);
final BookMeta meta = (BookMeta) stack.getItemMeta();
meta.setAuthor(author);
stack.setItemMeta(meta);
} else if (split.length > 1 && split[0].equalsIgnoreCase("title") && stack.getType() == Material.WRITTEN_BOOK && hasMetaPermission(sender, "title", false, true, ess)) {
} else if (split.length > 1 && split[0].equalsIgnoreCase("title") && stack.getType() == WRITTEN_BOOK && hasMetaPermission(sender, "title", false, true, ess)) {
final String title = FormatUtil.replaceFormat(split[1].replace('_', ' '));
final BookMeta meta = (BookMeta) stack.getItemMeta();
meta.setTitle(title);
stack.setItemMeta(meta);
} else if (split.length > 1 && split[0].equalsIgnoreCase("power") && stack.getType() == Material.FIREWORK && hasMetaPermission(sender, "firework-power", false, true, ess)) {
} else if (split.length > 1 && split[0].equalsIgnoreCase("power") && (MaterialUtil.isFirework(stack.getType()))&& hasMetaPermission(sender, "firework-power", false, true, ess)) {
final int power = NumberUtil.isInt(split[1]) ? Integer.parseInt(split[1]) : 0;
final FireworkMeta meta = (FireworkMeta) stack.getItemMeta();
meta.setPower(power > 3 ? 4 : power);
stack.setItemMeta(meta);
} else if (split.length > 1 && split[0].equalsIgnoreCase("itemflags") && hasMetaPermission(sender, "itemflags", false, true, ess)) {
addItemFlags(string);
} else if (stack.getType() == Material.FIREWORK) {//WARNING - Meta for fireworks will be ignored after this point.
} else if (MaterialUtil.isFirework(stack.getType())) {//WARNING - Meta for fireworks will be ignored after this point.
addFireworkMeta(sender, false, string, ess);
} else if (isPotion(stack.getType())) { //WARNING - Meta for potions will be ignored after this point.
} else if (MaterialUtil.isPotion(stack.getType())) { //WARNING - Meta for potions will be ignored after this point.
addPotionMeta(sender, false, string, ess);
} else if (banner != null && stack.getType() == banner) { //WARNING - Meta for banners will be ignored after this point.
} else if (MaterialUtil.isBanner(stack.getType())) {
//WARNING - Meta for banners will be ignored after this point.
addBannerMeta(sender, false, string, ess);
} else if (shield != null && stack.getType() == shield) { //WARNING - Meta for shields will be ignored after this point.
addBannerMeta(sender, false, string, ess);
} else if (split.length > 1 && (split[0].equalsIgnoreCase("color") || split[0].equalsIgnoreCase("colour")) && (stack.getType() == Material.LEATHER_BOOTS || stack.getType() == Material.LEATHER_CHESTPLATE || stack.getType() == Material.LEATHER_HELMET || stack.getType() == Material.LEATHER_LEGGINGS)) {
} else if (split.length > 1 && (split[0].equalsIgnoreCase("color") || split[0].equalsIgnoreCase("colour")) && MaterialUtil.isLeatherArmor(stack.getType())) {
final String[] color = split[1].split("(\\||,)");
if(color.length == 1 && (NumberUtil.isInt(color[0]) || color[0].startsWith("#"))) { // int rgb and hex
if (color.length == 1 && (NumberUtil.isInt(color[0]) || color[0].startsWith("#"))) {
// Either integer or hexadecimal
final LeatherArmorMeta meta = (LeatherArmorMeta) stack.getItemMeta();
String input = color[0];
if(input.startsWith("#")) {
if (input.startsWith("#")) { // Hex
meta.setColor(Color.fromRGB(
Integer.valueOf(input.substring(1, 3), 16),
Integer.valueOf(input.substring(3, 5), 16),
Integer.valueOf(input.substring(5, 7), 16)));
} else {
} else { // Int
meta.setColor(Color.fromRGB(Integer.parseInt(input)));
}
stack.setItemMeta(meta);
@@ -281,7 +270,7 @@ public class MetaItemStack {
}
public void addFireworkMeta(final CommandSource sender, final boolean allowShortName, final String string, final IEssentials ess) throws Exception {
if (stack.getType() == Material.FIREWORK) {
if (MaterialUtil.isFirework(stack.getType())) {
final String[] split = splitPattern.split(string, 2);
if (split.length < 2) {
return;
@@ -353,7 +342,7 @@ public class MetaItemStack {
}
public void addPotionMeta(final CommandSource sender, final boolean allowShortName, final String string, final IEssentials ess) throws Exception {
if (isPotion(stack.getType())) {
if (MaterialUtil.isPotion(stack.getType())) {
final String[] split = splitPattern.split(string, 2);
if (split.length < 2) {
@@ -482,13 +471,13 @@ public class MetaItemStack {
}
public void addBannerMeta(final CommandSource sender, final boolean allowShortName, final String string, final IEssentials ess) throws Exception {
if (stack.getType() == Material.BANNER && string != null) {
if (MaterialUtil.isBanner(stack.getType()) && !stack.getType().toString().equals("SHIELD") && string != null) {
final String[] split = splitPattern.split(string, 2);
if (split.length < 2) {
throw new Exception(tl("invalidBanner", split[1]));
}
PatternType patternType = null;
try {
patternType = PatternType.valueOf(split[0]);
@@ -506,7 +495,7 @@ public class MetaItemStack {
}
stack.setItemMeta(meta);
} else if (stack.getType() == Material.SHIELD && string != null) {
} else if (stack.getType().toString().equals("SHIELD") && string != null) {
final String[] split = splitPattern.split(string, 2);
if (split.length < 2) {
@@ -554,22 +543,36 @@ public class MetaItemStack {
}
}
private static int bukkitUnbreakableSupport = -1;
private static Method spigotMethod;
private static Method setUnbreakableMethod;
private void setUnbreakable(ItemStack is, boolean unbreakable) {
ItemMeta meta = is.getItemMeta();
try {
if (spigotMethod == null) {
spigotMethod = meta.getClass().getDeclaredMethod("spigot");
spigotMethod.setAccessible(true);
if (bukkitUnbreakableSupport == -1) {
try {
ItemMeta.class.getDeclaredMethod("setUnbreakable", boolean.class);
bukkitUnbreakableSupport = 1;
} catch (NoSuchMethodException | SecurityException ex) {
bukkitUnbreakableSupport = 0;
}
}
Object itemStackSpigot = spigotMethod.invoke(meta);
if (setUnbreakableMethod == null) {
setUnbreakableMethod = itemStackSpigot.getClass().getDeclaredMethod("setUnbreakable", Boolean.TYPE);
setUnbreakableMethod.setAccessible(true);
if (bukkitUnbreakableSupport == 1) {
meta.setUnbreakable(unbreakable);
} else {
if (spigotMethod == null) {
spigotMethod = meta.getClass().getDeclaredMethod("spigot");
spigotMethod.setAccessible(true);
}
Object itemStackSpigot = spigotMethod.invoke(meta);
if (setUnbreakableMethod == null) {
setUnbreakableMethod = itemStackSpigot.getClass().getDeclaredMethod("setUnbreakable", Boolean.TYPE);
setUnbreakableMethod.setAccessible(true);
}
setUnbreakableMethod.invoke(itemStackSpigot, unbreakable);
}
setUnbreakableMethod.invoke(itemStackSpigot, unbreakable);
is.setItemMeta(meta);
} catch (Throwable t) {
t.printStackTrace();
@@ -75,6 +75,14 @@ public enum Mob {
HUSK("Husk", Enemies.ENEMY, "HUSK"),
ILLUSIONER("Illusioner", Enemies.ENEMY, "ILLUSIONER"),
PARROT("Parrot", Enemies.NEUTRAL, "PARROT"),
TURTLE("Turtle", Enemies.NEUTRAL, "TURTLE"),
PHANTOM("Phantom", Enemies.ENEMY, "PHANTOM"),
COD("Cod", Enemies.NEUTRAL, "COD"),
SALMON("Salmon", Enemies.NEUTRAL, "SALMON"),
PUFFERFISH("Pufferfish", Enemies.NEUTRAL, "PUFFERFISH"),
TROPICAL_FISH("TropicalFish", Enemies.NEUTRAL, "TROPICAL_FISH"),
DROWNED("Drowned", Enemies.ENEMY, "DROWNED"),
DOLPHIN("Dolphin", Enemies.NEUTRAL, "DOLPHIN"),
;
public static final Logger logger = Logger.getLogger("Essentials");
@@ -1,6 +1,7 @@
package com.earth2me.essentials;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.StringUtil;
import org.bukkit.DyeColor;
import org.bukkit.Material;
@@ -53,9 +54,9 @@ public enum MobData {
BAY_HORSE("bay", EntityType.HORSE, Horse.Color.BROWN, true),
BROWN_HORSE("brown", EntityType.HORSE, Horse.Color.BROWN, false),
SADDLE_HORSE("saddle", EntityType.HORSE, Data.HORSESADDLE, true),
GOLD_ARMOR_HORSE("goldarmor", EntityType.HORSE, Material.GOLD_BARDING, true),
DIAMOND_ARMOR_HORSE("diamondarmor", EntityType.HORSE, Material.DIAMOND_BARDING, true),
ARMOR_HORSE("armor", EntityType.HORSE, Material.IRON_BARDING, true),
GOLD_ARMOR_HORSE("goldarmor", EntityType.HORSE, EnumUtil.getMaterial("GOLDEN_HORSE_ARMOR", "GOLD_BARDING"), true),
DIAMOND_ARMOR_HORSE("diamondarmor", EntityType.HORSE, EnumUtil.getMaterial("DIAMOND_HORSE_ARMOR", "DIAMOND_BARDING"), true),
ARMOR_HORSE("armor", EntityType.HORSE, EnumUtil.getMaterial("IRON_HORSE_ARMOR", "IRON_BARDING"), true),
SIAMESE_CAT("siamese", EntityType.OCELOT, Ocelot.Type.SIAMESE_CAT, true),
WHITE_CAT("white", EntityType.OCELOT, Ocelot.Type.SIAMESE_CAT, false),
RED_CAT("red", EntityType.OCELOT, Ocelot.Type.RED_CAT, true),
@@ -66,12 +67,12 @@ public enum MobData {
BABY_ZOMBIE("baby", EntityType.ZOMBIE.getEntityClass(), Data.BABYZOMBIE, true),
ADULT_ZOMBIE("adult", EntityType.ZOMBIE.getEntityClass(), Data.ADULTZOMBIE, true),
DIAMOND_SWORD_ZOMBIE("diamondsword", EntityType.ZOMBIE.getEntityClass(), Material.DIAMOND_SWORD, true),
GOLD_SWORD_ZOMBIE("goldsword", EntityType.ZOMBIE.getEntityClass(), Material.GOLD_SWORD, true),
GOLD_SWORD_ZOMBIE("goldsword", EntityType.ZOMBIE.getEntityClass(), EnumUtil.getMaterial("GOLDEN_SWORD", "GOLD_SWORD"), true),
IRON_SWORD_ZOMBIE("ironsword", EntityType.ZOMBIE.getEntityClass(), Material.IRON_SWORD, true),
STONE_SWORD_ZOMBIE("stonesword", EntityType.ZOMBIE.getEntityClass(), Material.STONE_SWORD, false),
SWORD_ZOMBIE("sword", EntityType.ZOMBIE.getEntityClass(), Material.STONE_SWORD, true),
DIAMOND_SWORD_SKELETON("diamondsword", EntityType.SKELETON, Material.DIAMOND_SWORD, true),
GOLD_SWORD_SKELETON("goldsword", EntityType.SKELETON, Material.GOLD_SWORD, true),
GOLD_SWORD_SKELETON("goldsword", EntityType.SKELETON, EnumUtil.getMaterial("GOLDEN_SWORD", "GOLD_SWORD"), true),
IRON_SWORD_SKELETON("ironsword", EntityType.SKELETON, Material.IRON_SWORD, true),
STONE_SWORD_SKELETON("stonesword", EntityType.SKELETON, Material.STONE_SWORD, false),
SWORD_SKELETON("sword", EntityType.SKELETON, Material.STONE_SWORD, true),
@@ -95,6 +96,18 @@ public enum MobData {
BLUE_PARROT("blue", EntityType.PARROT, Parrot.Variant.BLUE, true),
CYAN_PARROT("cyan", EntityType.PARROT, Parrot.Variant.CYAN, true),
GRAY_PARROT("gray", EntityType.PARROT, Parrot.Variant.GRAY, true),
KOB_TROPICAL_FISH("kob", EntityType.TROPICAL_FISH, TropicalFish.Pattern.KOB, true),
SUNSTREAK_TROPICAL_FISH("sunstreak", EntityType.TROPICAL_FISH, TropicalFish.Pattern.SUNSTREAK, true),
SNOOPER_TROPICAL_FISH("snooper", EntityType.TROPICAL_FISH, TropicalFish.Pattern.SNOOPER, true),
DASHER_TROPICAL_FISH("dasher", EntityType.TROPICAL_FISH, TropicalFish.Pattern.DASHER, true),
BRINELY_TROPICAL_FISH("brinely", EntityType.TROPICAL_FISH, TropicalFish.Pattern.BRINELY, true),
SPOTTY_TROPICAL_FISH("spotty", EntityType.TROPICAL_FISH, TropicalFish.Pattern.SPOTTY, true),
FLOPPER_TROPICAL_FISH("flopper", EntityType.TROPICAL_FISH, TropicalFish.Pattern.FLOPPER, true),
STRIPEY_TROPICAL_FISH("stripey", EntityType.TROPICAL_FISH, TropicalFish.Pattern.STRIPEY, true),
GLITTER_TROPICAL_FISH("glitter", EntityType.TROPICAL_FISH, TropicalFish.Pattern.GLITTER, true),
BLOCKFISH_TROPICAL_FISH("blockfish", EntityType.TROPICAL_FISH, TropicalFish.Pattern.BLOCKFISH, true),
BETTY_TROPICAL_FISH("betty", EntityType.TROPICAL_FISH, TropicalFish.Pattern.BETTY, true),
CLAYFISH_TROPICAL_FISH("clayfish", EntityType.TROPICAL_FISH, TropicalFish.Pattern.CLAYFISH, true);
;
@@ -252,6 +265,8 @@ public enum MobData {
}
} else if (this.value instanceof Parrot.Variant) {
((Parrot) spawned).setVariant((Parrot.Variant) this.value);
} else if (this.value instanceof TropicalFish.Pattern) {
((TropicalFish) spawned).setPattern((TropicalFish.Pattern) this.value);
}
}
}
@@ -8,7 +8,9 @@ import org.bukkit.advancement.AdvancementProgress;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.PistonMoveReaction;
import org.bukkit.block.data.BlockData;
import org.bukkit.conversations.Conversation;
import org.bukkit.conversations.ConversationAbandonedEvent;
import org.bukkit.entity.*;
@@ -25,6 +27,8 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.util.BoundingBox;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
import java.lang.reflect.InvocationTargetException;
@@ -145,6 +149,10 @@ public class OfflinePlayer implements Player {
return -1;
}
public BlockFace getFacing() {
return null;
}
@Override
public boolean performCommand(String string) {
return false;
@@ -200,24 +208,34 @@ public class OfflinePlayer implements Player {
return Collections.emptyList();
}
@Override
public Block getTargetBlock(HashSet<Byte> hs, int i) {
return null;
}
@Override
public Block getTargetBlock(Set<Material> mat, int i) {
return null;
}
@Override
public List<Block> getLastTwoTargetBlocks(HashSet<Byte> hs, int i) {
public List<Block> getLastTwoTargetBlocks(Set<Material> mat, int i) {
return Collections.emptyList();
}
@Override
public List<Block> getLastTwoTargetBlocks(Set<Material> mat, int i) {
return Collections.emptyList();
public Block getTargetBlockExact(int maxDistance) {
return null;
}
@Override
public Block getTargetBlockExact(int maxDistance, FluidCollisionMode fluidCollisionMode) {
return null;
}
@Override
public RayTraceResult rayTraceBlocks(double maxDistance) {
return null;
}
@Override
public RayTraceResult rayTraceBlocks(double maxDistance, FluidCollisionMode fluidCollisionMode) {
return null;
}
@Override
@@ -243,6 +261,15 @@ public class OfflinePlayer implements Player {
return server;
}
@Override
public boolean isPersistent() {
return false;
}
@Override
public void setPersistent(boolean persistent) {
}
public Vector getMomentum() {
return getVelocity();
}
@@ -481,7 +508,8 @@ public class OfflinePlayer implements Player {
}
@Override
public void sendBlockChange(Location lctn, int i, byte b) {
public void sendBlockChange(Location loc, BlockData block) {
}
@Override
@@ -653,6 +681,31 @@ public class OfflinePlayer implements Player {
public void setPlayerListName(String name) {
}
@Override
public String getPlayerListHeader() {
return null;
}
@Override
public String getPlayerListFooter() {
return null;
}
@Override
public void setPlayerListHeader(String header) {
}
@Override
public void setPlayerListFooter(String footer) {
}
@Override
public void setPlayerListHeaderFooter(String header, String footer) {
}
@Override
public String getPlayerListName() {
return name;
@@ -734,6 +787,21 @@ public class OfflinePlayer implements Player {
public void setBedSpawnLocation(Location lctn, boolean force) {
}
@Override
public boolean sleep(Location location, boolean force) {
return false;
}
@Override
public void wakeup(boolean setSpawnLocation) {
}
@Override
public Location getBedLocation() {
return null;
}
@Override
public void playEffect(EntityEffect ee) {
}
@@ -742,10 +810,20 @@ public class OfflinePlayer implements Player {
public void hidePlayer(Player player) {
}
@Override
public void hidePlayer(Plugin plugin, Player player) {
}
@Override
public void showPlayer(Player player) {
}
@Override
public void showPlayer(Plugin plugin, Player player) {
}
@Override
public boolean canSee(Player player) {
return false;
@@ -920,6 +998,26 @@ public class OfflinePlayer implements Player {
return 0;
}
@Override
public boolean discoverRecipe(NamespacedKey recipe) {
return false;
}
@Override
public int discoverRecipes(Collection<NamespacedKey> recipes) {
return 0;
}
@Override
public boolean undiscoverRecipe(NamespacedKey recipe) {
return false;
}
@Override
public int undiscoverRecipes(Collection<NamespacedKey> recipes) {
return 0;
}
@Override
public boolean hasLineOfSight(Entity entity) {
return false;
@@ -1195,6 +1293,21 @@ public class OfflinePlayer implements Player {
public void setGliding(boolean b) {
}
@Override
public boolean isSwimming() {
return false;
}
@Override
public void setSwimming(boolean swimming) {
}
@Override
public boolean isRiptiding() {
return false;
}
@Override
public void setAI(boolean b) {
}
@@ -1412,6 +1525,11 @@ public class OfflinePlayer implements Player {
return null;
}
@Override
public int getClientViewDistance() {
return 0;
}
@Override
public String getLocale() {
return null;
@@ -1459,6 +1577,11 @@ public class OfflinePlayer implements Player {
return 0;
}
@Override
public BoundingBox getBoundingBox() {
return null;
}
@Override
public List<Entity> getPassengers() {
return null;
@@ -1478,4 +1601,8 @@ public class OfflinePlayer implements Player {
public PistonMoveReaction getPistonMoveReaction() {
return null;
}
@Override
public void updateCommands() {
}
}
@@ -11,8 +11,8 @@ import java.util.Set;
public class Potions {
private static final Map<String, PotionEffectType> POTIONS = new HashMap<String, PotionEffectType>();
private static final Map<String, PotionEffectType> ALIASPOTIONS = new HashMap<String, PotionEffectType>();
private static final Map<String, PotionEffectType> POTIONS = new HashMap<>();
private static final Map<String, PotionEffectType> ALIASPOTIONS = new HashMap<>();
static {
@@ -1,23 +1,24 @@
package com.earth2me.essentials;
import com.earth2me.essentials.api.IItemDb;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.signs.EssentialsSign;
import com.earth2me.essentials.signs.Signs;
import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.event.EventPriority;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
@@ -37,7 +38,6 @@ public class Settings implements net.ess3.api.ISettings {
private final transient EssentialsConf config;
private static final Logger logger = Logger.getLogger("Essentials");
private final transient IEssentials ess;
private boolean metricsEnabled = true;
public Settings(IEssentials ess) {
this.ess = ess;
@@ -432,6 +432,9 @@ public class Settings implements net.ess3.api.ISettings {
mFormat = "§r".concat(mFormat);
chatFormats.put(group, mFormat);
}
if (isDebug()) {
ess.getLogger().info(String.format("Found format '%s' for group '%s'", mFormat, group));
}
return mFormat;
}
@@ -533,19 +536,29 @@ public class Settings implements net.ess3.api.ISettings {
currencyFormat = _getCurrencyFormat();
unprotectedSigns = _getUnprotectedSign();
defaultEnabledConfirmCommands = _getDefaultEnabledConfirmCommands();
isCompassTowardsHomePerm = _isCompassTowardsHomePerm();
isAllowWorldInBroadcastworld = _isAllowWorldInBroadcastworld();
itemDbType = _getItemDbType();
forceEnableRecipe = _isForceEnableRecipe();
allowOldIdSigns = _allowOldIdSigns();
}
private List<Integer> itemSpawnBl = new ArrayList<Integer>();
void _lateLoadItemSpawnBlacklist() {
itemSpawnBl = _getItemSpawnBlacklist();
}
private List<Material> itemSpawnBl = new ArrayList<>();
@Override
public List<Integer> itemSpawnBlacklist() {
public List<Material> itemSpawnBlacklist() {
return itemSpawnBl;
}
private List<Integer> _getItemSpawnBlacklist() {
final List<Integer> epItemSpwn = new ArrayList<Integer>();
if (ess.getItemDb() == null) {
logger.log(Level.FINE, "Aborting ItemSpawnBL read, itemDB not yet loaded.");
private List<Material> _getItemSpawnBlacklist() {
final List<Material> epItemSpwn = new ArrayList<>();
final IItemDb itemDb = ess.getItemDb();
if (itemDb == null || !itemDb.isReady()) {
logger.log(Level.FINE, "Skipping item spawn blacklist read; item DB not yet loaded.");
return epItemSpwn;
}
for (String itemName : config.getString("item-spawn-blacklist", "").split(",")) {
@@ -554,10 +567,10 @@ public class Settings implements net.ess3.api.ISettings {
continue;
}
try {
final ItemStack iStack = ess.getItemDb().get(itemName);
epItemSpwn.add(iStack.getTypeId());
final ItemStack iStack = itemDb.get(itemName);
epItemSpwn.add(iStack.getType());
} catch (Exception ex) {
logger.log(Level.SEVERE, tl("unknownItemInList", itemName, "item-spawn-blacklist"));
logger.log(Level.SEVERE, tl("unknownItemInList", itemName, "item-spawn-blacklist"), ex);
}
}
return epItemSpwn;
@@ -643,10 +656,17 @@ public class Settings implements net.ess3.api.ISettings {
// #easteregg
@Override
@Deprecated
public boolean isTradeInStacks(int id) {
return config.getBoolean("trade-in-stacks-" + id, false);
}
// #easteregg
@Override
public boolean isTradeInStacks(Material type) {
return config.getBoolean("trade-in-stacks." + type.toString().toLowerCase().replace("_", ""), false);
}
// #easteregg
private boolean economyDisabled = false;
@@ -665,19 +685,27 @@ public class Settings implements net.ess3.api.ISettings {
}
@Override
public List<Integer> getProtectList(final String configName) {
final List<Integer> list = new ArrayList<Integer>();
public List<Material> getProtectList(final String configName) {
final List<Material> list = new ArrayList<>();
for (String itemName : config.getString(configName, "").split(",")) {
itemName = itemName.trim();
if (itemName.isEmpty()) {
continue;
}
ItemStack itemStack;
try {
itemStack = ess.getItemDb().get(itemName);
list.add(itemStack.getTypeId());
} catch (Exception ex) {
Material mat = EnumUtil.getMaterial(itemName.toUpperCase());
if (mat == null) {
try {
ItemStack itemStack = ess.getItemDb().get(itemName);
mat = itemStack.getType();
} catch (Exception ignored) {}
}
if (mat == null) {
logger.log(Level.SEVERE, tl("unknownItemInList", itemName, configName));
} else {
list.add(mat);
}
}
return list;
@@ -1091,6 +1119,11 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("ignore-colors-in-max-nick-length", false);
}
@Override
public boolean hideDisplayNameInVanish() {
return config.getBoolean("hide-displayname-in-vanish", false);
}
private boolean allowSilentJoin;
public boolean _allowSilentJoinQuit() {
@@ -1292,7 +1325,12 @@ public class Settings implements net.ess3.api.ISettings {
if (isCommandCooldownsEnabled()) {
for (Entry<Pattern, Long> entry : this.commandCooldowns.entrySet()) {
// Check if label matches current pattern (command-cooldown in config)
if (entry.getKey().matcher(label).matches()) {
boolean matches = entry.getKey().matcher(label).matches();
if (isDebug()) {
ess.getLogger().info(String.format("Checking command '%s' against cooldown '%s': %s", label, entry.getKey(), matches));
}
if (matches) {
return entry;
}
}
@@ -1334,24 +1372,8 @@ public class Settings implements net.ess3.api.ISettings {
DecimalFormat currencyFormat = new DecimalFormat(currencyFormatString, decimalFormatSymbols);
currencyFormat.setRoundingMode(RoundingMode.FLOOR);
// Updates NumberUtil#PRETTY_FORMAT field so that all of Essentials
// can follow a single format.
try {
Field field = NumberUtil.class.getDeclaredField("PRETTY_FORMAT");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, currencyFormat);
modifiersField.setAccessible(false);
field.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException e) {
ess.getLogger().severe("Failed to apply custom currency format: " + e.getMessage());
if (isDebug()) {
e.printStackTrace();
}
}
// Updates NumberUtil#PRETTY_FORMAT field so that all of Essentials can follow a single format.
NumberUtil.internalSetPrettyFormat(currencyFormat);
return currencyFormat;
}
@@ -1439,4 +1461,59 @@ public class Settings implements net.ess3.api.ISettings {
public boolean isConfirmCommandEnabledByDefault(String commandName) {
return getDefaultEnabledConfirmCommands().contains(commandName.toLowerCase());
}
private boolean isCompassTowardsHomePerm;
private boolean _isCompassTowardsHomePerm() {
return config.getBoolean("compass-towards-home-perm", false);
}
@Override
public boolean isCompassTowardsHomePerm() {
return isCompassTowardsHomePerm;
}
private boolean isAllowWorldInBroadcastworld;
private boolean _isAllowWorldInBroadcastworld() {
return config.getBoolean("allow-world-in-broadcastworld", false);
}
@Override
public boolean isAllowWorldInBroadcastworld() {
return isAllowWorldInBroadcastworld;
}
private String itemDbType; // #EasterEgg - admins can manually switch items provider if they want
private String _getItemDbType() {
return config.getString("item-db-type", "auto");
}
@Override
public String getItemDbType() {
return itemDbType;
}
private boolean forceEnableRecipe; // https://github.com/EssentialsX/Essentials/issues/1397
private boolean _isForceEnableRecipe() {
return config.getBoolean("force-enable-recipe", false);
}
@Override
public boolean isForceEnableRecipe() {
return forceEnableRecipe;
}
private boolean allowOldIdSigns;
private boolean _allowOldIdSigns() {
return config.getBoolean("allow-old-id-signs", false);
}
@Override
public boolean allowOldIdSigns() {
return allowOldIdSigns;
}
}
@@ -2,6 +2,7 @@ package com.earth2me.essentials;
import com.earth2me.essentials.Mob.MobException;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.IEssentials;
@@ -19,6 +20,13 @@ import static com.earth2me.essentials.I18n.tl;
public class SpawnMob {
private static final Material GOLDEN_HELMET = EnumUtil.getMaterial("GOLDEN_HELMET", "GOLD_HELMET");
private static final Material GOLDEN_CHESTPLATE = EnumUtil.getMaterial("GOLDEN_CHESTPLATE", "GOLD_CHESTPLATE");
private static final Material GOLDEN_LEGGINGS = EnumUtil.getMaterial("GOLDEN_LEGGINGS", "GOLD_LEGGINGS");
private static final Material GOLDEN_BOOTS = EnumUtil.getMaterial("GOLDEN_BOOTS", "GOLD_BOOTS");
private static final Material GOLDEN_SWORD = EnumUtil.getMaterial("GOLDEN_SWORD", "GOLD_SWORD");
public static String mobList(final User user) {
final Set<String> mobList = Mob.getMobList();
final Set<String> availableList = new HashSet<String>();
@@ -191,16 +199,16 @@ public class SpawnMob {
invent.setChestplate(new ItemStack(Material.DIAMOND_CHESTPLATE, 1));
invent.setHelmet(new ItemStack(Material.DIAMOND_HELMET, 1));
} else if (inputData.contains("gold")) {
invent.setBoots(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.GOLD_LEGGINGS, 1));
invent.setChestplate(new ItemStack(Material.GOLD_CHESTPLATE, 1));
invent.setHelmet(new ItemStack(Material.GOLD_HELMET, 1));
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
invent.setLeggings(new ItemStack(GOLDEN_LEGGINGS, 1));
invent.setChestplate(new ItemStack(GOLDEN_CHESTPLATE, 1));
invent.setHelmet(new ItemStack(GOLDEN_HELMET, 1));
} else if (inputData.contains("leather")) {
invent.setBoots(new ItemStack(Material.LEATHER_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.LEATHER_LEGGINGS, 1));
invent.setChestplate(new ItemStack(Material.LEATHER_CHESTPLATE, 1));
invent.setHelmet(new ItemStack(Material.LEATHER_HELMET, 1));
} else {
} else if (inputData.contains("iron")) {
invent.setBoots(new ItemStack(Material.IRON_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.IRON_LEGGINGS, 1));
invent.setChestplate(new ItemStack(Material.IRON_CHESTPLATE, 1));
@@ -228,7 +236,7 @@ public class SpawnMob {
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(Material.BOW, 1));
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
invent.setBoots(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
invent.setBootsDropChance(0.0f);
}
@@ -237,10 +245,10 @@ public class SpawnMob {
setVillager(zombie, false);
final EntityEquipment invent = zombie.getEquipment();
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(Material.GOLD_SWORD, 1));
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(GOLDEN_SWORD, 1));
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
invent.setBoots(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
invent.setBootsDropChance(0.0f);
}
@@ -249,7 +257,7 @@ public class SpawnMob {
setVillager(zombie, false);
final EntityEquipment invent = zombie.getEquipment();
invent.setBoots(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
invent.setBootsDropChance(0.0f);
}
@@ -2,8 +2,12 @@ package com.earth2me.essentials;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.LocationUtil;
import io.papermc.lib.PaperLib;
import net.ess3.api.IEssentials;
import net.ess3.api.ITeleport;
import net.ess3.api.IUser;
import net.ess3.api.events.UserWarpEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerRespawnEvent;
@@ -16,7 +20,7 @@ import java.util.GregorianCalendar;
import static com.earth2me.essentials.I18n.tl;
public class Teleport implements net.ess3.api.ITeleport {
public class Teleport implements ITeleport {
private final IUser teleportOwner;
private final IEssentials ess;
private TimedTeleport timedTeleport;
@@ -47,7 +51,7 @@ public class Teleport implements net.ess3.api.ITeleport {
final long earliestLong = earliestTime.getTimeInMillis();
// When was the last teleportPlayer used?
final Long lastTime = teleportOwner.getLastTeleportTimestamp();
final long lastTime = teleportOwner.getLastTeleportTimestamp();
if (lastTime > time.getTimeInMillis()) {
// This is to make sure time didn't get messed up on last teleportPlayer use.
@@ -122,21 +126,21 @@ public class Teleport implements net.ess3.api.ITeleport {
if (LocationUtil.isBlockUnsafeForUser(teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
if (ess.getSettings().isTeleportSafetyEnabled()) {
if (ess.getSettings().isForceDisableTeleportSafety()) {
teleportee.getBase().teleport(loc, cause);
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
} else {
teleportee.getBase().teleport(LocationUtil.getSafeDestination(ess, teleportee, loc), cause);
PaperLib.teleportAsync(teleportee.getBase(), LocationUtil.getSafeDestination(ess, teleportee, loc), cause);
}
} else {
throw new Exception(tl("unsafeTeleportDestination", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
}
} else {
if (ess.getSettings().isForceDisableTeleportSafety()) {
teleportee.getBase().teleport(loc, cause);
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
} else {
if (ess.getSettings().isTeleportToCenterLocation()) {
loc = LocationUtil.getRoundedDestination(loc);
}
teleportee.getBase().teleport(loc, cause);
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
}
}
}
@@ -229,7 +233,7 @@ public class Teleport implements net.ess3.api.ITeleport {
initTimer((long) (delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
}
protected void respawnNow(IUser teleportee, TeleportCause cause) throws Exception {
void respawnNow(IUser teleportee, TeleportCause cause) throws Exception {
final Player player = teleportee.getBase();
Location bed = player.getBedSpawnLocation();
if (bed != null) {
@@ -247,6 +251,13 @@ public class Teleport implements net.ess3.api.ITeleport {
//The warp function is a wrapper used to teleportPlayer a player to a /warp
@Override
public void warp(IUser teleportee, String warp, Trade chargeFor, TeleportCause cause) throws Exception {
UserWarpEvent event = new UserWarpEvent(teleportee, warp, chargeFor);
Bukkit.getServer().getPluginManager().callEvent(event);
if(event.isCancelled()) {
return;
}
warp = event.getWarp();
Location loc = ess.getWarps().getWarp(warp);
teleportee.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
if (!teleportee.equals(teleportOwner)) {
@@ -16,9 +16,9 @@ public class TimedTeleport implements Runnable {
private final IEssentials ess;
private final Teleport teleport;
private final UUID timer_teleportee;
private int timer_task = -1;
private final long timer_started; // time this task was initiated
private final long timer_delay; // how long to delay the teleportPlayer
private int timer_task;
private final long timer_started; // time this task was initiated
private final long timer_delay; // how long to delay the teleportPlayer
private double timer_health;
// note that I initially stored a clone of the location for reference, but...
// when comparing locations, I got incorrect mismatches (rounding errors, looked like)
@@ -32,8 +32,7 @@ public class TimedTeleport implements Runnable {
private final Trade timer_chargeFor;
private final TeleportCause timer_cause;
public TimedTeleport(IUser user, IEssentials ess, Teleport teleport, long delay, IUser teleportUser, ITarget target, Trade chargeFor, TeleportCause cause, boolean respawn) {
TimedTeleport(IUser user, IEssentials ess, Teleport teleport, long delay, IUser teleportUser, ITarget target, Trade chargeFor, TeleportCause cause, boolean respawn) {
this.teleportOwner = user;
this.ess = ess;
this.teleport = teleport;
@@ -111,8 +110,7 @@ public class TimedTeleport implements Runnable {
if (timer_chargeFor != null) {
timer_chargeFor.charge(teleportOwner);
}
} catch (Exception ex) {
}
} catch (Exception ignored) {}
} catch (Exception ex) {
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
@@ -124,7 +122,7 @@ public class TimedTeleport implements Runnable {
}
//If we need to cancelTimer a pending teleportPlayer call this method
public void cancelTimer(boolean notifyUser) {
void cancelTimer(boolean notifyUser) {
if (timer_task == -1) {
return;
}
@@ -8,6 +8,7 @@ import com.earth2me.essentials.register.payment.Methods;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
import net.ess3.api.events.AfkStatusChangeEvent;
@@ -18,6 +19,7 @@ import net.ess3.nms.refl.ReflUtil;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
@@ -26,12 +28,7 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -222,8 +219,19 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
}
@Override
public Boolean canSpawnItem(final int itemId) {
return !ess.getSettings().itemSpawnBlacklist().contains(itemId);
public Boolean canSpawnItem(final Material material) {
if (ess.getSettings().permissionBasedItemSpawn()) {
final String name = material.toString().toLowerCase(Locale.ENGLISH).replace("_", "");
if (isAuthorized("essentials.itemspawn.item-all") || isAuthorized("essentials.itemspawn.item-" + name)) return true;
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
final int id = material.getId();
if (isAuthorized("essentials.itemspawn.item-" + id)) return true;
}
}
return isAuthorized("essentials.itemspawn.exempt") || !ess.getSettings().itemSpawnBlacklist().contains(material);
}
@Override
@@ -359,7 +367,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
}
public String getDisplayName() {
return super.getBase().getDisplayName() == null ? super.getBase().getName() : super.getBase().getDisplayName();
return super.getBase().getDisplayName() == null || (ess.getSettings().hideDisplayNameInVanish() && isHidden()) ? super.getBase().getName() : super.getBase().getDisplayName();
}
@Override
@@ -871,7 +879,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
* Returns the {@link ItemStack} in the main hand or off-hand. If the main hand is empty then the offhand item is returned - also nullable.
*/
public ItemStack getItemInHand() {
if (ReflUtil.getNmsVersionObject().isLowerThan(ReflUtil.V1_9_R1)) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
return getBase().getInventory().getItemInHand();
} else {
PlayerInventory inventory = getBase().getInventory();
@@ -7,6 +7,7 @@ import net.ess3.api.IEssentials;
import net.ess3.api.InvalidWorldException;
import net.ess3.api.MaxMoneyException;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -231,26 +232,35 @@ public abstract class UserData extends PlayerExtension implements IConf {
config.save();
}
private List<Integer> unlimited;
private List<Material> unlimited;
private List<Integer> _getUnlimited() {
return config.getIntegerList("unlimited");
private List<Material> _getUnlimited() {
List<Material> retlist = new ArrayList<>();
List<String> configList = config.getStringList("unlimited");
for(String s : configList) {
Material mat = Material.matchMaterial(s);
if(mat != null) {
retlist.add(mat);
}
}
return retlist;
}
public List<Integer> getUnlimited() {
public List<Material> getUnlimited() {
return unlimited;
}
public boolean hasUnlimited(ItemStack stack) {
return unlimited.contains(stack.getTypeId());
return unlimited.contains(stack.getType());
}
public void setUnlimited(ItemStack stack, boolean state) {
if (unlimited.contains(stack.getTypeId())) {
unlimited.remove(Integer.valueOf(stack.getTypeId()));
if (unlimited.contains(stack.getType())) {
unlimited.remove(stack.getType());
}
if (state) {
unlimited.add(stack.getTypeId());
unlimited.add(stack.getType());
}
config.setProperty("unlimited", unlimited);
config.save();
@@ -262,7 +272,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
if (config.isConfigurationSection("powertools")) {
return config.getConfigurationSection("powertools").getValues(false);
}
return new HashMap<String, Object>();
return new HashMap<>();
}
public void clearAllPowertools() {
@@ -273,19 +283,19 @@ public abstract class UserData extends PlayerExtension implements IConf {
@SuppressWarnings("unchecked")
public List<String> getPowertool(ItemStack stack) {
return (List<String>) powertools.get("" + stack.getTypeId());
return (List<String>) powertools.get(stack.getType().name().toLowerCase(Locale.ENGLISH));
}
@SuppressWarnings("unchecked")
public List<String> getPowertool(int id) {
return (List<String>) powertools.get("" + id);
public List<String> getPowertool(Material material) {
return (List<String>) powertools.get(material.name().toLowerCase(Locale.ENGLISH));
}
public void setPowertool(ItemStack stack, List<String> commandList) {
if (commandList == null || commandList.isEmpty()) {
powertools.remove("" + stack.getTypeId());
powertools.remove(stack.getType().name().toLowerCase(Locale.ENGLISH));
} else {
powertools.put("" + stack.getTypeId(), commandList);
powertools.put(stack.getType().name().toLowerCase(Locale.ENGLISH), commandList);
}
config.setProperty("powertools", powertools);
config.save();
@@ -467,10 +477,11 @@ public abstract class UserData extends PlayerExtension implements IConf {
}
public void setIgnoredPlayer(IUser user, boolean set) {
final String entry = user.getName().toLowerCase(Locale.ENGLISH);
if (set) {
ignoredPlayers.add(user.getName().toLowerCase(Locale.ENGLISH));
if (!ignoredPlayers.contains(entry)) ignoredPlayers.add(entry);
} else {
ignoredPlayers.remove(user.getName().toLowerCase(Locale.ENGLISH));
ignoredPlayers.remove(entry);
}
setIgnoredPlayers(ignoredPlayers);
}
@@ -6,13 +6,11 @@ import net.ess3.api.InvalidNameException;
import net.ess3.api.InvalidWorldException;
import org.bukkit.Location;
import org.bukkit.Server;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.earth2me.essentials.I18n.tl;
@@ -57,6 +55,11 @@ public class Warps implements IConf, net.ess3.api.IWarps {
@Override
public void setWarp(String name, Location loc) throws Exception {
setWarp(null, name, loc);
}
@Override
public void setWarp(IUser user, String name, Location loc) throws Exception {
String filename = StringUtil.sanitizeFileName(name);
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
if (conf == null) {
@@ -69,13 +72,28 @@ public class Warps implements IConf, net.ess3.api.IWarps {
}
conf.setProperty(null, loc);
conf.setProperty("name", name);
if (user != null) conf.setProperty("lastowner", user.getBase().getUniqueId().toString());
try {
conf.saveWithError();
} catch (IOException ex) {
throw new IOException(tl("invalidWarpName"));
}
}
@Override
public UUID getLastOwner(String warp) throws WarpNotFoundException {
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
if (conf == null) {
throw new WarpNotFoundException();
}
UUID uuid = null;
try {
uuid = UUID.fromString(conf.getString("lastowner"));
}
catch (Exception ex) {}
return uuid;
}
@Override
public void removeWarp(String name) throws Exception {
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
@@ -1,6 +1,7 @@
package com.earth2me.essentials;
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import com.earth2me.essentials.utils.VersionUtil;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
@@ -21,57 +22,62 @@ public class Worth implements IConf {
config.load();
}
public BigDecimal getPrice(ItemStack itemStack) {
String itemname = itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
/**
* Get the value of an item stack from the config.
*
* @param ess The Essentials instance.
* @param itemStack The item stack to look up in the config.
* @return The price from the config.
*/
public BigDecimal getPrice(IEssentials ess, ItemStack itemStack) {
BigDecimal result;
//First check for matches with item name
String itemname = itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
// Check for matches with data value from stack
// Note that we always default to BigDecimal.ONE.negate(), equivalent to -1
result = config.getBigDecimal("worth." + itemname + "." + itemStack.getDurability(), BigDecimal.ONE.negate());
// Check for matches with data value 0
if (result.signum() < 0) {
final ConfigurationSection itemNameMatch = config.getConfigurationSection("worth." + itemname);
if (itemNameMatch != null && itemNameMatch.getKeys(false).size() == 1) {
result = config.getBigDecimal("worth." + itemname + ".0", BigDecimal.ONE.negate());
}
}
// Check for matches with data value wildcard
if (result.signum() < 0) {
result = config.getBigDecimal("worth." + itemname + ".*", BigDecimal.ONE.negate());
}
// Check for matches with item name alone
if (result.signum() < 0) {
result = config.getBigDecimal("worth." + itemname, BigDecimal.ONE.negate());
}
//Now we should check for item ID
if (result.signum() < 0) {
result = config.getBigDecimal("worth." + itemStack.getTypeId() + "." + itemStack.getDurability(), BigDecimal.ONE.negate());
}
if (result.signum() < 0) {
final ConfigurationSection itemNumberMatch = config.getConfigurationSection("worth." + itemStack.getTypeId());
if (itemNumberMatch != null && itemNumberMatch.getKeys(false).size() == 1) {
result = config.getBigDecimal("worth." + itemStack.getTypeId() + ".0", BigDecimal.ONE.negate());
}
}
if (result.signum() < 0) {
result = config.getBigDecimal("worth." + itemStack.getTypeId() + ".*", BigDecimal.ONE.negate());
}
if (result.signum() < 0) {
result = config.getBigDecimal("worth." + itemStack.getTypeId(), BigDecimal.ONE.negate());
}
//This is to match the old worth syntax
if (result.signum() < 0) {
result = config.getBigDecimal("worth-" + itemStack.getTypeId(), BigDecimal.ONE.negate());
}
if (result.signum() < 0) {
return null;
}
return result;
}
/**
* Get the amount of items to be sold from a player's inventory.
*
* @param ess The Essentials instance.
* @param user The user attempting to sell the item.
* @param is A stack of the item to search the inventory for.
* @param args The amount to try to sell.
* @param isBulkSell Whether or not to try and bulk sell all items.
* @return The amount of items to sell from the player's inventory.
* @throws Exception Thrown if trying to sell air or an invalid amount.
*/
public int getAmount(IEssentials ess, User user, ItemStack is, String[] args, boolean isBulkSell) throws Exception {
if (is == null || is.getType() == Material.AIR) {
throw new Exception(tl("itemSellAir"));
}
int id = is.getTypeId();
int amount = 0;
if (args.length > 1) {
@@ -86,7 +92,7 @@ public class Worth implements IConf {
}
boolean stack = args.length > 1 && args[1].endsWith("s");
boolean requireStack = ess.getSettings().isTradeInStacks(id);
boolean requireStack = ess.getSettings().isTradeInStacks(is.getType());
if (requireStack && !stack) {
throw new Exception(tl("itemMustBeStacked"));
@@ -123,14 +129,23 @@ public class Worth implements IConf {
return amount;
}
public void setPrice(ItemStack itemStack, double price) {
if (itemStack.getType().getData() == null) {
config.setProperty("worth." + itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", ""), price);
} else {
/**
* Set the price of an item and save it to the config.
*
* @param ess The Essentials instance.
* @param itemStack A stack of the item to save.
* @param price The new price of the item.
*/
public void setPrice(IEssentials ess, ItemStack itemStack, double price) {
String path = "worth." + itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
// Spigot 1.13+ throws an exception if a 1.13+ plugin even *attempts* to do set data.
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01) && itemStack.getType().getData() == null) {
// Bukkit-bug: getDurability still contains the correct value, while getData().getData() is 0.
config.setProperty("worth." + itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "") + "." + itemStack.getDurability(), price);
path = path + "." + itemStack.getDurability();
}
config.removeProperty("worth-" + itemStack.getTypeId());
config.setProperty(path, price);
config.save();
}
@@ -8,6 +8,7 @@ import com.earth2me.essentials.utils.StringUtil;
import com.google.common.base.Charsets;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
import org.bukkit.entity.Player;
import java.io.File;
import java.math.BigDecimal;
@@ -18,7 +19,7 @@ import java.util.logging.Logger;
/**
* Instead of using this api directly, we recommend to use the register plugin: http://bit.ly/RegisterMethod
* You should use Vault instead of directly using this class.
*/
public class Economy {
public Economy() {
@@ -64,7 +65,24 @@ public class Economy {
if (name == null) {
throw new RuntimeException("Economy username cannot be null");
}
return ess.getUser(name);
User user = ess.getUser(name);
if (user == null) {
/*
Attempt lookup using UUID - this prevents balance resets when accessing economy
via Vault during player join.
See: https://github.com/EssentialsX/Essentials/issues/2400
*/
Player player = ess.getServer().getPlayerExact(name);
if (player != null) {
user = ess.getUser(player.getUniqueId());
if (user != null) {
logger.info(String.format("[Economy] Found player %s by UUID %s but not by their actual name - they may have changed their username", name, player.getUniqueId().toString()));
}
}
}
return user;
}
/**
@@ -78,7 +96,14 @@ public class Economy {
*/
@Deprecated
public static double getMoney(String name) throws UserDoesNotExistException {
return getMoneyExact(name).doubleValue();
BigDecimal exactAmount = getMoneyExact(name);
double amount = exactAmount.doubleValue();
if (new BigDecimal(amount).compareTo(exactAmount) > 0) {
// closest double is bigger than the exact amount
// -> get the previous double value to not return more money than the user has
amount = Math.nextAfter(amount, Double.NEGATIVE_INFINITY);
}
return amount;
}
public static BigDecimal getMoneyExact(String name) throws UserDoesNotExistException {
@@ -178,7 +203,7 @@ public class Economy {
* Divides the balance of a user by a value
*
* @param name Name of the user
* @param value The balance is divided by this value
* @param amount The balance is divided by this value
*
* @throws UserDoesNotExistException If a user by that name does not exists
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
@@ -202,7 +227,7 @@ public class Economy {
* Multiplies the balance of a user by a value
*
* @param name Name of the user
* @param value The balance is multiplied by this value
* @param amount The balance is multiplied by this value
*
* @throws UserDoesNotExistException If a user by that name does not exists
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
@@ -1,24 +1,163 @@
package com.earth2me.essentials.api;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.IEssentials;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
public interface IItemDb {
ItemStack get(final String name, final int quantity) throws Exception;
/**
* Create a stack from the given name with the given quantity.
*
* @param name Item name to look up in the database
* @param quantity Quantity of the item stack
* @return The requested item stack
* @throws Exception if the item stack cannot be created
*/
default ItemStack get(final String name, final int quantity) throws Exception {
final ItemStack stack = get(name.toLowerCase(Locale.ENGLISH));
stack.setAmount(quantity);
return stack;
}
/**
* Create a stack from the given name with the maximum stack size for that material.
*
* @param name Item name to look up in the database
* @return The requested item stack with the maximum stack size
* @throws Exception if the item stack cannot be created
*/
ItemStack get(final String name) throws Exception;
String names(ItemStack item);
/**
* Get a comma-separated string list of up to 15 aliases for the given stack.
*
* @param item Item stack whose names to find
* @return Comma-separated list of up to 15 item names
*/
default String names(ItemStack item) {
List<String> nameList = nameList(item);
if (nameList.size() > 15) {
nameList = nameList.subList(0, 14);
}
return StringUtil.joinList(", ", nameList);
};
/**
* Get a List of all aliases for the given item stack.
*
* @param item Item stack whose names to find
* @return List of all names
*/
List<String> nameList(ItemStack item);
/**
* Get the primary name for the given item stack.
*
* @param item Item stack whose name to find
* @return Primary name of the item
*/
String name(ItemStack item);
/**
* Get all stacks in a given User's inventory that matches the given arguments.
*
* @param user The user with the player inventory to search
* @param args Either an item name, or one of the following:
* hand (default), inventory/invent/all, blocks
* @return A List of all matching ItemStacks
* @throws Exception if the given args are invalid or no blocks are found
*/
List<ItemStack> getMatching(User user, String[] args) throws Exception;
/**
* Serialise an ItemStack into a format that can be decoded by
* {@link #get(String) get} and
* {@link com.earth2me.essentials.MetaItemStack#parseStringMeta(CommandSource, boolean, String[], int, IEssentials)} MetaItemStack#parseStringMeta}.
* Used to encode items for kits.
*
* @param is Stack to serialise
* @return Serialised stack
*/
String serialize(ItemStack is);
/**
* Return names recognised by the database, intended for tab-completion.
*
* @return Collection of all item names
*/
Collection<String> listNames();
/**
* Get the material matching the given legacy ID. Used for conversion from item IDs to
* modern names.
*
* @param id Legacy ID of material to find
* @return Updated material
*/
@Deprecated
default Material getFromLegacyId(int id) {
return getFromLegacy(id, (byte) 0);
}
/**
* Get the legacy ID for the given material.
*
* @param material Material to look up
* @return Legacy ID of given material
* @throws Exception if the ID cannot be looked up
* @deprecated Item IDs are no longer supported.
*/
@Deprecated
int getLegacyId(Material material) throws Exception;
/**
* Convert colon syntax (eg. "13", "1:5") legacy IDs to Material. Used for conversion from
* item IDs to modern names.
*
* @param item Legacy ID in colon syntax.
* @return
*/
default Material getFromLegacy(String item) {
final String[] split = item.split(":");
final int id = Integer.parseInt(split[0]);
byte damage = 0;
if (split.length > 1 && NumberUtil.isInt(split[1])) {
damage = Byte.parseByte(split[1]);
}
return getFromLegacy(id, damage);
}
/**
* Convert legacy ID and damage value to Material. Used for conversion from item IDs to
* modern names.
*
* @param id Legacy ID
* @param damage Damage value
* @return Material
*/
default Material getFromLegacy(final int id, final byte damage) {
return MaterialUtil.convertFromLegacy(id, damage);
}
/**
* Check whether the item database is loaded and ready for use.
*
* @return Whether items have finished loading
*/
boolean isReady();
}
@@ -1,11 +1,13 @@
package com.earth2me.essentials.api;
import com.earth2me.essentials.IConf;
import com.earth2me.essentials.IUser;
import com.earth2me.essentials.commands.WarpNotFoundException;
import org.bukkit.Location;
import java.io.File;
import java.util.Collection;
import java.util.UUID;
public interface IWarps extends IConf {
@@ -54,6 +56,25 @@ public interface IWarps extends IConf {
*/
void setWarp(String name, Location loc) throws Exception;
/**
* Set a warp
*
* @param user - User of warp
* @param name - Name of warp
* @param loc - Location of warp
*
* @throws Exception
*/
void setWarp(IUser user, String name, Location loc) throws Exception;
/**
* Gets Lastowner UUID
*
* @param name - Name of warp
*
* @throws WarpNotFoundException
*/
UUID getLastOwner(String warp) throws WarpNotFoundException;
/**
* Check to see if the file is empty
*
@@ -79,6 +79,7 @@ public class Commandafk extends EssentialsCommand {
if (!msg.isEmpty()) {
ess.broadcastMessage(user, msg);
}
user.setDisplayNick(); // Set this again after toggling
}
@Override
@@ -17,9 +17,17 @@ public class Commandback extends EssentialsCommand {
if (user.getLastLocation() == null) {
throw new Exception(tl("noLocationFound"));
}
if (user.getWorld() != user.getLastLocation().getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + user.getLastLocation().getWorld().getName())) {
throw new Exception(tl("noPerm", "essentials.worlds." + user.getLastLocation().getWorld().getName()));
String lastWorldName = user.getLastLocation().getWorld().getName();
if (user.getWorld() != user.getLastLocation().getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + lastWorldName)) {
throw new Exception(tl("noPerm", "essentials.worlds." + lastWorldName));
}
if (!user.isAuthorized("essentials.back.into." + lastWorldName)) {
throw new Exception(tl("noPerm", "essentials.back.into." + lastWorldName));
}
final Trade charge = new Trade(this.getName(), ess);
charge.isAffordableFor(user);
user.getTeleport().back(charge);
@@ -6,6 +6,7 @@ import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.FormatUtil;
import org.bukkit.BanList;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.List;
@@ -14,7 +15,6 @@ import java.util.logging.Level;
import static com.earth2me.essentials.I18n.tl;
//TODO: Add kick to online players matching ip ban.
public class Commandbanip extends EssentialsCommand {
public Commandbanip() {
super("banip");
@@ -51,9 +51,17 @@ public class Commandbanip extends EssentialsCommand {
banReason = tl("defaultBanReason");
}
String banDisplay = tl("banFormat", banReason, senderName);
ess.getServer().getBanList(BanList.Type.IP).addBan(ipAddress, banReason, null, senderName);
server.getLogger().log(Level.INFO, tl("playerBanIpAddress", senderName, ipAddress, banReason));
for (Player player : ess.getServer().getOnlinePlayers()) {
if (player.getAddress().getAddress().getHostAddress().equalsIgnoreCase(ipAddress)) {
player.kickPlayer(banDisplay);
}
}
ess.broadcastMessage("essentials.banip.notify", tl("playerBanIpAddress", senderName, ipAddress, banReason));
}
@@ -27,6 +27,8 @@ public class Commandbigtree extends EssentialsCommand {
tree = TreeType.BIG_TREE;
} else if (args.length > 0 && args[0].equalsIgnoreCase("jungle")) {
tree = TreeType.JUNGLE;
} else if (args.length > 0 && args[0].equalsIgnoreCase("darkoak")) {
tree = TreeType.DARK_OAK;
} else {
throw new NotEnoughArgumentsException();
}
@@ -44,7 +46,7 @@ public class Commandbigtree extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
if (args.length == 1) {
return Lists.newArrayList("redwood", "tree", "jungle");
return Lists.newArrayList("redwood", "tree", "jungle", "darkoak");
} else {
return Collections.emptyList();
}
@@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.User;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import com.earth2me.essentials.utils.EnumUtil;
import com.google.common.collect.Lists;
import org.bukkit.Material;
import org.bukkit.Server;
@@ -15,11 +16,13 @@ import static com.earth2me.essentials.I18n.tl;
public class Commandbook extends EssentialsCommand {
private static final Material WRITABLE_BOOK = EnumUtil.getMaterial("WRITABLE_BOOK", "BOOK_AND_QUILL");
public Commandbook() {
super("book");
}
//TODO: Translate this
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
final ItemStack item = user.getItemInHand();
@@ -45,7 +48,7 @@ public class Commandbook extends EssentialsCommand {
}
} else {
if (isAuthor(bmeta, player) || user.isAuthorized("essentials.book.others")) {
ItemStack newItem = new ItemStack(Material.BOOK_AND_QUILL, item.getAmount());
ItemStack newItem = new ItemStack(WRITABLE_BOOK, item.getAmount());
newItem.setItemMeta(bmeta);
InventoryWorkaround.setItemInMainHand(user.getBase(), newItem);
user.sendMessage(tl("editBookContents"));
@@ -53,7 +56,7 @@ public class Commandbook extends EssentialsCommand {
throw new Exception(tl("denyBookEdit"));
}
}
} else if (item.getType() == Material.BOOK_AND_QUILL) {
} else if (item.getType() == WRITABLE_BOOK) {
BookMeta bmeta = (BookMeta) item.getItemMeta();
if (!user.isAuthorized("essentials.book.author")) {
bmeta.setAuthor(player);
@@ -27,7 +27,25 @@ public class Commandbroadcastworld extends EssentialsCommand {
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
sendBroadcast(user.getWorld().getName(), user.getDisplayName(), getFinalArg(args, 0));
World world = user.getWorld();
String message = getFinalArg(args, 0);
if (args.length < 1) {
throw new NotEnoughArgumentsException();
} else if (args.length > 1 && ess.getSettings().isAllowWorldInBroadcastworld()) {
World argWorld = ess.getWorld(args[0]);
if (argWorld != null) {
world = argWorld;
message = getFinalArg(args, 1);
}
}
if (world == null) {
world = user.getWorld();
message = getFinalArg(args, 0);
}
sendBroadcast(world.getName(), user.getDisplayName(), message);
}
@Override
@@ -43,6 +61,9 @@ public class Commandbroadcastworld extends EssentialsCommand {
if (world == null) {
throw new Exception(tl("invalidWorld"));
}
if (message.isEmpty()) {
throw new NotEnoughArgumentsException();
}
sendToWorld(world, tl("broadcast", FormatUtil.replaceFormat(message).replace("\\n", "\n"), name));
}
@@ -63,7 +84,15 @@ public class Commandbroadcastworld extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
return Collections.emptyList(); // The argument is only for non-players
if (args.length == 1 && ess.getSettings().isAllowWorldInBroadcastworld()) {
List<String> worlds = Lists.newArrayList();
for (World world : server.getWorlds()) {
worlds.add(world.getName());
}
return worlds;
} else {
return Collections.emptyList();
}
}
@Override
@@ -8,15 +8,12 @@ import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.*;
public class Commandclearinventory extends EssentialsCommand {
@@ -87,6 +84,7 @@ public class Commandclearinventory extends EssentialsCommand {
short data = -1;
int type = -1;
int amount = -1;
final Set<Material> mats = new HashSet<>();
if (args.length > (offset + 1) && NumberUtil.isInt(args[(offset + 1)])) {
amount = Integer.parseInt(args[(offset + 1)]);
@@ -95,15 +93,15 @@ public class Commandclearinventory extends EssentialsCommand {
if (args[offset].equalsIgnoreCase("**")) {
type = -2;
} else if (!args[offset].equalsIgnoreCase("*")) {
final String[] split = args[offset].split(":");
final ItemStack item = ess.getItemDb().get(split[0]);
type = item.getTypeId();
final String[] split = args[offset].split(",");
if (split.length > 1 && NumberUtil.isInt(split[1])) {
data = Short.parseShort(split[1]);
} else {
data = item.getDurability();
for (String name : split) {
try {
mats.add(ess.getItemDb().get(name).getType());
} catch (Exception ignored) {}
}
type = 1;
}
}
@@ -123,32 +121,27 @@ public class Commandclearinventory extends EssentialsCommand {
InventoryWorkaround.setItemInOffHand(player, null);
player.getInventory().setArmorContents(null);
} else {
if (data == -1) // data -1 means that all subtypes will be cleared
{
ItemStack stack = new ItemStack(type);
if (showExtended) {
sender.sendMessage(tl("inventoryClearingAllStack", stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
}
player.getInventory().clear(type, data);
} else if (amount == -1) // amount -1 means all items will be cleared
{
ItemStack stack = new ItemStack(type, BASE_AMOUNT, data);
ItemStack removedStack = player.getInventory().removeItem(stack).get(0);
final int removedAmount = (BASE_AMOUNT - removedStack.getAmount());
if (removedAmount > 0 || showExtended) {
sender.sendMessage(tl("inventoryClearingStack", removedAmount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
}
} else {
if (amount < 0) {
amount = 1;
}
ItemStack stack = new ItemStack(type, amount, data);
if (player.getInventory().containsAtLeast(stack, amount)) {
sender.sendMessage(tl("inventoryClearingStack", amount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
player.getInventory().removeItem(stack);
for (Material mat : mats) {
if (amount == -1) // amount -1 means all items will be cleared
{
ItemStack stack = new ItemStack(mat, BASE_AMOUNT, data);
ItemStack removedStack = player.getInventory().removeItem(stack).get(0);
final int removedAmount = (BASE_AMOUNT - removedStack.getAmount());
if (removedAmount > 0 || showExtended) {
sender.sendMessage(tl("inventoryClearingStack", removedAmount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
}
} else {
if (showExtended) {
sender.sendMessage(tl("inventoryClearFail", player.getDisplayName(), amount, stack.getType().toString().toLowerCase(Locale.ENGLISH)));
if (amount < 0) {
amount = 1;
}
ItemStack stack = new ItemStack(mat, amount);
if (player.getInventory().containsAtLeast(stack, amount)) {
sender.sendMessage(tl("inventoryClearingStack", amount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
player.getInventory().removeItem(stack);
} else {
if (showExtended) {
sender.sendMessage(tl("inventoryClearFail", player.getDisplayName(), amount, stack.getType().toString().toLowerCase(Locale.ENGLISH)));
}
}
}
}
@@ -16,23 +16,23 @@ public class Commandcompass extends EssentialsCommand {
final int bearing = (int) (user.getLocation().getYaw() + 180 + 360) % 360;
String dir;
if (bearing < 23) {
dir = "N";
dir = tl("north");
} else if (bearing < 68) {
dir = "NE";
dir = tl("northEast");
} else if (bearing < 113) {
dir = "E";
dir = tl("east");
} else if (bearing < 158) {
dir = "SE";
dir = tl("southEast");
} else if (bearing < 203) {
dir = "S";
dir = tl("south");
} else if (bearing < 248) {
dir = "SW";
dir = tl("southWest");
} else if (bearing < 293) {
dir = "W";
dir = tl("west");
} else if (bearing < 338) {
dir = "NW";
dir = tl("northWest");
} else {
dir = "N";
dir = tl("north");
}
user.sendMessage(tl("compassBearing", dir, bearing));
}
@@ -19,6 +19,10 @@ public class Commanddeljail extends EssentialsCommand {
throw new NotEnoughArgumentsException();
}
if (ess.getJails().getJail(args[0]) == null) {
throw new Exception(tl("jailNotExist"));
}
ess.getJails().removeJail(args[0]);
sender.sendMessage(tl("deleteJail", args[0]));
}
@@ -71,7 +71,7 @@ public class Commandeco extends EssentialsLoopCommand {
private void take(BigDecimal amount, final User player, final CommandSource sender) throws ChargeException {
BigDecimal money = player.getMoney();
BigDecimal minBalance = ess.getSettings().getMinMoney();
if (money.subtract(amount).compareTo(minBalance) > 0) {
if (money.subtract(amount).compareTo(minBalance) >= 0) {
player.takeMoney(amount, sender);
} else if (sender == null) {
try {
@@ -46,7 +46,7 @@ public class Commandenchant extends EssentialsCommand {
throw new NotEnoughArgumentsException(tl("enchantments", StringUtil.joinList(enchantmentslist.toArray())));
}
int level = -1;
int level = 1;
if (args.length > 1) {
try {
level = Integer.parseInt(args[1]);
@@ -4,10 +4,7 @@ import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.EssentialsUpgrade;
import com.earth2me.essentials.User;
import com.earth2me.essentials.UserMap;
import com.earth2me.essentials.metrics.Metrics;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.FloatUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.*;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import org.bukkit.Material;
@@ -19,13 +16,15 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import java.io.IOException;
import java.util.*;
import static com.earth2me.essentials.I18n.tl;
// This command has 4 undocumented behaviours #EasterEgg
public class Commandessentials extends EssentialsCommand {
private final Sound NOTE_HARP = EnumUtil.valueOf(Sound.class, "BLOCK_NOTE_HARP", "NOTE_PIANO");
public Commandessentials() {
super("essentials");
}
@@ -36,7 +35,22 @@ public class Commandessentials extends EssentialsCommand {
private final List<String> versionPlugins = Arrays.asList(
"Vault",
"LuckPerms",
"PermissionsEx"
"PermissionsEx",
"GroupManager"
);
private final List<String> officialPlugins = Arrays.asList(
"EssentialsAntiBuild",
"EssentialsChat",
"EssentialsGeoIP",
"EssentialsProtect",
"EssentialsSpawn",
"EssentialsXMPP"
);
private final List<String> warnPlugins = Arrays.asList(
"PermissionsEx",
"GroupManager"
);
@Override
@@ -51,8 +65,6 @@ public class Commandessentials extends EssentialsCommand {
run_moo(server, sender, commandLabel, args);
} else if (args[0].equalsIgnoreCase("reset")) {
run_reset(server, sender, commandLabel, args);
} else if (args[0].equalsIgnoreCase("opt-out")) {
run_optout(server, sender, commandLabel, args);
} else if (args[0].equalsIgnoreCase("cleanup")) {
run_cleanup(server, sender, commandLabel, args);
} else if (args[0].equalsIgnoreCase("uuidconvert")) {
@@ -143,15 +155,9 @@ public class Commandessentials extends EssentialsCommand {
if (note == null || note.isEmpty()) {
return;
}
Sound noteHarp;
try {
noteHarp = Sound.valueOf("NOTE_PIANO"); // pre-1.9, referenced internally as note.harp
} catch (IllegalArgumentException e) {
noteHarp = Sound.valueOf("BLOCK_NOTE_HARP"); // 1.9
}
for (Player onlinePlayer : ess.getOnlinePlayers()) {
onlinePlayer.playSound(onlinePlayer.getLocation(), noteHarp, 1, noteMap.get(note));
onlinePlayer.playSound(onlinePlayer.getLocation(), NOTE_HARP, 1, noteMap.get(note));
}
}
}, 20, 2);
@@ -171,12 +177,8 @@ public class Commandessentials extends EssentialsCommand {
private final String[] playerMoo = new String[]{" (__)", " (oo)", " /------\\/", " / | | |", " * /\\---/\\", " ~~ ~~", "....\"Have you mooed today?\"..."};
private void run_moo(final Server server, final CommandSource sender, final String command, final String args[]) {
Sound moo;
try {
moo = Sound.valueOf("COW_IDLE"); // pre-1.9
} catch (IllegalArgumentException e) {
moo = Sound.valueOf("ENTITY_COW_MILK"); // 1.9
}
Sound moo = EnumUtil.valueOf(Sound.class, "COW_IDLE", "ENTITY_COW_MILK");
if (args.length == 2 && args[1].equals("moo")) {
for (String s : consoleMoo) {
logger.info(s);
@@ -197,19 +199,6 @@ public class Commandessentials extends EssentialsCommand {
}
}
private void run_optout(final Server server, final CommandSource sender, final String command, final String args[]) {
final Metrics metrics = ess.getMetrics();
sender.sendMessage("Essentials collects simple metrics to highlight which features to concentrate work on in the future.");
if (metrics.isOptOut()) {
metrics.enable();
} else {
metrics.disable();
}
sender.sendMessage("Anonymous Metrics are now " + (metrics.isOptOut() ? "disabled" : "enabled") + " for EssentialsX until server restart.");
sender.sendMessage("To " + (metrics.isOptOut() ? "disable" : "enable") + " them for all plugins permanently, see the bStats config.");
}
private void run_cleanup(final Server server, final CommandSource sender, final String command, final String args[]) throws Exception {
if (args.length < 2 || !NumberUtil.isInt(args[1])) {
sender.sendMessage("This sub-command will delete users who havent logged in in the last <days> days.");
@@ -318,11 +307,13 @@ public class Commandessentials extends EssentialsCommand {
boolean isMismatched = false;
boolean isVaultInstalled = false;
boolean isUnsupported = false;
final boolean isServerSupported = VersionUtil.isServerSupported();
final PluginManager pm = server.getPluginManager();
final String essVer = pm.getPlugin("Essentials").getDescription().getVersion();
sender.sendMessage("Server version: " + server.getBukkitVersion() + " " + server.getVersion());
sender.sendMessage("EssentialsX version: " + essVer);
sender.sendMessage(tl(isServerSupported ? "versionOutputFine" : "versionOutputWarn", "Server", server.getBukkitVersion() + " " + server.getVersion()));
sender.sendMessage(tl("versionOutputFine", "EssentialsX", essVer));
for (Plugin plugin : pm.getPlugins()) {
final PluginDescriptionFile desc = plugin.getDescription();
@@ -330,15 +321,28 @@ public class Commandessentials extends EssentialsCommand {
String version = desc.getVersion();
if (name.startsWith("Essentials") && !name.equalsIgnoreCase("Essentials")) {
if (!version.equalsIgnoreCase(essVer)) {
version = "\u00a7c" + version;
isMismatched = true;
if (officialPlugins.contains(name)) {
name = name.replace("Essentials", "EssentialsX");
if (!version.equalsIgnoreCase(essVer)) {
isMismatched = true;
sender.sendMessage(tl("versionOutputWarn", name, version));
} else {
sender.sendMessage(tl("versionOutputFine", name, version));
}
} else {
sender.sendMessage(tl("versionOutputUnsupported", name, version));
isUnsupported = true;
}
sender.sendMessage(name.replace("Essentials", "EssentialsX") + " version: " + version);
}
if (versionPlugins.contains(name)) {
sender.sendMessage(name + " version: " + version);
if (warnPlugins.contains(name)) {
sender.sendMessage(tl("versionOutputUnsupported", name, version));
isUnsupported = true;
} else {
sender.sendMessage(tl("versionOutputFine", name, version));
}
}
if (name.equals("Vault")) isVaultInstalled = true;
@@ -349,7 +353,15 @@ public class Commandessentials extends EssentialsCommand {
}
if (!isVaultInstalled) {
sender.sendMessage("Vault is not installed - chat and permissions may not work.");
sender.sendMessage(tl("versionOutputVaultMissing"));
}
if (isUnsupported) {
sender.sendMessage(tl("versionOutputUnsupportedPlugins"));
}
if (!VersionUtil.isServerSupported()) {
sender.sendMessage(tl("serverUnsupported"));
}
}
@@ -362,7 +374,6 @@ public class Commandessentials extends EssentialsCommand {
//options.add("nya");
//options.add("moo");
options.add("reset");
options.add("opt-out");
options.add("cleanup");
//options.add("uuidconvert");
//options.add("uuidtest");
@@ -380,8 +391,6 @@ public class Commandessentials extends EssentialsCommand {
if (args.length == 2) {
return getPlayers(server, sender);
}
} else if (args[0].equalsIgnoreCase("opt-out")) {
// No args
} else if (args[0].equalsIgnoreCase("cleanup")) {
if (args.length == 2) {
return COMMON_DURATIONS;
@@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.MetaItemStack;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.google.common.collect.Lists;
import org.bukkit.DyeColor;
@@ -43,8 +44,8 @@ public class Commandfirework extends EssentialsCommand {
@Override
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
final ItemStack stack = user.getBase().getItemInHand();
if (stack.getType() == Material.FIREWORK) {
final ItemStack stack = user.getItemInHand();
if (MaterialUtil.isFirework(stack.getType())) {
if (args.length > 0) {
if (args[0].equalsIgnoreCase("clear")) {
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
@@ -31,9 +31,9 @@ public class Commandgive extends EssentialsCommand {
}
ItemStack stack = ess.getItemDb().get(args[1]);
final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
if (sender.isPlayer() && (ess.getSettings().permissionBasedItemSpawn() ? (!ess.getUser(sender.getPlayer()).isAuthorized("essentials.itemspawn.item-all") && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.itemspawn.item-" + itemname) && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.itemspawn.item-" + stack.getTypeId())) : (!ess.getUser(sender.getPlayer()).isAuthorized("essentials.itemspawn.exempt") && !ess.getUser(sender.getPlayer()).canSpawnItem(stack.getTypeId())))) {
if (sender.isPlayer() && !ess.getUser(sender.getPlayer()).canSpawnItem(stack.getType())) {
throw new Exception(tl("cantSpawnItem", itemname));
}
@@ -33,8 +33,8 @@ public class Commandhat extends EssentialsCommand {
user.sendMessage(tl("hatRemoved"));
}
} else {
if (user.getBase().getItemInHand().getType() != Material.AIR) {
final ItemStack hand = user.getBase().getItemInHand();
final ItemStack hand = user.getItemInHand();
if (hand != null && hand.getType() != Material.AIR) {
if (hand.getType().getMaxDurability() == 0) {
final PlayerInventory inv = user.getBase().getInventory();
final ItemStack head = inv.getHelmet();
@@ -25,12 +25,14 @@ public class Commanditem extends EssentialsCommand {
if (args.length < 1) {
throw new NotEnoughArgumentsException();
}
ItemStack stack = ess.getItemDb().get(args[0]);
final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
if (ess.getSettings().permissionBasedItemSpawn() ? (!user.isAuthorized("essentials.itemspawn.item-all") && !user.isAuthorized("essentials.itemspawn.item-" + itemname) && !user.isAuthorized("essentials.itemspawn.item-" + stack.getTypeId())) : (!user.isAuthorized("essentials.itemspawn.exempt") && !user.canSpawnItem(stack.getTypeId()))) {
if (!user.canSpawnItem(stack.getType())) {
throw new Exception(tl("cantSpawnItem", itemname));
}
try {
if (args.length > 1 && Integer.parseInt(args[1]) > 0) {
stack.setAmount(Integer.parseInt(args[1]));
@@ -1,6 +1,7 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.utils.VersionUtil;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.inventory.ItemStack;
@@ -21,9 +22,9 @@ public class Commanditemdb extends EssentialsCommand {
ItemStack itemStack = null;
boolean itemHeld = false;
if (args.length < 1) {
if (sender.isPlayer()) {
if (sender.isPlayer() && sender.getPlayer() != null) {
itemHeld = true;
itemStack = sender.getPlayer().getItemInHand();
itemStack = ess.getUser(sender.getPlayer()).getItemInHand();
}
if (itemStack == null) {
throw new NotEnoughArgumentsException();
@@ -31,7 +32,19 @@ public class Commanditemdb extends EssentialsCommand {
} else {
itemStack = ess.getItemDb().get(args[0]);
}
sender.sendMessage(tl("itemType", itemStack.getType().toString(), itemStack.getTypeId() + ":" + Integer.toString(itemStack.getDurability())));
String itemId = "none";
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
itemId = itemStack.getType().getId() + ":" + itemStack.getDurability();
}
sender.sendMessage(tl("itemType", itemStack.getType().toString(), itemId));
// Don't send IDs twice
if (!tl("itemType").contains("{1}") && !itemId.equals("none")) {
sender.sendMessage(tl("itemId", itemId));
}
if (itemHeld && itemStack.getType() != Material.AIR) {
int maxuses = itemStack.getType().getMaxDurability();
@@ -20,7 +20,9 @@ public class Commandkickall extends EssentialsCommand {
for (Player onlinePlayer : ess.getOnlinePlayers()) {
if (!sender.isPlayer() || !onlinePlayer.getName().equalsIgnoreCase(sender.getPlayer().getName())) {
onlinePlayer.kickPlayer(kickReason);
if (!ess.getUser(onlinePlayer).isAuthorized("essentials.kickall.exempt")) {
onlinePlayer.kickPlayer(kickReason);
}
}
}
sender.sendMessage(tl("kickedAll"));
@@ -105,11 +105,11 @@ public class Commandmail extends EssentialsCommand {
if (u == null) {
throw new Exception(tl("playerNeverOnServer", args[1]));
}
u.addMail(tl("mailFormat", "Server", getFinalArg(args, 2)));
u.addMail(tl("mailFormat", "Server", FormatUtil.replaceFormat(getFinalArg(args, 2))));
sender.sendMessage(tl("mailSent"));
return;
} else if (args.length >= 2 && "sendall".equalsIgnoreCase(args[0])) {
ess.runTaskAsynchronously(new SendAll(tl("mailFormat", "Server", getFinalArg(args, 1))));
ess.runTaskAsynchronously(new SendAll(tl("mailFormat", "Server", FormatUtil.replaceFormat(getFinalArg(args, 1)))));
sender.sendMessage(tl("mailSent"));
return;
} else if (args.length >= 2) {
@@ -118,7 +118,7 @@ public class Commandmail extends EssentialsCommand {
if (u == null) {
throw new Exception(tl("playerNeverOnServer", args[0]));
}
u.addMail(tl("mailFormat", "Server", getFinalArg(args, 1)));
u.addMail(tl("mailFormat", "Server", FormatUtil.replaceFormat(getFinalArg(args, 1))));
sender.sendMessage(tl("mailSent"));
return;
}
@@ -16,15 +16,16 @@ public class Commandmore extends EssentialsCommand {
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
final ItemStack stack = user.getBase().getItemInHand();
final ItemStack stack = user.getItemInHand();
if (stack == null) {
throw new Exception(tl("cantSpawnItem", "Air"));
}
if (stack.getAmount() >= ((user.isAuthorized("essentials.oversizedstacks")) ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize())) {
throw new Exception(tl("fullStack"));
}
final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
if (ess.getSettings().permissionBasedItemSpawn() ? (!user.isAuthorized("essentials.itemspawn.item-all") && !user.isAuthorized("essentials.itemspawn.item-" + itemname) && !user.isAuthorized("essentials.itemspawn.item-" + stack.getTypeId())) : (!user.isAuthorized("essentials.itemspawn.exempt") && !user.canSpawnItem(stack.getTypeId()))) {
if (!user.canSpawnItem(stack.getType())) {
throw new Exception(tl("cantSpawnItem", itemname));
}
if (user.isAuthorized("essentials.oversizedstacks")) {
@@ -55,16 +55,16 @@ public class Commandnick extends EssentialsLoopCommand {
@Override
protected void updatePlayer(final Server server, final CommandSource sender, final User target, final String[] args) throws NotEnoughArgumentsException {
final String nick = args[0];
if (target.getName().equalsIgnoreCase(nick)) {
if ("off".equalsIgnoreCase(nick)) {
setNickname(server, sender, target, null);
target.sendMessage(tl("nickNoMore"));
} else if (target.getName().equalsIgnoreCase(nick)) {
String oldName = target.getDisplayName();
setNickname(server, sender, target, nick);
if (!target.getDisplayName().equalsIgnoreCase(oldName)) {
target.sendMessage(tl("nickNoMore"));
}
target.sendMessage(tl("nickSet", target.getDisplayName()));
} else if ("off".equalsIgnoreCase(nick)) {
setNickname(server, sender, target, null);
target.sendMessage(tl("nickNoMore"));
} else if (nickInUse(server, target, nick)) {
throw new NotEnoughArgumentsException(tl("nickInUse"));
} else {
@@ -75,7 +75,7 @@ public class Commandnick extends EssentialsLoopCommand {
private String formatNickname(final User user, final String nick) throws Exception {
String newNick = user == null ? FormatUtil.replaceFormat(nick) : FormatUtil.formatString(user, "essentials.nick", nick);
if (!newNick.matches("^[a-zA-Z_0-9\u00a7]+$")) {
if (!newNick.matches("^[a-zA-Z_0-9\u00a7]+$") && user != null && !user.isAuthorized("essentials.nick.allowunsafe")) {
throw new Exception(tl("nickNamesAlpha"));
} else if (getNickLength(newNick) > ess.getSettings().getMaxNickLength()) {
throw new Exception(tl("nickTooLong"));
@@ -31,7 +31,7 @@ public class Commandrealname extends EssentialsCommand {
final String displayName = FormatUtil.stripFormat(u.getDisplayName()).toLowerCase(Locale.ENGLISH);
if (displayName.contains(whois)) {
foundUser = true;
sender.sendMessage(u.getDisplayName() + " " + tl("is") + " " + u.getName());
sender.sendMessage(tl("realName", u.getDisplayName(), u.getName()));
}
}
if (!foundUser) {
@@ -2,7 +2,9 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.VersionUtil;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.inventory.*;
@@ -19,13 +21,20 @@ import net.ess3.nms.refl.ReflUtil;
public class Commandrecipe extends EssentialsCommand {
private static final Material FIREWORK_ROCKET = EnumUtil.getMaterial("FIREWORK_ROCKET", "FIREWORK");
private static final Material FIREWORK_STAR = EnumUtil.getMaterial("FIREWORK_STAR", "FIREWORK_CHARGE");
private static final Material GUNPOWDER = EnumUtil.getMaterial("GUNPOWDER", "SULPHUR");
public Commandrecipe() {
super("recipe");
}
private void disableCommandForVersion1_12() throws Exception {
if (ReflUtil.getNmsVersionObject().equals(ReflUtil.V1_12_R1)) {
throw new Exception("/recipe is temporarily disabled. Please use the recipe book in your inventory.");
VersionUtil.BukkitVersion version = VersionUtil.getServerBukkitVersion();
if (version.isHigherThanOrEqualTo(VersionUtil.v1_12_0_R01)
&& !ess.getSettings().isForceEnableRecipe()) {
throw new Exception("Please use the recipe book in your inventory.");
}
}
@@ -64,11 +73,11 @@ public class Commandrecipe extends EssentialsCommand {
} else if (selectedRecipe instanceof ShapedRecipe) {
shapedRecipe(sender, (ShapedRecipe) selectedRecipe, sender.isPlayer());
} else if (selectedRecipe instanceof ShapelessRecipe) {
if (recipesOfType.size() == 1 && itemType.getType() == Material.FIREWORK) {
if (recipesOfType.size() == 1 && (itemType.getType() == FIREWORK_ROCKET)) {
ShapelessRecipe shapelessRecipe = new ShapelessRecipe(itemType);
shapelessRecipe.addIngredient(Material.SULPHUR);
shapelessRecipe.addIngredient(GUNPOWDER);
shapelessRecipe.addIngredient(Material.PAPER);
shapelessRecipe.addIngredient(Material.FIREWORK_CHARGE);
shapelessRecipe.addIngredient(FIREWORK_STAR);
shapelessRecipe(sender, shapelessRecipe, sender.isPlayer());
} else {
shapelessRecipe(sender, (ShapelessRecipe) selectedRecipe, sender.isPlayer());
@@ -4,6 +4,7 @@ import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.StringUtil;
import com.earth2me.essentials.utils.VersionUtil;
import com.google.common.collect.Lists;
import net.ess3.api.IUser;
import org.bukkit.Material;
@@ -38,7 +39,7 @@ public class Commandrepair extends EssentialsCommand {
}
public void repairHand(User user) throws Exception {
final ItemStack item = user.getBase().getItemInHand();
final ItemStack item = user.getItemInHand();
if (item == null || item.getType().isBlock() || item.getDurability() == 0) {
throw new Exception(tl("repairInvalidType"));
}
@@ -48,7 +49,7 @@ public class Commandrepair extends EssentialsCommand {
}
final String itemName = item.getType().toString().toLowerCase(Locale.ENGLISH);
final Trade charge = new Trade("repair-" + itemName.replace('_', '-'), new Trade("repair-" + item.getTypeId(), new Trade("repair-item", ess), ess), ess);
final Trade charge = getCharge(item.getType());
charge.isAffordableFor(user);
@@ -76,7 +77,7 @@ public class Commandrepair extends EssentialsCommand {
}
private void repairItem(final ItemStack item) throws Exception {
final Material material = Material.getMaterial(item.getTypeId());
final Material material = item.getType();
if (material.isBlock() || material.getMaxDurability() < 1) {
throw new Exception(tl("repairInvalidType"));
}
@@ -88,13 +89,15 @@ public class Commandrepair extends EssentialsCommand {
item.setDurability((short) 0);
}
private void repairItems(final ItemStack[] items, final IUser user, final List<String> repaired) {
private void repairItems(final ItemStack[] items, final IUser user, final List<String> repaired) throws Exception {
for (ItemStack item : items) {
if (item == null || item.getType().isBlock() || item.getDurability() == 0) {
continue;
}
final String itemName = item.getType().toString().toLowerCase(Locale.ENGLISH);
final Trade charge = new Trade("repair-" + itemName.replace('_', '-'), new Trade("repair-" + item.getTypeId(), new Trade("repair-item", ess), ess), ess);
final Trade charge = getCharge(item.getType());
try {
charge.isAffordableFor(user);
} catch (ChargeException ex) {
@@ -119,6 +122,16 @@ public class Commandrepair extends EssentialsCommand {
}
}
private Trade getCharge(final Material material) {
final String itemName = material.toString().toLowerCase(Locale.ENGLISH);
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
final int itemId = material.getId();
return new Trade("repair-" + itemName.replace('_', '-'), new Trade("repair-" + itemId, new Trade("repair-item", ess), ess), ess);
} else {
return new Trade("repair-" + itemName.replace('_', '-'), new Trade("repair-item", ess), ess);
}
}
@Override
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
if (args.length == 1) {
@@ -69,7 +69,7 @@ public class Commandsell extends EssentialsCommand {
private BigDecimal sellItem(User user, ItemStack is, String[] args, boolean isBulkSell) throws Exception {
int amount = ess.getWorth().getAmount(ess, user, is, args, isBulkSell);
BigDecimal worth = ess.getWorth().getPrice(is);
BigDecimal worth = ess.getWorth().getPrice(ess, is);
if (worth == null) {
throw new Exception(tl("itemCannotBeSold"));
@@ -36,7 +36,7 @@ public class Commandsetwarp extends EssentialsCommand {
}
if (warpLoc == null || user.isAuthorized("essentials.warp.overwrite." + StringUtil.safeString(args[0]))) {
warps.setWarp(args[0], loc);
warps.setWarp(user, args[0], loc);
} else {
throw new Exception(tl("warpOverwrite"));
}
@@ -31,7 +31,7 @@ public class Commandsetworth extends EssentialsCommand {
price = args[1];
}
ess.getWorth().setPrice(stack, FloatUtil.parseDouble(price));
ess.getWorth().setPrice(ess, stack, FloatUtil.parseDouble(price));
user.sendMessage(tl("worthSet"));
}
@@ -42,7 +42,7 @@ public class Commandsetworth extends EssentialsCommand {
}
ItemStack stack = ess.getItemDb().get(args[0]);
ess.getWorth().setPrice(stack, FloatUtil.parseDouble(args[1]));
ess.getWorth().setPrice(ess, stack, FloatUtil.parseDouble(args[1]));
sender.sendMessage(tl("worthSet"));
}
}
@@ -2,6 +2,8 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.User;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import com.google.common.collect.Lists;
import org.bukkit.Material;
import org.bukkit.Server;
@@ -14,6 +16,9 @@ import java.util.List;
import static com.earth2me.essentials.I18n.tl;
public class Commandskull extends EssentialsCommand {
private static final Material SKULL_ITEM = EnumUtil.getMaterial("PLAYER_HEAD", "SKULL_ITEM");
public Commandskull() {
super("skull");
}
@@ -31,14 +36,14 @@ public class Commandskull extends EssentialsCommand {
owner = user.getName();
}
ItemStack itemSkull = user.getBase().getItemInHand();
ItemStack itemSkull = user.getItemInHand();
SkullMeta metaSkull = null;
boolean spawn = false;
if (itemSkull != null && itemSkull.getType() == Material.SKULL_ITEM && itemSkull.getDurability() == 3) {
if (itemSkull != null && MaterialUtil.isPlayerHead(itemSkull.getType(), itemSkull.getDurability())) {
metaSkull = (SkullMeta) itemSkull.getItemMeta();
} else if (user.isAuthorized("essentials.skull.spawn")) {
itemSkull = new ItemStack(Material.SKULL_ITEM, 1, (byte) 3);
itemSkull = new ItemStack(SKULL_ITEM, 1, (byte) 3);
metaSkull = (SkullMeta) itemSkull.getItemMeta();
spawn = true;
} else {
@@ -3,6 +3,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.Mob;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil;
@@ -28,7 +29,9 @@ public class Commandspawner extends EssentialsCommand {
}
final Location target = LocationUtil.getTarget(user.getBase());
if (target == null || target.getBlock().getType() != Material.MOB_SPAWNER) {
Material MOB_SPAWNER = EnumUtil.getMaterial("SPAWNER", "MOB_SPAWNER");
if (target == null || target.getBlock().getType() != MOB_SPAWNER) {
throw new Exception(tl("mobSpawnTarget"));
}
@@ -32,6 +32,10 @@ public class Commandtree extends EssentialsCommand {
}
if (args[0].equalsIgnoreCase("jungle")) {
tree = TreeType.SMALL_JUNGLE;
} else if (args[0].equalsIgnoreCase("acacia")) {
tree = TreeType.ACACIA;
} else if (args[0].equalsIgnoreCase("birch")) {
tree = TreeType.BIRCH;
}
if (tree == null) {
throw new NotEnoughArgumentsException();
@@ -32,12 +32,12 @@ public class Commandunlimited extends EssentialsCommand {
final String list = getList(target);
user.sendMessage(list);
} else if (args[0].equalsIgnoreCase("clear")) {
final List<Integer> itemList = target.getUnlimited();
final List<Material> itemList = target.getUnlimited();
int index = 0;
while (itemList.size() > index) {
final Integer item = itemList.get(index);
if (toggleUnlimited(user, target, item.toString()) == false) {
final Material item = itemList.get(index);
if (!toggleUnlimited(user, target, item.toString())) {
index++;
}
}
@@ -50,16 +50,16 @@ public class Commandunlimited extends EssentialsCommand {
final StringBuilder output = new StringBuilder();
output.append(tl("unlimitedItems")).append(" ");
boolean first = true;
final List<Integer> items = target.getUnlimited();
final List<Material> items = target.getUnlimited();
if (items.isEmpty()) {
output.append(tl("none"));
}
for (Integer integer : items) {
for (Material material : items) {
if (!first) {
output.append(", ");
}
first = false;
final String matname = Material.getMaterial(integer).toString().toLowerCase(Locale.ENGLISH).replace("_", "");
final String matname = material.toString().toLowerCase(Locale.ENGLISH).replace("_", "");
output.append(matname);
}
@@ -71,7 +71,7 @@ public class Commandunlimited extends EssentialsCommand {
stack.setAmount(Math.min(stack.getType().getMaxStackSize(), 2));
final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
if (ess.getSettings().permissionBasedItemSpawn() && (!user.isAuthorized("essentials.unlimited.item-all") && !user.isAuthorized("essentials.unlimited.item-" + itemname) && !user.isAuthorized("essentials.unlimited.item-" + stack.getTypeId()) && !((stack.getType() == Material.WATER_BUCKET || stack.getType() == Material.LAVA_BUCKET) && user.isAuthorized("essentials.unlimited.item-bucket")))) {
if (ess.getSettings().permissionBasedItemSpawn() && (!user.isAuthorized("essentials.unlimited.item-all") && !user.isAuthorized("essentials.unlimited.item-" + itemname) && !((stack.getType() == Material.WATER_BUCKET || stack.getType() == Material.LAVA_BUCKET) && user.isAuthorized("essentials.unlimited.item-bucket")))) {
throw new Exception(tl("unlimitedItemPermission", itemname));
}
@@ -13,9 +13,9 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import static com.earth2me.essentials.I18n.tl;
@@ -64,17 +64,8 @@ public class Commandwarp extends EssentialsCommand {
//TODO: Use one of the new text classes, like /help ?
private void warpList(final CommandSource sender, final String[] args, final IUser user) throws Exception {
final IWarps warps = ess.getWarps();
final List<String> warpNameList = new ArrayList<>(warps.getList());
final List<String> warpNameList = getAvailableWarpsFor(user);
if (user != null) {
final Iterator<String> iterator = warpNameList.iterator();
while (iterator.hasNext()) {
final String warpName = iterator.next();
if (ess.getSettings().getPerWarpPermission() && !user.isAuthorized("essentials.warps." + warpName)) {
iterator.remove();
}
}
}
if (warpNameList.isEmpty()) {
throw new Exception(tl("noWarpsDefined"));
}
@@ -112,10 +103,20 @@ public class Commandwarp extends EssentialsCommand {
owner.getTeleport().warp(user, name, charge, TeleportCause.COMMAND);
}
private List<String> getAvailableWarpsFor(final IUser user) {
if (ess.getSettings().getPerWarpPermission() && user != null) {
return ess.getWarps().getList().stream()
.filter(warpName -> user.isAuthorized("essentials.warps." + warpName))
.collect(Collectors.toList());
}
return new ArrayList<>(ess.getWarps().getList());
}
@Override
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (args.length == 1 && user.isAuthorized("essentials.warp.list")) {
return new ArrayList<>(ess.getWarps().getList());
return getAvailableWarpsFor(user);
} else if (args.length == 2 && (user.isAuthorized("essentials.warp.otherplayers") || user.isAuthorized("essentials.warp.others"))) {
//TODO: Remove 'otherplayers' permission.
return getPlayers(server, user);
@@ -4,6 +4,7 @@ import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import com.earth2me.essentials.craftbukkit.SetExpFix;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.Server;
import org.bukkit.Statistic;
@@ -16,6 +17,10 @@ import static com.earth2me.essentials.I18n.tl;
public class Commandwhois extends EssentialsCommand {
// For some reason, in 1.13 PLAY_ONE_MINUTE = ticks played = what used to be PLAY_ONE_TICK
// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/b848d8ce633871b52115247b089029749c02f579
private static final Statistic PLAY_ONE_TICK = EnumUtil.getStatistic("PLAY_ONE_MINUTE", "PLAY_ONE_TICK");
public Commandwhois() {
super("whois");
}
@@ -36,7 +41,7 @@ public class Commandwhois extends EssentialsCommand {
sender.sendMessage(tl("whoisHunger", user.getBase().getFoodLevel(), user.getBase().getSaturation()));
sender.sendMessage(tl("whoisExp", SetExpFix.getTotalExperience(user.getBase()), user.getBase().getLevel()));
sender.sendMessage(tl("whoisLocation", user.getLocation().getWorld().getName(), user.getLocation().getBlockX(), user.getLocation().getBlockY(), user.getLocation().getBlockZ()));
long playtimeMs = System.currentTimeMillis() - (user.getBase().getStatistic(Statistic.PLAY_ONE_TICK) * 50);
long playtimeMs = System.currentTimeMillis() - (user.getBase().getStatistic(PLAY_ONE_TICK) * 50);
sender.sendMessage(tl("whoisPlaytime", DateUtil.formatDateDiff(playtimeMs)));
if (!ess.getSettings().isEcoDisabled()) {
sender.sendMessage(tl("whoisMoney", NumberUtil.displayCurrency(user.getMoney(), ess)));
@@ -84,7 +84,7 @@ public class Commandworth extends EssentialsCommand {
amount = ess.getWorth().getAmount(ess, user, is, args, true);
}
BigDecimal worth = ess.getWorth().getPrice(is);
BigDecimal worth = ess.getWorth().getPrice(ess, is);
if (worth == null) {
throw new Exception(tl("itemCannotBeSold"));
@@ -3,6 +3,7 @@ package com.earth2me.essentials.craftbukkit;
import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.*;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
@@ -10,6 +11,8 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.BoundingBox;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
import java.io.File;
@@ -17,6 +20,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
public class FakeWorld implements World {
@@ -38,16 +42,6 @@ public class FakeWorld implements World {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int getBlockTypeIdAt(int i, int i1, int i2) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int getBlockTypeIdAt(Location lctn) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int getHighestBlockYAt(int i, int i1) {
throw new UnsupportedOperationException("Not supported yet.");
@@ -93,6 +87,11 @@ public class FakeWorld implements World {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isChunkGenerated(int x, int z) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void loadChunk(int i, int i1) {
throw new UnsupportedOperationException("Not supported yet.");
@@ -138,6 +137,21 @@ public class FakeWorld implements World {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean isChunkForceLoaded(int x, int z) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void setChunkForceLoaded(int x, int z, boolean forced) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Collection<Chunk> getForceLoadedChunks() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Item dropItem(Location lctn, ItemStack is) {
throw new UnsupportedOperationException("Not supported yet.");
@@ -164,7 +178,7 @@ public class FakeWorld implements World {
}
@Override
public boolean generateTree(Location lctn, TreeType tt, BlockChangeDelegate bcd) {
public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -203,6 +217,11 @@ public class FakeWorld implements World {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean setSpawnLocation(Location location) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public boolean setSpawnLocation(int i, int i1, int i2) {
throw new UnsupportedOperationException("Not supported yet.");
@@ -348,6 +367,11 @@ public class FakeWorld implements World {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public FallingBlock spawnFallingBlock(Location location, BlockData blockData) throws IllegalArgumentException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public ChunkSnapshot getEmptyChunkSnapshot(int i, int i1, boolean bln, boolean bln1) {
throw new UnsupportedOperationException("Not supported yet.");
@@ -583,11 +607,6 @@ public class FakeWorld implements World {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public FallingBlock spawnFallingBlock(Location location, int blockId, byte blockData) throws IllegalArgumentException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void playSound(Location arg0, Sound arg1, float arg2, float arg3) {
throw new UnsupportedOperationException("Not supported yet.");
@@ -600,12 +619,12 @@ public class FakeWorld implements World {
@Override
public void playSound(Location location, Sound sound, SoundCategory soundCategory, float v, float v1) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void playSound(Location location, String s, SoundCategory soundCategory, float v, float v1) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
@@ -650,66 +669,151 @@ public class FakeWorld implements World {
@Override
public void spawnParticle(Particle particle, Location location, int i) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void spawnParticle(Particle particle, double v, double v1, double v2, int i) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> void spawnParticle(Particle particle, Location location, int i, T t) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> void spawnParticle(Particle particle, double v, double v1, double v2, int i, T t) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void spawnParticle(Particle particle, Location location, int i, double v, double v1, double v2) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void spawnParticle(Particle particle, double v, double v1, double v2, int i, double v3, double v4, double v5) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> void spawnParticle(Particle particle, Location location, int i, double v, double v1, double v2, T t) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> void spawnParticle(Particle particle, double v, double v1, double v2, int i, double v3, double v4, double v5, T t) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void spawnParticle(Particle particle, Location location, int i, double v, double v1, double v2, double v3) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void spawnParticle(Particle particle, double v, double v1, double v2, int i, double v3, double v4, double v5, double v6) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> void spawnParticle(Particle particle, Location location, int i, double v, double v1, double v2, double v3, T t) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> void spawnParticle(Particle particle, double v, double v1, double v2, int i, double v3, double v4, double v5, double v6, T t) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> void spawnParticle(Particle particle, Location location, int i, double v, double v1, double v2, double v3, T t, boolean b) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> void spawnParticle(Particle particle, double v, double v1, double v2, int i, double v3, double v4, double v5, double v6, T t, boolean b) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Location locateNearestStructure(Location origin, StructureType structureType, int radius, boolean findUnexplored) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public List<Entity> getNearbyEntities(Location loc, double x, double y, double z) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
@Override
public Collection<Entity> getNearbyEntities(Location location, double x, double y, double z, Predicate<Entity> filter) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Collection<Entity> getNearbyEntities(BoundingBox boundingBox) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Collection<Entity> getNearbyEntities(BoundingBox boundingBox, Predicate<Entity> filter) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public RayTraceResult rayTraceEntities(Location start, Vector direction, double maxDistance) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public RayTraceResult rayTraceEntities(Location start, Vector direction, double maxDistance, double raySize) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public RayTraceResult rayTraceEntities(Location start, Vector direction, double maxDistance, Predicate<Entity> filter) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public RayTraceResult rayTraceEntities(Location start, Vector direction, double maxDistance, double raySize, Predicate<Entity> filter) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public RayTraceResult rayTraceBlocks(Location start, Vector direction, double maxDistance) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public RayTraceResult rayTraceBlocks(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public RayTraceResult rayTraceBlocks(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public RayTraceResult rayTrace(Location start, Vector direction, double maxDistance, FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, Predicate<Entity> filter) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> T getGameRuleDefault(GameRule<T> arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> T getGameRuleValue(GameRule<T> arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <T> boolean setGameRule(GameRule<T> arg0, T arg1) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
@@ -0,0 +1,234 @@
package com.earth2me.essentials.items;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.IConf;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.StringUtil;
import com.earth2me.essentials.utils.VersionUtil;
import org.bukkit.Color;
import org.bukkit.DyeColor;
import org.bukkit.FireworkEffect;
import org.bukkit.Material;
import org.bukkit.block.Banner;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.*;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import static com.earth2me.essentials.I18n.tl;
public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
protected boolean ready = false;
@Override
public List<ItemStack> getMatching(User user, String[] args) throws Exception {
List<ItemStack> is = new ArrayList<>();
if (args.length < 1) {
is.add(user.getItemInHand().clone());
} else if (args[0].equalsIgnoreCase("hand")) {
is.add(user.getItemInHand().clone());
} else if (args[0].equalsIgnoreCase("inventory") || args[0].equalsIgnoreCase("invent") || args[0].equalsIgnoreCase("all")) {
for (ItemStack stack : user.getBase().getInventory().getContents()) {
if (stack == null || stack.getType() == Material.AIR) {
continue;
}
is.add(stack.clone());
}
} else if (args[0].equalsIgnoreCase("blocks")) {
for (ItemStack stack : user.getBase().getInventory().getContents()) {
if (stack == null || stack.getType() == Material.AIR) {
continue;
}
is.add(stack.clone());
}
} else {
is.add(get(args[0]));
}
if (is.isEmpty() || is.get(0).getType() == Material.AIR) {
throw new Exception(tl("itemSellAir"));
}
return is;
}
@Override
public String serialize(ItemStack is) {
String mat = name(is);
if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_12_2_R01) && is.getData().getData() != 0) {
mat = mat + ":" + is.getData().getData();
}
int quantity = is.getAmount();
StringBuilder sb = new StringBuilder(); // Add space AFTER you add something. We can trim at end.
sb.append(mat).append(" ").append(quantity).append(" ");
// ItemMeta applies to anything.
if (is.hasItemMeta()) {
ItemMeta meta = is.getItemMeta();
if (meta.hasDisplayName()) {
sb.append("name:").append(meta.getDisplayName().replaceAll(" ", "_")).append(" ");
}
if (meta.hasLore()) {
sb.append("lore:");
boolean first = true;
for (String s : meta.getLore()) {
// Add | before the line if it's not the first one. Easy but weird way
// to do this since we need each line separated by |
if (!first) {
sb.append("|");
}
first = false;
sb.append(s.replaceAll(" ", "_"));
}
sb.append(" ");
}
if (meta.hasEnchants()) {
for (Enchantment e : meta.getEnchants().keySet()) {
sb.append(e.getName().toLowerCase()).append(":").append(meta.getEnchantLevel(e)).append(" ");
}
}
Set<ItemFlag> flags = meta.getItemFlags();
if (flags != null && !flags.isEmpty()) {
sb.append("itemflags:");
boolean first = true;
for (ItemFlag flag : flags) {
if (!first) {
sb.append(",");
}
sb.append(flag.name());
first = false;
}
}
}
final Material material = is.getType();
switch (material) {
case WRITTEN_BOOK:
// Everything from http://wiki.ess3.net/wiki/Item_Meta#Books in that order.
// Interesting as I didn't see a way to do pages or chapters.
BookMeta bookMeta = (BookMeta) is.getItemMeta();
if (bookMeta.hasTitle()) {
sb.append("title:").append(bookMeta.getTitle()).append(" ");
}
if (bookMeta.hasAuthor()) {
sb.append("author:").append(bookMeta.getAuthor()).append(" ");
}
// Only other thing it could have is lore but that's done up there ^^^
break;
case ENCHANTED_BOOK:
EnchantmentStorageMeta enchantmentStorageMeta = (EnchantmentStorageMeta) is.getItemMeta();
for (Enchantment e : enchantmentStorageMeta.getStoredEnchants().keySet()) {
sb.append(e.getName().toLowerCase()).append(":").append(enchantmentStorageMeta.getStoredEnchantLevel(e)).append(" ");
}
break;
}
if (MaterialUtil.isFirework(material)) {
// Everything from http://wiki.ess3.net/wiki/Item_Meta#Fireworks in that order.
FireworkMeta fireworkMeta = (FireworkMeta) is.getItemMeta();
if (fireworkMeta.hasEffects()) {
for (FireworkEffect effect : fireworkMeta.getEffects()) {
if (effect.getColors() != null && !effect.getColors().isEmpty()) {
sb.append("color:");
boolean first = true;
for (Color c : effect.getColors()) {
if (!first) {
sb.append(","); // same thing as above.
}
sb.append(c.toString());
first = false;
}
sb.append(" ");
}
sb.append("shape:").append(effect.getType().name()).append(" ");
if (effect.getFadeColors() != null && !effect.getFadeColors().isEmpty()) {
sb.append("fade:");
boolean first = true;
for (Color c : effect.getFadeColors()) {
if (!first) {
sb.append(","); // same thing as above.
}
sb.append(c.toString());
first = false;
}
sb.append(" ");
}
}
sb.append("power:").append(fireworkMeta.getPower()).append(" ");
}
} else if (MaterialUtil.isPotion(material)) {
Potion potion = Potion.fromItemStack(is);
for (PotionEffect e : potion.getEffects()) {
// long but needs to be effect:speed power:2 duration:120 in that order.
sb.append("splash:").append(potion.isSplash()).append(" ").append("effect:").append(e.getType().getName().toLowerCase()).append(" ").append("power:").append(e.getAmplifier()).append(" ").append("duration:").append(e.getDuration() / 20).append(" ");
}
} else if (MaterialUtil.isPlayerHead(material, is.getData().getData())) {
// item stack with meta
SkullMeta skullMeta = (SkullMeta) is.getItemMeta();
if (skullMeta != null && skullMeta.hasOwner()) {
sb.append("player:").append(skullMeta.getOwner()).append(" ");
}
} else if (MaterialUtil.isBanner(material)) {
if (material.toString().contains("SHIELD")) {
// Hacky fix for accessing Shield meta - https://github.com/drtshock/Essentials/pull/745#issuecomment-234843795
BlockStateMeta shieldMeta = (BlockStateMeta) is.getItemMeta();
Banner shieldBannerMeta = (Banner) shieldMeta.getBlockState();
DyeColor baseDyeColor = shieldBannerMeta.getBaseColor();
if (baseDyeColor != null) {
int basecolor = baseDyeColor.getColor().asRGB();
sb.append("basecolor:").append(basecolor).append(" ");
}
for (org.bukkit.block.banner.Pattern p : shieldBannerMeta.getPatterns()) {
String type = p.getPattern().getIdentifier();
int color = p.getColor().getColor().asRGB();
sb.append(type).append(",").append(color).append(" ");
}
} else {
BannerMeta bannerMeta = (BannerMeta) is.getItemMeta();
if (bannerMeta != null) {
DyeColor baseDyeColor = bannerMeta.getBaseColor();
if (baseDyeColor == null) {
baseDyeColor = MaterialUtil.getColorOf(material);
}
if (baseDyeColor != null) {
int basecolor = baseDyeColor
.getColor()
.asRGB();
sb.append("basecolor:").append(basecolor).append(" ");
}
for (org.bukkit.block.banner.Pattern p : bannerMeta.getPatterns()) {
String type = p.getPattern().getIdentifier();
int color = p.getColor().getColor().asRGB();
sb.append(type).append(",").append(color).append(" ");
}
}
}
} else if (MaterialUtil.isLeatherArmor(material)) {
LeatherArmorMeta leatherArmorMeta = (LeatherArmorMeta) is.getItemMeta();
int rgb = leatherArmorMeta.getColor().asRGB();
sb.append("color:").append(rgb).append(" ");
}
return sb.toString().trim().replaceAll("§", "&");
}
@Override
public boolean isReady() {
return ready;
}
}
@@ -0,0 +1,278 @@
package com.earth2me.essentials.items;
import com.earth2me.essentials.ManagedFile;
import com.earth2me.essentials.utils.MaterialUtil;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.ess3.api.IEssentials;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData;
import java.util.*;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import static com.earth2me.essentials.I18n.tl;
public class FlatItemDb extends AbstractItemDb {
protected static final Logger LOGGER = Logger.getLogger("Essentials");
private static Gson gson = new Gson();
private final transient IEssentials ess;
// Maps primary name to ItemData
private final transient Map<String, ItemData> items = new HashMap<>();
// Maps alias to primary name
private final transient Map<String, String> itemAliases = new HashMap<>();
// Every known alias
private final transient Set<String> allAliases = new HashSet<>();
private transient ManagedFile file = null;
public FlatItemDb(final IEssentials ess) {
this.ess = ess;
}
@Override
public void reloadConfig() {
if (file == null) {
file = new ManagedFile("items.json", ess);
}
this.rebuild();
LOGGER.info(String.format("Loaded %s items from items.json.", listNames().size()));
}
private void rebuild() {
this.reset();
String json = file.getLines().stream()
.filter(line -> !line.startsWith("#"))
.collect(Collectors.joining());
this.loadJSON(String.join("\n", json));
ready = true;
}
private void reset() {
ready = false;
items.clear();
itemAliases.clear();
allAliases.clear();
}
public void loadJSON(String source) {
JsonObject map = (new JsonParser()).parse(source).getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : map.entrySet()) {
String key = entry.getKey();
JsonElement element = entry.getValue();
boolean valid = false;
if (element.isJsonObject()) {
ItemData data = gson.fromJson(element, ItemData.class);
items.put(key, data);
valid = true;
} else {
try {
String target = element.getAsString();
itemAliases.put(key, target);
valid = true;
} catch (Exception ignored) {}
}
if (valid) {
allAliases.add(key);
} else {
LOGGER.warning(String.format("Failed to add item: \"%s\": %s", key, element.toString()));
}
}
}
@Override
public ItemStack get(String id) throws Exception {
id = id.toLowerCase();
final String[] split = id.split(":");
ItemData data = getByName(split[0]);
if (data == null) {
throw new Exception(tl("unknownItemName", id));
}
Material material = data.getMaterial();
if (!material.isItem()) throw new Exception(tl("unableToSpawnItem", id));
ItemStack stack = new ItemStack(material);
stack.setAmount(material.getMaxStackSize());
PotionData potionData = data.getPotionData();
ItemMeta meta = stack.getItemMeta();
if (potionData != null && meta instanceof PotionMeta) {
PotionMeta potionMeta = (PotionMeta) meta;
potionMeta.setBasePotionData(potionData);
}
// For some reason, Damageable doesn't extend ItemMeta but CB implements them in the same
// class. As to why, your guess is as good as mine.
if (split.length > 1 && meta instanceof Damageable) {
Damageable damageMeta = (Damageable) meta;
damageMeta.setDamage(Integer.parseInt(split[1]));
}
stack.setItemMeta(meta);
// The spawner provider will update the meta again, so we need to call it after
// setItemMeta to prevent a race condition
EntityType entity = data.getEntity();
if (entity != null && material.toString().contains("SPAWNER")) {
ess.getSpawnerProvider().setEntityType(stack, entity);
}
return stack;
}
private ItemData getByName(String name) {
name = name.toLowerCase();
if (items.containsKey(name)) {
return items.get(name);
} else if (itemAliases.containsKey(name)) {
return items.get(itemAliases.get(name));
}
return null;
}
@Override
public List<String> nameList(ItemStack item) {
List<String> names = new ArrayList<>();
String primaryName = name(item);
names.add(primaryName);
for (Map.Entry<String, String> entry : itemAliases.entrySet()) {
if (entry.getValue().equalsIgnoreCase(primaryName)) {
names.add(entry.getKey());
}
}
return names;
}
@Override
public String name(ItemStack item) {
ItemData data = lookup(item);
for (Map.Entry<String, ItemData> entry : items.entrySet()) {
if (entry.getValue().equals(data)) {
return entry.getKey();
}
}
return null;
}
@Override
@Deprecated
public int getLegacyId(Material material) throws Exception {
throw new UnsupportedOperationException("Legacy IDs aren't supported on this version.");
}
public ItemData lookup(ItemStack item) {
Material type = item.getType();
if (MaterialUtil.isPotion(type) && item.getItemMeta() instanceof PotionMeta) {
PotionData potion = ((PotionMeta) item.getItemMeta()).getBasePotionData();
return new ItemData(type, potion);
} else if (type.toString().contains("SPAWNER")) {
EntityType entity = ess.getSpawnerProvider().getEntityType(item);
return new ItemData(type, entity);
} else {
return new ItemData(type);
}
}
@Override
public Collection<String> listNames() {
return Collections.unmodifiableSet(allAliases);
}
public static class ItemData {
private final Material material;
private PotionData potionData = null;
private EntityType entity = null;
public ItemData(Material material) {
this.material = material;
}
public ItemData(Material material, PotionData potionData) {
this.material = material;
this.potionData = potionData;
}
public ItemData(Material material, EntityType entity) {
this.material = material;
this.entity = entity;
}
@Override
public int hashCode() {
return (31 * material.hashCode()) ^ potionData.hashCode();
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (!(o instanceof ItemData)) {
return false;
}
ItemData that = (ItemData) o;
return this.material == that.getMaterial() && potionDataEquals(that) && entityEquals(that);
}
public Material getMaterial() {
return material;
}
public PotionData getPotionData() {
return this.potionData;
}
public EntityType getEntity() {
return this.entity;
}
private boolean potionDataEquals(ItemData o) {
if (this.potionData == null && o.getPotionData() == null) {
return true;
} else if (this.potionData != null && o.getPotionData() != null) {
return this.potionData.equals(o.getPotionData());
} else {
return false;
}
}
private boolean entityEquals(ItemData o) {
if (this.entity == null && o.getEntity() == null) { // neither have an entity
return true;
} else if (this.entity != null && o.getEntity() != null) { // both have an entity; check if it's the same one
return this.entity.equals(o.getEntity());
} else { // one has an entity but the other doesn't, so they can't be equal
return false;
}
}
}
}
@@ -0,0 +1,298 @@
package com.earth2me.essentials.items;
import com.earth2me.essentials.ManagedFile;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials;
import net.ess3.nms.refl.ReflUtil;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.earth2me.essentials.I18n.tl;
public class LegacyItemDb extends AbstractItemDb {
protected static final Logger LOGGER = Logger.getLogger("Essentials");
private final transient IEssentials ess;
private final transient Map<String, Integer> items = new HashMap<>();
private final transient Map<ItemData, List<String>> names = new HashMap<>();
private final transient Map<ItemData, String> primaryName = new HashMap<>();
private final transient Map<Integer, ItemData> legacyIds = new HashMap<>();
private final transient Map<String, Short> durabilities = new HashMap<>();
private final transient Map<String, String> nbtData = new HashMap<>();
private final transient ManagedFile file;
private final transient Pattern splitPattern = Pattern.compile("((.*)[:+',;.](\\d+))");
private final transient Pattern csvSplitPattern = Pattern.compile("(\"([^\"]*)\"|[^,]*)(,|$)");
public LegacyItemDb(final IEssentials ess) {
this.ess = ess;
file = new ManagedFile("items.csv", ess);
}
@Override
public void reloadConfig() {
final List<String> lines = file.getLines();
if (lines.isEmpty()) {
return;
}
ready = false;
durabilities.clear();
items.clear();
names.clear();
primaryName.clear();
for (String line : lines) {
if (line.length() > 0 && line.charAt(0) == '#') {
continue;
}
String itemName = null;
int numeric = -1;
short data = 0;
String nbt = null;
int col = 0;
Matcher matcher = csvSplitPattern.matcher(line);
while (matcher.find()) {
String match = matcher.group(1);
if (StringUtils.stripToNull(match) == null) {
continue;
}
match = StringUtils.strip(match.trim(), "\"");
switch (col) {
case 0:
itemName = match.toLowerCase(Locale.ENGLISH);
break;
case 1:
numeric = Integer.parseInt(match);
break;
case 2:
data = Short.parseShort(match);
break;
case 3:
nbt = StringUtils.stripToNull(match);
break;
default:
continue;
}
col++;
}
// Invalid row
if (itemName == null || numeric < 0) {
continue;
}
durabilities.put(itemName, data);
items.put(itemName, numeric);
if (nbt != null) {
nbtData.put(itemName, nbt);
}
ItemData itemData = new ItemData(numeric, data);
if (names.containsKey(itemData)) {
List<String> nameList = names.get(itemData);
nameList.add(itemName);
} else {
List<String> nameList = new ArrayList<>();
nameList.add(itemName);
names.put(itemData, nameList);
primaryName.put(itemData, itemName);
}
legacyIds.put(numeric, itemData);
}
for (List<String> nameList : names.values()) {
Collections.sort(nameList, LengthCompare.INSTANCE);
}
LOGGER.info(String.format("Loaded %s items from items.csv.", listNames().size()));
ready = true;
}
@Override
public ItemStack get(final String id) throws Exception {
int itemid = 0;
String itemname;
short metaData = 0;
Matcher parts = splitPattern.matcher(id);
if (parts.matches()) {
itemname = parts.group(2);
metaData = Short.parseShort(parts.group(3));
} else {
itemname = id;
}
if (NumberUtil.isInt(itemname)) {
itemid = Integer.parseInt(itemname);
} else if (NumberUtil.isInt(id)) {
itemid = Integer.parseInt(id);
} else {
itemname = itemname.toLowerCase(Locale.ENGLISH);
}
if (itemid < 1) {
if (items.containsKey(itemname)) {
itemid = items.get(itemname);
if (durabilities.containsKey(itemname) && metaData == 0) {
metaData = durabilities.get(itemname);
}
}
}
if (itemid < 1) {
Material matFromName = EnumUtil.getMaterial(itemname.toUpperCase());
if (matFromName != null) {
itemid = matFromName.getId();
}
}
if (itemid < 1) {
throw new Exception(tl("unknownItemName", itemname));
}
ItemData data = legacyIds.get(itemid);
if (data == null) {
throw new Exception(tl("unknownItemId", itemid));
}
Material mat = getFromLegacy(itemid, (byte) metaData);
ItemStack retval = new ItemStack(mat);
if (nbtData.containsKey(itemname)) {
String nbt = nbtData.get(itemname);
if (nbt.startsWith("*")) {
nbt = nbtData.get(nbt.substring(1));
}
retval = ess.getServer().getUnsafe().modifyItemStack(retval, nbt);
}
Material MOB_SPAWNER = EnumUtil.getMaterial("SPAWNER", "MOB_SPAWNER");
if (mat == MOB_SPAWNER) {
if (metaData == 0) metaData = EntityType.PIG.getTypeId();
try {
retval = ess.getSpawnerProvider().setEntityType(retval, EntityType.fromId(metaData));
} catch (IllegalArgumentException e) {
throw new Exception("Can't spawn entity ID " + metaData + " from mob spawners.");
}
} else if (mat.name().contains("MONSTER_EGG")) {
EntityType type;
try {
type = EntityType.fromId(metaData);
} catch (IllegalArgumentException e) {
throw new Exception("Can't spawn entity ID " + metaData + " from spawn eggs.");
}
retval = ess.getSpawnEggProvider().createEggItem(type);
} else if (mat.name().endsWith("POTION")
&& ReflUtil.getNmsVersionObject().isLowerThan(ReflUtil.V1_11_R1)) { // Only apply this to pre-1.11 as items.csv might only work in 1.11
retval = ess.getPotionMetaProvider().createPotionItem(mat, metaData);
} else {
retval.setDurability(metaData);
}
retval.setAmount(mat.getMaxStackSize());
return retval;
}
@Override
public List<String> nameList(ItemStack item) {
ItemData itemData = new ItemData(item.getType().getId(), item.getDurability());
List<String> nameList = names.get(itemData);
if (nameList == null) {
itemData = new ItemData(item.getType().getId(), (short) 0);
nameList = names.get(itemData);
if (nameList == null) {
return null;
}
}
return Collections.unmodifiableList(nameList);
}
@Override
public String name(ItemStack item) {
ItemData itemData = new ItemData(item.getType().getId(), item.getDurability());
String name = primaryName.get(itemData);
if (name == null) {
itemData = new ItemData(item.getType().getId(), (short) 0);
name = primaryName.get(itemData);
if (name == null) {
return null;
}
}
return name;
}
@Override
public int getLegacyId(Material material) throws Exception {
for(Map.Entry<String, Integer> entry : items.entrySet()) {
if(material.name().toLowerCase(Locale.ENGLISH).equalsIgnoreCase(entry.getKey())) {
return entry.getValue();
}
}
throw new Exception("Itemid not found for material: " + material.name());
}
@Override
public Collection<String> listNames() {
return primaryName.values();
}
static class ItemData {
private int itemNo;
final private short itemData;
ItemData(final int itemNo, final short itemData) {
this.itemNo = itemNo;
this.itemData = itemData;
}
public int getItemNo() {
return itemNo;
}
public short getItemData() {
return itemData;
}
@Override
public int hashCode() {
return (31 * itemNo) ^ itemData;
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (!(o instanceof ItemData)) {
return false;
}
ItemData pairo = (ItemData) o;
return this.itemNo == pairo.getItemNo() && this.itemData == pairo.getItemData();
}
}
static class LengthCompare implements java.util.Comparator<String> {
private static final LengthCompare INSTANCE = new LengthCompare();
public LengthCompare() {
super();
}
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
}
@@ -2,7 +2,6 @@ package com.earth2me.essentials.messaging;
import static com.earth2me.essentials.I18n.tl;
import com.earth2me.essentials.Console;
import com.earth2me.essentials.IEssentials;
import com.earth2me.essentials.IUser;
import com.earth2me.essentials.User;
@@ -17,7 +16,7 @@ import java.lang.ref.WeakReference;
* <li>{@link IMessageRecipient#getReplyRecipient()}</li>
* <li>{@link IMessageRecipient#setReplyRecipient(IMessageRecipient)}</li>
* </ul>
*
*
* <b>The given {@code parent} must implement the following methods to prevent overflow:</b>
* <ul>
* <li>{@link IMessageRecipient#sendMessage(String)}</li>
@@ -25,14 +24,14 @@ import java.lang.ref.WeakReference;
* <li>{@link IMessageRecipient#getDisplayName()}</li>
* <li>{@link IMessageRecipient#isReachable()}</li>
* </ul>
*
*
* The reply-recipient is wrapped in a {@link WeakReference}.
*/
public class SimpleMessageRecipient implements IMessageRecipient {
private final IEssentials ess;
private final IMessageRecipient parent;
private long lastMessageMs;
private WeakReference<IMessageRecipient> replyRecipient;
@@ -42,7 +41,7 @@ public class SimpleMessageRecipient implements IMessageRecipient {
}
return recipient instanceof User ? (User) recipient : null;
}
public SimpleMessageRecipient(IEssentials ess, IMessageRecipient parent) {
this.ess = ess;
this.parent = parent;
@@ -117,13 +116,12 @@ public class SimpleMessageRecipient implements IMessageRecipient {
if (!isReachable()) {
return MessageResponse.UNREACHABLE;
}
User user = getUser(this);
boolean afk = false;
if (user != null) {
if (user.isIgnoreMsg()
&& !(sender instanceof Console)) { // Console must never be ignored.
return MessageResponse.MESSAGES_IGNORED;
if (user.isIgnoreMsg() && sender instanceof IUser && !((IUser) sender).isAuthorized("essentials.msgtoggle.bypass")) { // Don't ignore console and senders with permission
return MessageResponse.MESSAGES_IGNORED;
}
afk = user.isAfk();
// Check whether this recipient ignores the sender, only if the sender is not the console.
@@ -138,7 +136,7 @@ public class SimpleMessageRecipient implements IMessageRecipient {
// If this recipient doesn't have a reply recipient, initiate by setting the first
// message sender to this recipient's replyRecipient.
long timeout = ess.getSettings().getLastMessageReplyRecipientTimeout() * 1000;
if (getReplyRecipient() == null || !getReplyRecipient().isReachable()
if (getReplyRecipient() == null || !getReplyRecipient().isReachable()
|| System.currentTimeMillis() - this.lastMessageMs > timeout) {
setReplyRecipient(sender);
}
File diff suppressed because it is too large. Load diff
@@ -13,7 +13,7 @@ public class PermissionsHandler implements IPermissionsHandler {
private transient IPermissionsHandler handler = null;
private transient String defaultGroup = "default";
private final transient Essentials ess;
private transient boolean useSuperperms = false;
private transient boolean useSuperperms;
private Class<?> lastHandler = null;
@@ -92,10 +92,7 @@ public class PermissionsHandler implements IPermissionsHandler {
public void checkPermissions() {
// load and assign a handler
List<Class<? extends SuperpermsHandler>> providerClazz = Arrays.asList(
BPermissions2Handler.class,
PermissionsExHandler.class,
PrivilegesHandler.class,
SimplyPermsHandler.class,
GenericVaultHandler.class,
SuperpermsHandler.class
);
@@ -158,7 +155,4 @@ public class PermissionsHandler implements IPermissionsHandler {
}
}
private void checkPermLag(long start) {
checkPermLag(start, "not defined");
}
}
@@ -13,7 +13,7 @@ public abstract class AbstractVaultHandler extends SuperpermsHandler {
protected static Permission perms = null;
protected static Chat chat = null;
public boolean setupProviders() {
private boolean setupProviders() {
try {
Class.forName("net.milkbowl.vault.permission.Permission");
Class.forName("net.milkbowl.vault.chat.Chat");
@@ -65,7 +65,7 @@ public abstract class AbstractVaultHandler extends SuperpermsHandler {
}
}
protected boolean canLoad() {
boolean canLoad() {
if (Bukkit.getPluginManager().getPlugin("Vault") == null) return false;
try {
return setupProviders();
@@ -1,17 +0,0 @@
package com.earth2me.essentials.perm.impl;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class BPermissions2Handler extends AbstractVaultHandler {
@Override
public boolean canBuild(final Player base, final String group) {
return hasPermission(base, "bPermissions.build");
}
@Override
public boolean tryProvider() {
return super.canLoad() && Bukkit.getPluginManager().getPlugin("bPermissions") != null;
}
}
@@ -1,16 +0,0 @@
package com.earth2me.essentials.perm.impl;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class PrivilegesHandler extends AbstractVaultHandler {
@Override
public boolean canBuild(Player base, String group) {
return hasPermission(base, "privileges.build");
}
@Override
public boolean tryProvider() {
return super.canLoad() && Bukkit.getPluginManager().getPlugin("Privileges") != null;
}
}
@@ -1,16 +0,0 @@
package com.earth2me.essentials.perm.impl;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class SimplyPermsHandler extends AbstractVaultHandler {
@Override
public boolean canBuild(Player base, String group) {
return hasPermission(base, "permissions.allow.build");
}
@Override
public boolean tryProvider() {
return super.canLoad() && Bukkit.getPluginManager().getPlugin("SimplyPerms") != null;
}
}
@@ -5,10 +5,10 @@ import org.bukkit.plugin.Plugin;
/**
* Interface to be implemented by a payment method.
* Copyright (C) 2011
* AOL license <http://aol.nexua.org>
*
* @author Nijikokun <nijikokun@shortmail.com> (@nijikokun)
* @copyright Copyright (C) 2011
* @license AOL license <http://aol.nexua.org>
*/
public interface Method {
/**
@@ -22,7 +22,7 @@ import java.util.Set;
* preferred: "iConomy"
* </pre></blockquote>
*
* @author: Nijikokun <nijikokun@shortmail.com> (@nijikokun) @copyright: Copyright (C) 2011 @license: AOL license
* @author Nijikokun <nijikokun@shortmail.com> (@nijikokun) @copyright: Copyright (C) 2011 @license: AOL license
* <http://aol.nexua.org>
*/
public class Methods {
@@ -30,9 +30,9 @@ public class Methods {
private static boolean self = false;
private static Method Method = null;
private static String preferred = "";
private static final Set<Method> Methods = new HashSet<Method>();
private static final Set<String> Dependencies = new HashSet<String>();
private static final Set<Method> Attachables = new HashSet<Method>();
private static final Set<Method> Methods = new HashSet<>();
private static final Set<String> Dependencies = new HashSet<>();
private static final Set<Method> Attachables = new HashSet<>();
static {
_init();
@@ -42,11 +42,6 @@ public class Methods {
* Implement all methods along with their respective name & class.
*/
private static void _init() {
addMethod("iConomy", new com.earth2me.essentials.register.payment.methods.iCo6());
addMethod("iConomy", new com.earth2me.essentials.register.payment.methods.iCo5());
addMethod("BOSEconomy", new com.earth2me.essentials.register.payment.methods.BOSE7());
addMethod("Currency", new com.earth2me.essentials.register.payment.methods.MCUR());
Dependencies.add("MultiCurrency");
addMethod("Vault", new com.earth2me.essentials.register.payment.methods.VaultEco());
}
@@ -84,7 +79,7 @@ public class Methods {
*
* @return <code>Set<String></code> - Array of payment methods that are loaded.
*
* @see #setMethod(org.bukkit.plugin.Plugin)
* @see #setMethod(PluginManager)
*/
public static Set<String> getDependencies() {
return Dependencies;
@@ -119,8 +114,8 @@ public class Methods {
*
* @return <code>boolean</code>
*
* @see #setMethod(org.bukkit.plugin.Plugin)
* @see #checkDisabled(org.bukkit.plugin.Plugin)
* @see #setMethod(PluginManager)
* @see #checkDisabled(Plugin)
*/
public static boolean hasMethod() {
return (Method != null);
@@ -129,7 +124,7 @@ public class Methods {
/**
* Checks Plugin Class against a multitude of checks to verify it's usability as a payment method.
*
* @param <code>PluginManager</code> the plugin manager for the server
* @param manager the plugin manager for the server
*
* @return <code>boolean</code> True on success, False on failure.
*/
@@ -145,7 +140,7 @@ public class Methods {
int count = 0;
boolean match = false;
Plugin plugin = null;
Plugin plugin;
for (String name : getDependencies()) {
if (hasMethod()) {
@@ -1,271 +0,0 @@
package com.earth2me.essentials.register.payment.methods;
import com.earth2me.essentials.register.payment.Method;
import cosine.boseconomy.BOSEconomy;
import org.bukkit.plugin.Plugin;
/**
* BOSEconomy 7 Implementation of Method
*
* @author Acrobot
* @author Nijikokun <nijikokun@shortmail.com> (@nijikokun) @copyright (c) 2011 @license AOL license
* <http://aol.nexua.org>
*/
public class BOSE7 implements Method {
private BOSEconomy BOSEconomy;
@Override
public BOSEconomy getPlugin() {
return this.BOSEconomy;
}
@Override
public String getName() {
return "BOSEconomy";
}
@Override
public String getLongName() {
return getName();
}
@Override
public String getVersion() {
return "0.7.0";
}
@Override
public int fractionalDigits() {
return this.BOSEconomy.getFractionalDigits();
}
@Override
public String format(double amount) {
String currency = this.BOSEconomy.getMoneyNamePlural();
if (amount == 1) {
currency = this.BOSEconomy.getMoneyName();
}
return amount + " " + currency;
}
@Override
public boolean hasBanks() {
return true;
}
@Override
public boolean hasBank(String bank) {
return this.BOSEconomy.bankExists(bank);
}
@Override
public boolean hasAccount(String name) {
return this.BOSEconomy.playerRegistered(name, false);
}
@Override
public boolean hasBankAccount(String bank, String name) {
return this.BOSEconomy.isBankOwner(bank, name) || this.BOSEconomy.isBankMember(bank, name);
}
@Override
public boolean createAccount(String name) {
if (hasAccount(name)) {
return false;
}
this.BOSEconomy.registerPlayer(name);
return true;
}
@Override
public boolean createAccount(String name, Double balance) {
if (hasAccount(name)) {
return false;
}
this.BOSEconomy.registerPlayer(name);
this.BOSEconomy.setPlayerMoney(name, balance, false);
return true;
}
@Override
public MethodAccount getAccount(String name) {
if (!hasAccount(name)) {
return null;
}
return new BOSEAccount(name, this.BOSEconomy);
}
@Override
public MethodBankAccount getBankAccount(String bank, String name) {
if (!hasBankAccount(bank, name)) {
return null;
}
return new BOSEBankAccount(bank, BOSEconomy);
}
@Override
public boolean isCompatible(Plugin plugin) {
return plugin.getDescription().getName().equalsIgnoreCase("boseconomy") && plugin instanceof BOSEconomy && !plugin.getDescription().getVersion().equals("0.6.2");
}
@Override
public void setPlugin(Plugin plugin) {
BOSEconomy = (BOSEconomy) plugin;
}
public class BOSEAccount implements MethodAccount {
private final String name;
private final BOSEconomy BOSEconomy;
public BOSEAccount(String name, BOSEconomy bOSEconomy) {
this.name = name;
this.BOSEconomy = bOSEconomy;
}
@Override
public double balance() {
return this.BOSEconomy.getPlayerMoneyDouble(this.name);
}
@Override
public boolean set(double amount) {
return this.BOSEconomy.setPlayerMoney(this.name, amount, false);
}
@Override
public boolean add(double amount) {
return this.BOSEconomy.addPlayerMoney(this.name, amount, false);
}
@Override
public boolean subtract(double amount) {
double balance = this.balance();
return this.BOSEconomy.setPlayerMoney(this.name, (balance - amount), false);
}
@Override
public boolean multiply(double amount) {
double balance = this.balance();
return this.BOSEconomy.setPlayerMoney(this.name, (balance * amount), false);
}
@Override
public boolean divide(double amount) {
double balance = this.balance();
return this.BOSEconomy.setPlayerMoney(this.name, (balance / amount), false);
}
@Override
public boolean hasEnough(double amount) {
return (this.balance() >= amount);
}
@Override
public boolean hasOver(double amount) {
return (this.balance() > amount);
}
@Override
public boolean hasUnder(double amount) {
return (this.balance() < amount);
}
@Override
public boolean isNegative() {
return (this.balance() < 0);
}
@Override
public boolean remove() {
return false;
}
}
public class BOSEBankAccount implements MethodBankAccount {
private final String bank;
private final BOSEconomy BOSEconomy;
public BOSEBankAccount(String bank, BOSEconomy bOSEconomy) {
this.bank = bank;
this.BOSEconomy = bOSEconomy;
}
@Override
public String getBankName() {
return this.bank;
}
@Override
public int getBankId() {
return -1;
}
@Override
public double balance() {
return this.BOSEconomy.getBankMoneyDouble(bank);
}
@Override
public boolean set(double amount) {
return this.BOSEconomy.setBankMoney(bank, amount, true);
}
@Override
public boolean add(double amount) {
double balance = this.balance();
return this.BOSEconomy.setBankMoney(bank, (balance + amount), false);
}
@Override
public boolean subtract(double amount) {
double balance = this.balance();
return this.BOSEconomy.setBankMoney(bank, (balance - amount), false);
}
@Override
public boolean multiply(double amount) {
double balance = this.balance();
return this.BOSEconomy.setBankMoney(bank, (balance * amount), false);
}
@Override
public boolean divide(double amount) {
double balance = this.balance();
return this.BOSEconomy.setBankMoney(bank, (balance / amount), false);
}
@Override
public boolean hasEnough(double amount) {
return (this.balance() >= amount);
}
@Override
public boolean hasOver(double amount) {
return (this.balance() > amount);
}
@Override
public boolean hasUnder(double amount) {
return (this.balance() < amount);
}
@Override
public boolean isNegative() {
return (this.balance() < 0);
}
@Override
public boolean remove() {
return this.BOSEconomy.removeBank(bank);
}
}
}
@@ -1,163 +0,0 @@
package com.earth2me.essentials.register.payment.methods;
import com.earth2me.essentials.register.payment.Method;
import me.ashtheking.currency.Currency;
import me.ashtheking.currency.CurrencyList;
import org.bukkit.plugin.Plugin;
/**
* MultiCurrency Method implementation.
*
* @author Acrobot @copyright (c) 2011 @license AOL license <http://aol.nexua.org>
*/
public class MCUR implements Method {
private Currency currencyList;
@Override
public Object getPlugin() {
return this.currencyList;
}
@Override
public String getName() {
return "MultiCurrency";
}
@Override
public String getLongName() {
return getName();
}
@Override
public String getVersion() {
return "0.09";
}
@Override
public int fractionalDigits() {
return -1;
}
@Override
public String format(double amount) {
return amount + " Currency";
}
@Override
public boolean hasBanks() {
return false;
}
@Override
public boolean hasBank(String bank) {
return false;
}
@Override
public boolean hasAccount(String name) {
return true;
}
@Override
public boolean hasBankAccount(String bank, String name) {
return false;
}
@Override
public boolean createAccount(String name) {
CurrencyList.setValue((String) CurrencyList.maxCurrency(name)[0], name, 0);
return true;
}
@Override
public boolean createAccount(String name, Double balance) {
CurrencyList.setValue((String) CurrencyList.maxCurrency(name)[0], name, balance);
return true;
}
@Override
public MethodAccount getAccount(String name) {
return new MCurrencyAccount(name);
}
@Override
public MethodBankAccount getBankAccount(String bank, String name) {
return null;
}
@Override
public boolean isCompatible(Plugin plugin) {
return (plugin.getDescription().getName().equalsIgnoreCase("Currency") || plugin.getDescription().getName().equalsIgnoreCase("MultiCurrency")) && plugin instanceof Currency;
}
@Override
public void setPlugin(Plugin plugin) {
currencyList = (Currency) plugin;
}
public class MCurrencyAccount implements MethodAccount {
private final String name;
public MCurrencyAccount(String name) {
this.name = name;
}
@Override
public double balance() {
return CurrencyList.getValue((String) CurrencyList.maxCurrency(name)[0], name);
}
@Override
public boolean set(double amount) {
CurrencyList.setValue((String) CurrencyList.maxCurrency(name)[0], name, amount);
return true;
}
@Override
public boolean add(double amount) {
return CurrencyList.add(name, amount);
}
@Override
public boolean subtract(double amount) {
return CurrencyList.subtract(name, amount);
}
@Override
public boolean multiply(double amount) {
return CurrencyList.multiply(name, amount);
}
@Override
public boolean divide(double amount) {
return CurrencyList.divide(name, amount);
}
@Override
public boolean hasEnough(double amount) {
return CurrencyList.hasEnough(name, amount);
}
@Override
public boolean hasOver(double amount) {
return CurrencyList.hasOver(name, amount);
}
@Override
public boolean hasUnder(double amount) {
return CurrencyList.hasUnder(name, amount);
}
@Override
public boolean isNegative() {
return CurrencyList.isNegative(name);
}
@Override
public boolean remove() {
return CurrencyList.remove(name);
}
}
}
@@ -1,18 +1,17 @@
package com.earth2me.essentials.register.payment.methods;
import com.earth2me.essentials.register.payment.Method;
import net.milkbowl.vault.Vault;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
public class VaultEco implements Method {
private Vault vault;
private Plugin vault;
private Economy economy;
@Override
public Vault getPlugin() {
public Plugin getPlugin() {
return this.vault;
}
@@ -108,17 +107,15 @@ public class VaultEco implements Method {
public boolean isCompatible(Plugin plugin) {
try {
RegisteredServiceProvider<Economy> ecoPlugin = plugin.getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
return plugin instanceof Vault && ecoPlugin != null && !ecoPlugin.getProvider().getName().equals("Essentials Economy");
} catch (LinkageError e) {
return false;
} catch (Exception e) {
return plugin.getName().equals("Vault") && ecoPlugin != null && !ecoPlugin.getProvider().getName().equals("Essentials Economy");
} catch (LinkageError | Exception e) {
return false;
}
}
@Override
public void setPlugin(Plugin plugin) {
this.vault = (Vault) plugin;
this.vault = plugin;
RegisteredServiceProvider<Economy> economyProvider = this.vault.getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if (economyProvider != null) {
this.economy = economyProvider.getProvider();
@@ -130,7 +127,7 @@ public class VaultEco implements Method {
private final String name;
private final Economy economy;
public VaultAccount(String name, Economy economy) {
VaultAccount(String name, Economy economy) {
this.name = name;
this.economy = economy;
}
@@ -1,312 +0,0 @@
package com.earth2me.essentials.register.payment.methods;
import com.earth2me.essentials.register.payment.Method;
import com.iConomy.iConomy;
import com.iConomy.system.Account;
import com.iConomy.system.BankAccount;
import com.iConomy.system.Holdings;
import com.iConomy.util.Constants;
import org.bukkit.plugin.Plugin;
/**
* iConomy 5 Implementation of Method
*
* @author Nijikokun <nijikokun@shortmail.com> (@nijikokun) @copyright (c) 2011 @license AOL license
* <http://aol.nexua.org>
*/
public class iCo5 implements Method {
private iConomy iConomy;
@Override
public iConomy getPlugin() {
return this.iConomy;
}
@Override
public String getName() {
return "iConomy";
}
@Override
public String getLongName() {
return getName();
}
@Override
public String getVersion() {
return "5";
}
@Override
public int fractionalDigits() {
return 2;
}
@Override
public String format(double amount) {
return com.iConomy.iConomy.format(amount);
}
@Override
public boolean hasBanks() {
return Constants.Banking;
}
@Override
public boolean hasBank(String bank) {
return (hasBanks()) && com.iConomy.iConomy.Banks.exists(bank);
}
@Override
public boolean hasAccount(String name) {
return com.iConomy.iConomy.hasAccount(name);
}
@Override
public boolean hasBankAccount(String bank, String name) {
return (hasBank(bank)) && com.iConomy.iConomy.getBank(bank).hasAccount(name);
}
@Override
public boolean createAccount(String name) {
if (hasAccount(name)) {
return false;
}
return com.iConomy.iConomy.Accounts.create(name);
}
@Override
public boolean createAccount(String name, Double balance) {
if (hasAccount(name)) {
return false;
}
if (!com.iConomy.iConomy.Accounts.create(name)) {
return false;
}
getAccount(name).set(balance);
return true;
}
@Override
public MethodAccount getAccount(String name) {
return new iCoAccount(com.iConomy.iConomy.getAccount(name));
}
@Override
public MethodBankAccount getBankAccount(String bank, String name) {
return new iCoBankAccount(com.iConomy.iConomy.getBank(bank).getAccount(name));
}
@Override
public boolean isCompatible(Plugin plugin) {
return plugin.getDescription().getName().equalsIgnoreCase("iconomy") && plugin.getClass().getName().equals("com.iConomy.iConomy") && plugin instanceof iConomy;
}
@Override
public void setPlugin(Plugin plugin) {
iConomy = (iConomy) plugin;
}
public class iCoAccount implements MethodAccount {
private final Account account;
private final Holdings holdings;
public iCoAccount(Account account) {
this.account = account;
this.holdings = account.getHoldings();
}
public Account getiCoAccount() {
return account;
}
@Override
public double balance() {
return this.holdings.balance();
}
@Override
public boolean set(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.set(amount);
return true;
}
@Override
public boolean add(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.add(amount);
return true;
}
@Override
public boolean subtract(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.subtract(amount);
return true;
}
@Override
public boolean multiply(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.multiply(amount);
return true;
}
@Override
public boolean divide(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.divide(amount);
return true;
}
@Override
public boolean hasEnough(double amount) {
return this.holdings.hasEnough(amount);
}
@Override
public boolean hasOver(double amount) {
return this.holdings.hasOver(amount);
}
@Override
public boolean hasUnder(double amount) {
return this.holdings.hasUnder(amount);
}
@Override
public boolean isNegative() {
return this.holdings.isNegative();
}
@Override
public boolean remove() {
if (this.account == null) {
return false;
}
this.account.remove();
return true;
}
}
public class iCoBankAccount implements MethodBankAccount {
private final BankAccount account;
private final Holdings holdings;
public iCoBankAccount(BankAccount account) {
this.account = account;
this.holdings = account.getHoldings();
}
public BankAccount getiCoBankAccount() {
return account;
}
@Override
public String getBankName() {
return this.account.getBankName();
}
@Override
public int getBankId() {
return this.account.getBankId();
}
@Override
public double balance() {
return this.holdings.balance();
}
@Override
public boolean set(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.set(amount);
return true;
}
@Override
public boolean add(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.add(amount);
return true;
}
@Override
public boolean subtract(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.subtract(amount);
return true;
}
@Override
public boolean multiply(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.multiply(amount);
return true;
}
@Override
public boolean divide(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.divide(amount);
return true;
}
@Override
public boolean hasEnough(double amount) {
return this.holdings.hasEnough(amount);
}
@Override
public boolean hasOver(double amount) {
return this.holdings.hasOver(amount);
}
@Override
public boolean hasUnder(double amount) {
return this.holdings.hasUnder(amount);
}
@Override
public boolean isNegative() {
return this.holdings.isNegative();
}
@Override
public boolean remove() {
if (this.account == null) {
return false;
}
this.account.remove();
return true;
}
}
}
@@ -1,201 +0,0 @@
package com.earth2me.essentials.register.payment.methods;
import com.earth2me.essentials.register.payment.Method;
import com.iCo6.iConomy;
import com.iCo6.system.Account;
import com.iCo6.system.Accounts;
import com.iCo6.system.Holdings;
import org.bukkit.plugin.Plugin;
/**
* iConomy 6 Implementation of Method
*
* @author Nijikokun <nijikokun@shortmail.com> (@nijikokun) @copyright (c) 2011 @license AOL license
* <http://aol.nexua.org>
*/
public class iCo6 implements Method {
private iConomy iConomy;
@Override
public iConomy getPlugin() {
return this.iConomy;
}
@Override
public String getName() {
return "iConomy";
}
@Override
public String getLongName() {
return getName();
}
@Override
public String getVersion() {
return "6";
}
@Override
public int fractionalDigits() {
return 2;
}
@Override
public String format(double amount) {
return com.iCo6.iConomy.format(amount);
}
@Override
public boolean hasBanks() {
return false;
}
@Override
public boolean hasBank(String bank) {
return false;
}
@Override
public boolean hasAccount(String name) {
return (new Accounts()).exists(name);
}
@Override
public boolean hasBankAccount(String bank, String name) {
return false;
}
@Override
public boolean createAccount(String name) {
if (hasAccount(name)) {
return false;
}
return (new Accounts()).create(name);
}
@Override
public boolean createAccount(String name, Double balance) {
if (hasAccount(name)) {
return false;
}
return (new Accounts()).create(name, balance);
}
@Override
public MethodAccount getAccount(String name) {
return new iCoAccount((new Accounts()).get(name));
}
@Override
public MethodBankAccount getBankAccount(String bank, String name) {
return null;
}
@Override
public boolean isCompatible(Plugin plugin) {
return plugin.getDescription().getName().equalsIgnoreCase("iconomy") && plugin.getClass().getName().equals("com.iCo6.iConomy") && plugin instanceof iConomy;
}
@Override
public void setPlugin(Plugin plugin) {
iConomy = (iConomy) plugin;
}
public class iCoAccount implements MethodAccount {
private final Account account;
private final Holdings holdings;
public iCoAccount(Account account) {
this.account = account;
this.holdings = account.getHoldings();
}
public Account getiCoAccount() {
return account;
}
@Override
public double balance() {
return this.holdings.getBalance();
}
@Override
public boolean set(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.setBalance(amount);
return true;
}
@Override
public boolean add(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.add(amount);
return true;
}
@Override
public boolean subtract(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.subtract(amount);
return true;
}
@Override
public boolean multiply(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.multiply(amount);
return true;
}
@Override
public boolean divide(double amount) {
if (this.holdings == null) {
return false;
}
this.holdings.divide(amount);
return true;
}
@Override
public boolean hasEnough(double amount) {
return this.holdings.hasEnough(amount);
}
@Override
public boolean hasOver(double amount) {
return this.holdings.hasOver(amount);
}
@Override
public boolean hasUnder(double amount) {
return this.holdings.hasUnder(amount);
}
@Override
public boolean isNegative() {
return this.holdings.isNegative();
}
@Override
public boolean remove() {
if (this.account == null) {
return false;
}
this.account.remove();
return true;
}
}
}
@@ -9,8 +9,7 @@ import org.bukkit.Location;
import java.util.HashMap;
import java.util.Map;
@Data @EqualsAndHashCode(callSuper = false) public class Spawns implements StorageObject {
@MapValueType(Location.class)
private Map<String, Location> spawns = new HashMap<String, Location>();
private Map<String, Location> spawns = new HashMap<>();
}
@@ -1,6 +1,7 @@
package com.earth2me.essentials.signs;
import com.earth2me.essentials.*;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
@@ -25,6 +26,7 @@ import static com.earth2me.essentials.I18n.tl;
public class EssentialsSign {
private static final Material SIGN_POST = EnumUtil.getMaterial("SIGN", "SIGN_POST");
private static final Set<Material> EMPTY_SET = new HashSet<Material>();
protected static final BigDecimal MINTRANSACTION = new BigDecimal("0.01");
protected transient final String signName;
@@ -58,9 +60,7 @@ public class EssentialsSign {
sign.setLine(0, getSuccessName(ess));
}
return ret;
} catch (ChargeException ex) {
showError(ess, user.getSource(), ex, signName);
} catch (SignException ex) {
} catch (ChargeException | SignException ex) {
showError(ess, user.getSource(), ex, signName);
}
// Return true, so the player sees the wrong sign.
@@ -115,9 +115,6 @@ public class EssentialsSign {
}
return onSignInteract(sign, user, getUsername(user), ess);
} catch (ChargeException ex) {
showError(ess, user.getSource(), ex, signName);
return false;
} catch (Exception ex) {
showError(ess, user.getSource(), ex, signName);
return false;
@@ -161,9 +158,7 @@ public class EssentialsSign {
User user = ess.getUser(player);
try {
return onBlockPlace(block, user, getUsername(user), ess);
} catch (ChargeException ex) {
showError(ess, user.getSource(), ex, signName);
} catch (SignException ex) {
} catch (ChargeException | SignException ex) {
showError(ess, user.getSource(), ex, signName);
}
return false;
@@ -173,9 +168,7 @@ public class EssentialsSign {
User user = ess.getUser(player);
try {
return onBlockInteract(block, user, getUsername(user), ess);
} catch (ChargeException ex) {
showError(ess, user.getSource(), ex, signName);
} catch (SignException ex) {
} catch (ChargeException | SignException ex) {
showError(ess, user.getSource(), ex, signName);
}
return false;
@@ -213,7 +206,7 @@ public class EssentialsSign {
protected static boolean checkIfBlockBreaksSigns(final Block block) {
final Block sign = block.getRelative(BlockFace.UP);
if (sign.getType() == Material.SIGN_POST && isValidSign(new BlockSign(sign))) {
if (sign.getType() == SIGN_POST && isValidSign(new BlockSign(sign))) {
return true;
}
final BlockFace[] directions = new BlockFace[]{BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
@@ -304,12 +297,16 @@ public class EssentialsSign {
}
protected final Trade getTrade(final ISign sign, final int amountIndex, final int itemIndex, final User player, final IEssentials ess) throws SignException {
return getTrade(sign, amountIndex, itemIndex, player, false, ess);
}
protected final Trade getTrade(final ISign sign, final int amountIndex, final int itemIndex, final User player, final boolean allowId, final IEssentials ess) throws SignException {
final String itemType = getSignText(sign, itemIndex);
if (itemType.equalsIgnoreCase("exp") || itemType.equalsIgnoreCase("xp")) {
final int amount = getIntegerPositive(getSignText(sign, amountIndex));
return new Trade(amount, ess);
}
final ItemStack item = getItemStack(itemType, 1, ess);
final ItemStack item = getItemStack(itemType, 1, allowId, ess);
final int amount = Math.min(getIntegerPositive(getSignText(sign, amountIndex)), item.getType().getMaxStackSize() * player.getBase().getInventory().getSize());
if (item.getType() == Material.AIR || amount < 1) {
throw new SignException(tl("moreThanZero"));
@@ -346,6 +343,17 @@ public class EssentialsSign {
}
protected final ItemStack getItemStack(final String itemName, final int quantity, final IEssentials ess) throws SignException {
return getItemStack(itemName, quantity, false, ess);
}
protected final ItemStack getItemStack(final String itemName, final int quantity, final boolean allowId, final IEssentials ess) throws SignException {
if (allowId && ess.getSettings().allowOldIdSigns()) {
final Material newMaterial = ess.getItemDb().getFromLegacy(itemName);
if (newMaterial != null) {
return new ItemStack(newMaterial, quantity);
}
}
try {
final ItemStack item = ess.getItemDb().get(itemName);
item.setAmount(quantity);
@@ -398,6 +406,10 @@ public class EssentialsSign {
}
protected final Trade getTrade(final ISign sign, final int index, final int decrement, final IEssentials ess) throws SignException {
return getTrade(sign, index, decrement, false, ess);
}
protected final Trade getTrade(final ISign sign, final int index, final int decrement, final boolean allowId, final IEssentials ess) throws SignException {
final String line = getSignText(sign, index);
if (line.isEmpty()) {
return new Trade(signName.toLowerCase(Locale.ENGLISH) + "sign", ess);
@@ -420,7 +432,7 @@ public class EssentialsSign {
sign.setLine(index, quantity + " exp");
return new Trade(quantity, ess);
} else {
final ItemStack stack = getItemStack(item, quantity, ess);
final ItemStack stack = getItemStack(item, quantity, allowId, ess);
sign.setLine(index, quantity + " " + item);
return new Trade(stack, ess);
}
@@ -2,6 +2,7 @@ package com.earth2me.essentials.signs;
import com.earth2me.essentials.I18n;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FormatUtil;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
@@ -22,7 +23,7 @@ import java.util.logging.Logger;
public class SignBlockListener implements Listener {
private static final Logger LOGGER = Logger.getLogger("Essentials");
private static final Material WALL_SIGN = Material.WALL_SIGN;
private static final Material SIGN_POST = Material.SIGN_POST;
private static final Material SIGN_POST = EnumUtil.getMaterial("SIGN", "SIGN_POST");
private final transient IEssentials ess;
public SignBlockListener(IEssentials ess) {
@@ -1,5 +1,6 @@
package com.earth2me.essentials.signs;
import com.earth2me.essentials.utils.EnumUtil;
import net.ess3.api.IEssentials;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -11,6 +12,8 @@ import org.bukkit.event.entity.EntityExplodeEvent;
public class SignEntityListener implements Listener {
private static final Material SIGN_POST = EnumUtil.getMaterial("SIGN", "SIGN_POST");
private final transient IEssentials ess;
public SignEntityListener(final IEssentials ess) {
@@ -25,7 +28,7 @@ public class SignEntityListener implements Listener {
}
for (Block block : event.blockList()) {
if (((block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
if (((block.getType() == Material.WALL_SIGN || block.getType() == SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
event.setCancelled(true);
return;
}
@@ -46,7 +49,7 @@ public class SignEntityListener implements Listener {
}
final Block block = event.getBlock();
if (((block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
if (((block.getType() == Material.WALL_SIGN || block.getType() == SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
event.setCancelled(true);
return;
}
@@ -54,6 +54,8 @@ public class SignGameMode extends EssentialsSign {
player.setGameMode(GameMode.CREATIVE);
} else if (mode.contains("advent") || mode.equalsIgnoreCase("2")) {
player.setGameMode(GameMode.ADVENTURE);
} else if (mode.contains("spec") || mode.equalsIgnoreCase("3")) {
player.setGameMode(GameMode.SPECTATOR);
} else {
throw new SignException(tl("invalidSignLine", 2));
}
@@ -1,5 +1,6 @@
package com.earth2me.essentials.signs;
import com.earth2me.essentials.utils.MaterialUtil;
import net.ess3.api.IEssentials;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -54,7 +55,7 @@ public class SignPlayerListener implements Listener {
}
final Material mat = block.getType();
if (mat == Material.SIGN_POST || mat == Material.WALL_SIGN) {
if (MaterialUtil.isSign(mat)) {
final String csign = ((Sign) block.getState()).getLine(0);
for (EssentialsSign sign : ess.getSettings().enabledSigns()) {
if (csign.equalsIgnoreCase(sign.getSuccessName(ess))) {
@@ -4,7 +4,9 @@ import com.earth2me.essentials.ChargeException;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.Trade.OverflowType;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
import org.bukkit.Location;
@@ -21,14 +23,14 @@ import static com.earth2me.essentials.I18n.tl;
@Deprecated // This sign will be removed soon
public class SignProtection extends EssentialsSign {
private final transient Set<Material> protectedBlocks = EnumSet.noneOf(Material.class);
private final transient Set<Material> protectedBlocks = EnumUtil.getAllMatching(Material.class,
"CHEST",
"FURNACE",
"BURNING_FURNACE",
"DISPENSER");
public SignProtection() {
super("Protection");
protectedBlocks.add(Material.CHEST);
protectedBlocks.add(Material.BURNING_FURNACE);
protectedBlocks.add(Material.FURNACE);
protectedBlocks.add(Material.DISPENSER);
}
@Override
@@ -103,7 +105,7 @@ public class SignProtection extends EssentialsSign {
}
private SignProtectionState checkProtectionSign(final Block block, final User user, final String username) {
if (block.getType() == Material.SIGN_POST || block.getType() == Material.WALL_SIGN) {
if (MaterialUtil.isSign(block.getType())) {
final BlockSign sign = new BlockSign(block);
if (sign.getLine(0).equals(this.getSuccessName())) { // TODO call getSuccessName(IEssentials)
return checkProtectionSign(sign, user, username);
@@ -160,7 +162,7 @@ public class SignProtection extends EssentialsSign {
public boolean isBlockProtected(final Block block) {
final Block[] faces = getAdjacentBlocks(block);
for (Block b : faces) {
if (b.getType() == Material.SIGN_POST || b.getType() == Material.WALL_SIGN) {
if (MaterialUtil.isSign(b.getType())) {
final Sign sign = (Sign) b.getState();
if (sign.getLine(0).equalsIgnoreCase("§1[Protection]")) {
return true;
@@ -170,7 +172,7 @@ public class SignProtection extends EssentialsSign {
final Block[] faceChest = getAdjacentBlocks(b);
for (Block a : faceChest) {
if (a.getType() == Material.SIGN_POST || a.getType() == Material.WALL_SIGN) {
if (MaterialUtil.isSign(a.getType())) {
final Sign sign = (Sign) a.getState();
if (sign.getLine(0).equalsIgnoreCase("§1[Protection]")) {
return true;
@@ -26,8 +26,8 @@ public class SignTrade extends EssentialsSign {
protected boolean onSignCreate(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException, ChargeException {
validateTrade(sign, 1, false, ess);
validateTrade(sign, 2, true, ess);
final Trade trade = getTrade(sign, 2, AmountType.ROUNDED, true, ess);
final Trade charge = getTrade(sign, 1, AmountType.ROUNDED, false, ess);
final Trade trade = getTrade(sign, 2, AmountType.ROUNDED, true, true, ess);
final Trade charge = getTrade(sign, 1, AmountType.ROUNDED, false, true, ess);
if (trade.getType() == charge.getType() && (trade.getType() != TradeType.ITEM || trade.getItemStack().isSimilar(charge.getItemStack()))) {
throw new SignException("You cannot trade for the same item type.");
}
@@ -44,7 +44,7 @@ public class SignTrade extends EssentialsSign {
final Trade store = rechargeSign(sign, ess, player);
Trade stored;
try {
stored = getTrade(sign, 1, AmountType.TOTAL, true, ess);
stored = getTrade(sign, 1, AmountType.TOTAL, true, true, ess);
subtractAmount(sign, 1, stored, ess);
Map<Integer, ItemStack> withdraw = stored.pay(player, OverflowType.RETURN);
@@ -62,8 +62,8 @@ public class SignTrade extends EssentialsSign {
}
Trade.log("Sign", "Trade", "Deposit", username, store, username, null, sign.getBlock().getLocation(), ess);
} else {
final Trade charge = getTrade(sign, 1, AmountType.COST, false, ess);
final Trade trade = getTrade(sign, 2, AmountType.COST, true, ess);
final Trade charge = getTrade(sign, 1, AmountType.COST, false, true, ess);
final Trade trade = getTrade(sign, 2, AmountType.COST, true, true, ess);
charge.isAffordableFor(player);
addAmount(sign, 1, charge, ess);
subtractAmount(sign, 2, trade, ess);
@@ -80,7 +80,7 @@ public class SignTrade extends EssentialsSign {
}
private Trade rechargeSign(final ISign sign, final IEssentials ess, final User player) throws SignException, ChargeException {
final Trade trade = getTrade(sign, 2, AmountType.COST, false, ess);
final Trade trade = getTrade(sign, 2, AmountType.COST, false, true, ess);
if (trade.getItemStack() != null && player.getBase().getItemInHand() != null && trade.getItemStack().getType() == player.getBase().getItemInHand().getType() && trade.getItemStack().getDurability() == player.getBase().getItemInHand().getDurability() && trade.getItemStack().getEnchantments().equals(player.getBase().getItemInHand().getEnchantments())) {
int amount = player.getBase().getItemInHand().getAmount();
amount -= amount % trade.getItemStack().getAmount();
@@ -106,8 +106,8 @@ public class SignTrade extends EssentialsSign {
if (canBreak) {
try {
final Trade stored1 = getTrade(sign, 1, AmountType.TOTAL, false, ess);
final Trade stored2 = getTrade(sign, 2, AmountType.TOTAL, false, ess);
final Trade stored1 = getTrade(sign, 1, AmountType.TOTAL, false, true, ess);
final Trade stored2 = getTrade(sign, 2, AmountType.TOTAL, false, true, ess);
if (!canCollect) {
Trade.log("Sign", "Trade", "Destroy", signOwner, stored2, username, stored1, sign.getBlock().getLocation(), ess);
@@ -206,6 +206,10 @@ public class SignTrade extends EssentialsSign {
}
protected final Trade getTrade(final ISign sign, final int index, final AmountType amountType, final boolean notEmpty, final IEssentials ess) throws SignException {
return getTrade(sign, index, amountType, notEmpty, false, ess);
}
protected final Trade getTrade(final ISign sign, final int index, final AmountType amountType, final boolean notEmpty, final boolean allowId, final IEssentials ess) throws SignException {
final String line = sign.getLine(index).trim();
if (line.isEmpty()) {
throw new SignException("Empty line");
@@ -237,7 +241,7 @@ public class SignTrade extends EssentialsSign {
return new Trade((amountType == AmountType.COST ? stackamount : amount), ess);
} else {
final int stackamount = getIntegerPositive(split[0]);
final ItemStack item = getItemStack(split[1], stackamount, ess);
final ItemStack item = getItemStack(split[1], stackamount, allowId, ess);
int amount = getInteger(split[2]);
if (amountType == AmountType.ROUNDED) {
amount -= amount % stackamount;
@@ -1,18 +1,23 @@
package com.earth2me.essentials.storage;
import com.earth2me.essentials.Enchantments;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.plugin.Plugin;
import org.yaml.snakeyaml.constructor.BaseConstructor;
import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
import org.yaml.snakeyaml.introspector.PropertyUtils;
import org.yaml.snakeyaml.nodes.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
@@ -30,23 +35,37 @@ public class BukkitConstructor extends CustomClassLoaderConstructor {
setPropertyUtils(propertyUtils);
}
private Method constructScalarMethod = null;
protected String constructScalarRefl(ScalarNode scalarNode) {
try {
if (constructScalarMethod == null) {
constructScalarMethod = BaseConstructor.class.getDeclaredMethod("constructScalar", ScalarNode.class);
}
return (String) constructScalarMethod.invoke(this, scalarNode);
} catch (NoSuchMethodException
| SecurityException
| IllegalAccessException
| IllegalArgumentException
| InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
private class ConstructBukkitScalar extends ConstructScalar {
@Override
public Object construct(final Node node) {
if (node.getType().equals(Material.class)) {
final String val = (String) constructScalar((ScalarNode) node);
Material mat;
if (NumberUtil.isInt(val)) {
final int typeId = Integer.parseInt(val);
mat = Material.getMaterial(typeId);
} else {
mat = Material.matchMaterial(val);
}
return mat;
final String val = constructScalarRefl((ScalarNode) node);
return Material.matchMaterial(val);
}
if (node.getType().equals(MaterialData.class)) {
final String val = (String) constructScalar((ScalarNode) node);
final String val = constructScalarRefl((ScalarNode) node);
if (val.isEmpty()) {
return null;
}
@@ -54,13 +73,9 @@ public class BukkitConstructor extends CustomClassLoaderConstructor {
if (split.length == 0) {
return null;
}
Material mat;
if (NumberUtil.isInt(split[0])) {
final int typeId = Integer.parseInt(split[0]);
mat = Material.getMaterial(typeId);
} else {
mat = Material.matchMaterial(split[0]);
}
Material mat = Material.matchMaterial(split[0]);
if (mat == null) {
return null;
}
@@ -71,7 +86,7 @@ public class BukkitConstructor extends CustomClassLoaderConstructor {
return new MaterialData(mat, data);
}
if (node.getType().equals(ItemStack.class)) {
final String val = (String) constructScalar((ScalarNode) node);
final String val = constructScalarRefl((ScalarNode) node);
if (val.isEmpty()) {
return null;
}
@@ -83,13 +98,9 @@ public class BukkitConstructor extends CustomClassLoaderConstructor {
if (split2.length == 0) {
return null;
}
Material mat;
if (NumberUtil.isInt(split2[0])) {
final int typeId = Integer.parseInt(split2[0]);
mat = Material.getMaterial(typeId);
} else {
mat = Material.matchMaterial(split2[0]);
}
Material mat = Material.matchMaterial(split2[0]);
if (mat == null) {
return null;
}
@@ -108,13 +119,7 @@ public class BukkitConstructor extends CustomClassLoaderConstructor {
if (split3.length < 1) {
continue;
}
Enchantment enchantment;
if (NumberUtil.isInt(split3[0])) {
final int enchantId = Integer.parseInt(split3[0]);
enchantment = Enchantment.getById(enchantId);
} else {
enchantment = Enchantment.getByName(split3[0].toUpperCase(Locale.ENGLISH));
}
Enchantment enchantment = Enchantments.getByName(split3[0]);
if (enchantment == null) {
continue;
}
@@ -134,7 +139,7 @@ public class BukkitConstructor extends CustomClassLoaderConstructor {
return stack;
}
if (node.getType().equals(EnchantmentLevel.class)) {
final String val = (String) constructScalar((ScalarNode) node);
final String val = constructScalarRefl((ScalarNode) node);
if (val.isEmpty()) {
return null;
}
@@ -142,13 +147,7 @@ public class BukkitConstructor extends CustomClassLoaderConstructor {
if (split.length == 0) {
return null;
}
Enchantment enchant;
if (NumberUtil.isInt(split[0])) {
final int typeId = Integer.parseInt(split[0]);
enchant = Enchantment.getById(typeId);
} else {
enchant = Enchantment.getByName(split[0].toUpperCase(Locale.ENGLISH));
}
Enchantment enchant = Enchantments.getByName(split[0]);
if (enchant == null) {
return null;
}
@@ -169,6 +168,7 @@ public class BukkitConstructor extends CustomClassLoaderConstructor {
}
private class ConstructBukkitMapping extends ConstructMapping {
@Override
public Object construct(final Node node) {
if (node.getType().equals(Location.class)) {
@@ -181,25 +181,25 @@ public class BukkitConstructor extends CustomClassLoaderConstructor {
return null;
}
for (NodeTuple nodeTuple : mnode.getValue()) {
final String key = (String) constructScalar((ScalarNode) nodeTuple.getKeyNode());
final String key = constructScalarRefl((ScalarNode) nodeTuple.getKeyNode());
final ScalarNode snode = (ScalarNode) nodeTuple.getValueNode();
if (key.equalsIgnoreCase("world")) {
worldName = (String) constructScalar(snode);
worldName = constructScalarRefl(snode);
}
if (key.equalsIgnoreCase("x")) {
x = Double.parseDouble((String) constructScalar(snode));
x = Double.parseDouble(constructScalarRefl(snode));
}
if (key.equalsIgnoreCase("y")) {
y = Double.parseDouble((String) constructScalar(snode));
y = Double.parseDouble(constructScalarRefl(snode));
}
if (key.equalsIgnoreCase("z")) {
z = Double.parseDouble((String) constructScalar(snode));
z = Double.parseDouble(constructScalarRefl(snode));
}
if (key.equalsIgnoreCase("yaw")) {
yaw = Float.parseFloat((String) constructScalar(snode));
yaw = Float.parseFloat(constructScalarRefl(snode));
}
if (key.equalsIgnoreCase("pitch")) {
pitch = Float.parseFloat((String) constructScalar(snode));
pitch = Float.parseFloat(constructScalarRefl(snode));
}
}
if (worldName == null || worldName.isEmpty()) {
@@ -0,0 +1,81 @@
package com.earth2me.essentials.utils;
import org.bukkit.Material;
import org.bukkit.Statistic;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
public class EnumUtil {
/**
* Returns the field matching the first provided enum name that exists within the given
* enum class. If no field is found, this method returns null.
*
* @param enumClass The class to search through
* @param names The names of the fields to search for
* @param <T> The enum to search through
* @return The first matching enum field
*/
public static <T extends Enum> T valueOf(Class<T> enumClass, String... names) {
for (String name : names) {
try {
Field enumField = enumClass.getDeclaredField(name);
if (enumField.isEnumConstant()) {
return (T) enumField.get(null);
}
} catch (NoSuchFieldException | IllegalAccessException ignored) {}
}
return null;
}
/**
* Return a set containing <b>all</b> fields of the given enum that maths one of the provided
* names.
*
* @param enumClass The class to search through
* @param names The names of the fields to search for
* @param <T> The enum to search through
* @return All matching enum fields
*/
public static <T extends Enum> Set<T> getAllMatching(Class<T> enumClass, String... names) {
Set<T> set = new HashSet<>();
for (String name : names) {
try {
Field enumField = enumClass.getDeclaredField(name);
if (enumField.isEnumConstant()) {
set.add((T) enumField.get(null));
}
} catch (NoSuchFieldException | IllegalAccessException ignored) {}
}
return set;
}
/**
* Gets the first Material field found from the given names.
*
* @param names The names of the fields to search for
* @return The first matching Material
*/
public static Material getMaterial(String... names) {
return valueOf(Material.class, names);
}
/**
* Gets the first Statistic field found from the given names.
*
* @param names The names of the fields to search for
* @return The first matching Statistic
*/
public static Statistic getStatistic(String... names) {
return valueOf(Statistic.class, names);
}
}
@@ -1,5 +1,6 @@
package com.earth2me.essentials.utils;
import com.earth2me.essentials.IEssentials;
import net.ess3.api.IUser;
import org.bukkit.GameMode;
import org.bukkit.Location;
@@ -13,158 +14,32 @@ import java.util.*;
import static com.earth2me.essentials.I18n.tl;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.IEssentials;
public class LocationUtil {
// The player can stand inside these materials
public static final Set<Material> HOLLOW_MATERIALS = new HashSet<>();
private static final Set<Material> HOLLOW_MATERIALS = new HashSet<>();
private static final Set<Material> TRANSPARENT_MATERIALS = new HashSet<>();
static {
// Materials from Material.isTransparent()
HOLLOW_MATERIALS.add(Material.AIR);
HOLLOW_MATERIALS.add(Material.SAPLING);
HOLLOW_MATERIALS.add(Material.POWERED_RAIL);
HOLLOW_MATERIALS.add(Material.DETECTOR_RAIL);
HOLLOW_MATERIALS.add(Material.LONG_GRASS);
HOLLOW_MATERIALS.add(Material.DEAD_BUSH);
HOLLOW_MATERIALS.add(Material.YELLOW_FLOWER);
HOLLOW_MATERIALS.add(Material.RED_ROSE);
HOLLOW_MATERIALS.add(Material.BROWN_MUSHROOM);
HOLLOW_MATERIALS.add(Material.RED_MUSHROOM);
HOLLOW_MATERIALS.add(Material.TORCH);
HOLLOW_MATERIALS.add(Material.FIRE);
HOLLOW_MATERIALS.add(Material.REDSTONE_WIRE);
HOLLOW_MATERIALS.add(Material.CROPS);
HOLLOW_MATERIALS.add(Material.LADDER);
HOLLOW_MATERIALS.add(Material.RAILS);
HOLLOW_MATERIALS.add(Material.LEVER);
HOLLOW_MATERIALS.add(Material.REDSTONE_TORCH_OFF);
HOLLOW_MATERIALS.add(Material.REDSTONE_TORCH_ON);
HOLLOW_MATERIALS.add(Material.STONE_BUTTON);
HOLLOW_MATERIALS.add(Material.SNOW);
HOLLOW_MATERIALS.add(Material.SUGAR_CANE_BLOCK);
HOLLOW_MATERIALS.add(Material.PORTAL);
HOLLOW_MATERIALS.add(Material.DIODE_BLOCK_OFF);
HOLLOW_MATERIALS.add(Material.DIODE_BLOCK_ON);
HOLLOW_MATERIALS.add(Material.PUMPKIN_STEM);
HOLLOW_MATERIALS.add(Material.MELON_STEM);
HOLLOW_MATERIALS.add(Material.VINE);
HOLLOW_MATERIALS.add(Material.WATER_LILY);
HOLLOW_MATERIALS.add(Material.NETHER_WARTS);
HOLLOW_MATERIALS.add(Material.ENDER_PORTAL);
HOLLOW_MATERIALS.add(Material.COCOA);
HOLLOW_MATERIALS.add(Material.TRIPWIRE_HOOK);
HOLLOW_MATERIALS.add(Material.TRIPWIRE);
HOLLOW_MATERIALS.add(Material.FLOWER_POT);
HOLLOW_MATERIALS.add(Material.CARROT);
HOLLOW_MATERIALS.add(Material.POTATO);
HOLLOW_MATERIALS.add(Material.WOOD_BUTTON);
HOLLOW_MATERIALS.add(Material.SKULL);
HOLLOW_MATERIALS.add(Material.REDSTONE_COMPARATOR_OFF);
HOLLOW_MATERIALS.add(Material.REDSTONE_COMPARATOR_ON);
HOLLOW_MATERIALS.add(Material.ACTIVATOR_RAIL);
HOLLOW_MATERIALS.add(Material.CARPET);
HOLLOW_MATERIALS.add(Material.DOUBLE_PLANT);
// Additional Materials added in by Essentials
HOLLOW_MATERIALS.add(Material.SEEDS);
HOLLOW_MATERIALS.add(Material.SIGN_POST);
HOLLOW_MATERIALS.add(Material.WOODEN_DOOR);
HOLLOW_MATERIALS.add(Material.WALL_SIGN);
HOLLOW_MATERIALS.add(Material.STONE_PLATE);
HOLLOW_MATERIALS.add(Material.IRON_DOOR_BLOCK);
HOLLOW_MATERIALS.add(Material.WOOD_PLATE);
HOLLOW_MATERIALS.add(Material.FENCE_GATE);
for (Material mat : Material.values()) {
if (mat.isTransparent()) {
HOLLOW_MATERIALS.add(mat);
}
}
TRANSPARENT_MATERIALS.addAll(HOLLOW_MATERIALS);
TRANSPARENT_MATERIALS.add(Material.WATER);
TRANSPARENT_MATERIALS.add(Material.STATIONARY_WATER);
try {
TRANSPARENT_MATERIALS.add(Material.valueOf("FLOWING_WATER"));
} catch (Exception ignored) {} // 1.13 WATER uses Levelled
}
public static final int RADIUS = 3;
public static final Vector3D[] VOLUME;
public static ItemStack convertBlockToItem(final Block block) {
final ItemStack is = new ItemStack(block.getType(), 1, (short) 0, block.getData());
switch (is.getType()) {
case WOODEN_DOOR:
is.setType(Material.WOOD_DOOR);
is.setDurability((short) 0);
break;
case IRON_DOOR_BLOCK:
is.setType(Material.IRON_DOOR);
is.setDurability((short) 0);
break;
case SIGN_POST:
case WALL_SIGN:
is.setType(Material.SIGN);
is.setDurability((short) 0);
break;
case CROPS:
is.setType(Material.SEEDS);
is.setDurability((short) 0);
break;
case CAKE_BLOCK:
is.setType(Material.CAKE);
is.setDurability((short) 0);
break;
case BED_BLOCK:
is.setType(Material.BED);
is.setDurability((short) 0);
break;
case REDSTONE_WIRE:
is.setType(Material.REDSTONE);
is.setDurability((short) 0);
break;
case REDSTONE_TORCH_OFF:
case REDSTONE_TORCH_ON:
is.setType(Material.REDSTONE_TORCH_ON);
is.setDurability((short) 0);
break;
case DIODE_BLOCK_OFF:
case DIODE_BLOCK_ON:
is.setType(Material.DIODE);
is.setDurability((short) 0);
break;
case DOUBLE_STEP:
is.setType(Material.STEP);
break;
case TORCH:
case RAILS:
case LADDER:
case WOOD_STAIRS:
case COBBLESTONE_STAIRS:
case LEVER:
case STONE_BUTTON:
case FURNACE:
case DISPENSER:
case PUMPKIN:
case JACK_O_LANTERN:
case WOOD_PLATE:
case STONE_PLATE:
case PISTON_STICKY_BASE:
case PISTON_BASE:
case IRON_FENCE:
case THIN_GLASS:
case TRAP_DOOR:
case FENCE:
case FENCE_GATE:
case NETHER_FENCE:
is.setDurability((short) 0);
break;
case FIRE:
return null;
case PUMPKIN_STEM:
is.setType(Material.PUMPKIN_SEEDS);
break;
case MELON_STEM:
is.setType(Material.MELON_SEEDS);
break;
}
return is;
return new ItemStack(block.getType(), 1);
}
@@ -173,7 +48,7 @@ public class LocationUtil {
public int y;
public int z;
public Vector3D(int x, int y, int z) {
Vector3D(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
@@ -181,7 +56,7 @@ public class LocationUtil {
}
static {
List<Vector3D> pos = new ArrayList<Vector3D>();
List<Vector3D> pos = new ArrayList<>();
for (int x = -RADIUS; x <= RADIUS; x++) {
for (int y = -RADIUS; y <= RADIUS; y++) {
for (int z = -RADIUS; z <= RADIUS; z++) {
@@ -189,42 +64,27 @@ public class LocationUtil {
}
}
}
Collections.sort(pos, new Comparator<Vector3D>() {
@Override
public int compare(Vector3D a, Vector3D b) {
return (a.x * a.x + a.y * a.y + a.z * a.z) - (b.x * b.x + b.y * b.y + b.z * b.z);
}
});
pos.sort(Comparator.comparingInt(a -> (a.x * a.x + a.y * a.y + a.z * a.z)));
VOLUME = pos.toArray(new Vector3D[0]);
}
@SuppressWarnings("deprecation")
public static Location getTarget(final LivingEntity entity) throws Exception {
Block block;
Block block = null;
try {
block = entity.getTargetBlock(TRANSPARENT_MATERIALS, 300);
} catch (NoSuchMethodError e) {
HashSet<Byte> legacyTransparent = new HashSet<>(); // Bukkit API prevents declaring as Set<Byte>
for (Material m : TRANSPARENT_MATERIALS) {
legacyTransparent.add((byte) m.getId());
}
block = entity.getTargetBlock(legacyTransparent, 300);
}
} catch (NoSuchMethodError ignored) {} // failing now :(
if (block == null) {
throw new Exception("Not targeting a block");
}
return block.getLocation();
}
static boolean isBlockAboveAir(final World world, final int x, final int y, final int z) {
if (y > world.getMaxHeight()) {
return true;
}
return HOLLOW_MATERIALS.contains(world.getBlockAt(x, y - 1, z).getType());
public static boolean isBlockAboveAir(final World world, final int x, final int y, final int z) {
return y > world.getMaxHeight() || HOLLOW_MATERIALS.contains(world.getBlockAt(x, y - 1, z).getType());
}
public static boolean isBlockUnsafeForUser(final IUser user, final World world, final int x, final int y, final int z) {
if (user.getBase().isOnline() && world.equals(user.getBase().getWorld()) && (user.getBase().getGameMode() == GameMode.CREATIVE || user.isGodModeEnabled()) && user.getBase().getAllowFlight()) {
if (user.getBase().isOnline() && world.equals(user.getBase().getWorld()) && (user.getBase().getGameMode() == GameMode.CREATIVE || user.getBase().getGameMode() == GameMode.SPECTATOR || user.isGodModeEnabled()) && user.getBase().getAllowFlight()) {
return false;
}
@@ -235,26 +95,34 @@ public class LocationUtil {
}
public static boolean isBlockUnsafe(final World world, final int x, final int y, final int z) {
if (isBlockDamaging(world, x, y, z)) {
return true;
}
return isBlockAboveAir(world, x, y, z);
return isBlockDamaging(world, x, y, z) || isBlockAboveAir(world, x, y, z);
}
public static boolean isBlockDamaging(final World world, final int x, final int y, final int z) {
final Block below = world.getBlockAt(x, y - 1, z);
if (below.getType() == Material.LAVA || below.getType() == Material.STATIONARY_LAVA) {
switch (below.getType()) {
case LAVA:
case FIRE:
return true;
}
if (MaterialUtil.isBed(below.getType())) {
return true;
}
if (below.getType() == Material.FIRE) {
return true;
}
if (below.getType() == Material.BED_BLOCK) {
return true;
}
if (world.getBlockAt(x, y, z).getType() == Material.PORTAL) {
try {
if (below.getType() == Material.valueOf("FLOWING_LAVA")) {
return true;
}
} catch (Exception ignored) {} // 1.13 LAVA uses Levelled
Material PORTAL = EnumUtil.getMaterial("NETHER_PORTAL", "PORTAL");
if (world.getBlockAt(x, y, z).getType() == PORTAL) {
return true;
}
return (!HOLLOW_MATERIALS.contains(world.getBlockAt(x, y, z).getType())) || (!HOLLOW_MATERIALS.contains(world.getBlockAt(x, y + 1, z).getType()));
}
@@ -281,7 +149,6 @@ public class LocationUtil {
user.getBase().setFlying(true);
}
// ess can be null if old deprecated method is calling it.
System.out.println((ess == null) + " " + ess.getSettings().isTeleportToCenterLocation());
if (ess == null || ess.getSettings().isTeleportToCenterLocation()) {
return getRoundedDestination(loc);
} else {
@@ -0,0 +1,127 @@
package com.earth2me.essentials.utils;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.material.MaterialData;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;
public class MaterialUtil {
private static final Set<Material> BEDS;
private static final Set<Material> BANNERS;
private static final Set<Material> FIREWORKS;
private static final Set<Material> LEGACY_SKULLS;
private static final Set<Material> LEATHER_ARMOR;
private static final Set<Material> MOB_HEADS;
// includes TIPPED_ARROW which also has potion effects
private static final Set<Material> PLAYER_HEADS;
private static final Set<Material> POTIONS;
private static final Set<Material> SIGNS;
public static final Material SPAWNER = EnumUtil.getMaterial("MOB_SPAWNER", "SPAWNER");
static {
BEDS = EnumUtil.getAllMatching(Material.class, "BED", "WHITE_BED", "ORANGE_BED",
"MAGENTA_BED", "LIGHT_BLUE_BED", "YELLOW_BED", "LIME_BED", "PINK_BED", "GRAY_BED",
"LIGHT_GRAY_BED", "CYAN_BED", "PURPLE_BED", "BLUE_BED", "BROWN_BED", "GREEN_BED",
"RED_BED", "BLACK_BED");
BANNERS = EnumUtil.getAllMatching(Material.class, "BANNER", "WHITE_BANNER",
"ORANGE_BANNER", "MAGENTA_BANNER", "LIGHT_BLUE_BANNER", "YELLOW_BANNER", "LIME_BANNER",
"PINK_BANNER","GRAY_BANNER","LIGHT_GRAY_BANNER", "CYAN_BANNER", "PURPLE_BANNER",
"BLUE_BANNER", "BROWN_BANNER", "GREEN_BANNER", "RED_BANNER", "BLACK_BANNER", "SHIELD");
FIREWORKS = EnumUtil.getAllMatching(Material.class, "FIREWORK", "FIREWORK_ROCKET",
"FIREWORK_CHARGE", "FIREWORK_STAR");
LEATHER_ARMOR = EnumUtil.getAllMatching(Material.class, "LEATHER_HELMET",
"LEATHER_CHESTPLATE", "LEATHER_LEGGINGS", "LEATHER_BOOTS");
LEGACY_SKULLS = EnumUtil.getAllMatching(Material.class,"SKULL", "SKULL_ITEM");
MOB_HEADS = EnumUtil.getAllMatching(Material.class, "SKELETON_SKULL",
"SKELETON_WALL_SKULL", "WITHER_SKELETON_SKULL", "WITHER_SKELETON_WALL_SKULL",
"CREEPER_HEAD", "CREEPER_WALL_HEAD", "ZOMBIE_HEAD", "ZOMBIE_WALL_HEAD", "DRAGON_HEAD"
, "DRAGON_WALL_HEAD");
PLAYER_HEADS = EnumUtil.getAllMatching(Material.class, "PLAYER_HEAD", "PLAYER_WALL_HEAD");
POTIONS = EnumUtil.getAllMatching(Material.class, "POTION", "SPLASH_POTION",
"LINGERING_POTION", "TIPPED_ARROW");
SIGNS = EnumUtil.getAllMatching(Material.class, "SIGN", "SIGN_POST", "WALL_SIGN");
}
public static boolean isBed(Material material) {
return BEDS.contains(material);
}
public static boolean isBanner(Material material) {
return BANNERS.contains(material);
}
public static boolean isFirework(Material material) {
return FIREWORKS.contains(material);
}
public static boolean isLeatherArmor(Material material) {
return LEATHER_ARMOR.contains(material);
}
public static boolean isMobHead(Material material, int durability) {
if (MOB_HEADS.contains(material)) {
return true;
}
return LEGACY_SKULLS.contains(material) && (durability < 0 || durability != 3);
}
public static boolean isPlayerHead(Material material, int durability) {
if (PLAYER_HEADS.contains(material)) {
return true;
}
return LEGACY_SKULLS.contains(material) && durability == 3;
}
public static boolean isPotion(Material material) {
return POTIONS.contains(material);
}
public static boolean isSign(Material material) {
return SIGNS.contains(material);
}
public static boolean isSkull(Material material) {
return isPlayerHead(material, -1) || isMobHead(material, -1);
}
public static Material convertFromLegacy(int id, byte damage) {
for (Material material : EnumSet.allOf(Material.class)) {
if (material.getId() == id) {
try {
return Bukkit.getUnsafe().fromLegacy(new MaterialData(material, damage));
} catch (NoSuchMethodError error) {
return material;
}
}
}
return null;
}
public static DyeColor getColorOf(Material material) {
for (DyeColor color : DyeColor.values()) {
if (material.toString().contains(color.name())) {
return color;
}
}
return DyeColor.WHITE;
}
}
@@ -11,14 +11,14 @@ import java.util.Locale;
import static com.earth2me.essentials.I18n.tl;
public class NumberUtil {
static DecimalFormat twoDPlaces = new DecimalFormat("#,###.##");
static DecimalFormat currencyFormat = new DecimalFormat("#0.00", DecimalFormatSymbols.getInstance(Locale.US));
private static DecimalFormat twoDPlaces = new DecimalFormat("#,###.##");
private static DecimalFormat currencyFormat = new DecimalFormat("#0.00", DecimalFormatSymbols.getInstance(Locale.US));
// This field is likely to be modified in com.earth2me.essentials.Settings when loading currency format.
// This ensures that we can supply a constant formatting.
static final NumberFormat PRETTY_FORMAT = NumberFormat.getInstance(Locale.US);
private static NumberFormat PRETTY_FORMAT = NumberFormat.getInstance(Locale.US);
static {
twoDPlaces.setRoundingMode(RoundingMode.HALF_UP);
@@ -30,6 +30,11 @@ public class NumberUtil {
PRETTY_FORMAT.setMaximumFractionDigits(2);
}
// this method should only be called by Essentials
public static void internalSetPrettyFormat(NumberFormat prettyFormat) {
PRETTY_FORMAT = prettyFormat;
}
public static String shortCurrency(final BigDecimal value, final IEssentials ess) {
return ess.getSettings().getCurrencySymbol() + formatAsCurrency(value);
}
@@ -0,0 +1,156 @@
package com.earth2me.essentials.utils;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import org.bukkit.Bukkit;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class VersionUtil {
public static final BukkitVersion v1_8_8_R01 = BukkitVersion.fromString("1.8.8-R0.1-SNAPSHOT");
public static final BukkitVersion v1_9_R01 = BukkitVersion.fromString("1.9-R0.1-SNAPSHOT");
public static final BukkitVersion v1_9_4_R01 = BukkitVersion.fromString("1.9.4-R0.1-SNAPSHOT");
public static final BukkitVersion v1_10_2_R01 = BukkitVersion.fromString("1.10.2-R0.1-SNAPSHOT");
public static final BukkitVersion v1_11_2_R01 = BukkitVersion.fromString("1.11.2-R0.1-SNAPSHOT");
public static final BukkitVersion v1_12_0_R01 = BukkitVersion.fromString("1.12.0-R0.1-SNAPSHOT");
public static final BukkitVersion v1_12_2_R01 = BukkitVersion.fromString("1.12.2-R0.1-SNAPSHOT");
public static final BukkitVersion v1_13_0_R01 = BukkitVersion.fromString("1.13.0-R0.1-SNAPSHOT");
public static final BukkitVersion v1_13_2_R01 = BukkitVersion.fromString("1.13.2-R0.1-SNAPSHOT");
private static final Set<BukkitVersion> supportedVersions = ImmutableSet.of(v1_8_8_R01, v1_9_4_R01, v1_10_2_R01, v1_11_2_R01, v1_12_2_R01, v1_13_2_R01);
private static BukkitVersion serverVersion = null;
public static BukkitVersion getServerBukkitVersion() {
if (serverVersion == null) {
serverVersion = BukkitVersion.fromString(Bukkit.getServer().getBukkitVersion());
}
return serverVersion;
}
public static boolean isServerSupported() {
return supportedVersions.contains(getServerBukkitVersion());
}
public static class BukkitVersion implements Comparable<BukkitVersion> {
private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.?([0-9]*)-R([\\d.]+)(?:-SNAPSHOT)?");
private final int major;
private final int minor;
private final int patch;
private final double revision;
public static BukkitVersion fromString(String string) {
Preconditions.checkNotNull(string, "string cannot be null.");
Matcher matcher = VERSION_PATTERN.matcher(string);
if (!matcher.matches()) {
if (!Bukkit.getName().equals("Essentials Fake Server")) {
throw new IllegalArgumentException(string + " is not in valid version format. e.g. 1.8.8-R0.1");
}
matcher = VERSION_PATTERN.matcher(v1_13_2_R01.toString());
Preconditions.checkArgument(matcher.matches(), string + " is not in valid version format. e.g. 1.8.8-R0.1");
}
return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4));
}
private static BukkitVersion from(String major, String minor, String patch, String revision) {
if (patch.isEmpty()) patch = "0";
return new BukkitVersion(Integer.parseInt(major),
Integer.parseInt(minor),
Integer.parseInt(patch),
Double.parseDouble(revision));
}
private BukkitVersion(int major, int minor, int patch, double revision) {
this.major = major;
this.minor = minor;
this.patch = patch;
this.revision = revision;
}
public boolean isHigherThan(BukkitVersion o) {
return compareTo(o) > 0;
}
public boolean isHigherThanOrEqualTo(BukkitVersion o) {
return compareTo(o) >= 0;
}
public boolean isLowerThan(BukkitVersion o) {
return compareTo(o) < 0;
}
public boolean isLowerThanOrEqualTo(BukkitVersion o) {
return compareTo(o) <= 0;
}
public int getMajor() {
return major;
}
public int getMinor() {
return minor;
}
public int getPatch() {
return patch;
}
public double getRevision() {
return revision;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BukkitVersion that = (BukkitVersion) o;
return major == that.major &&
minor == that.minor &&
patch == that.patch &&
revision == that.revision;
}
@Override
public int hashCode() {
return Objects.hashCode(major, minor, patch, revision);
}
@Override
public String toString() {
return major + "." + minor + "." + patch + "-R" + revision;
}
@Override
public int compareTo(BukkitVersion o) {
if (major < o.major) {
return -1;
} else if (major > o.major) {
return 1;
} else { // equal major
if (minor < o.minor) {
return -1;
} else if (minor > o.minor) {
return 1;
} else { // equal minor
if (patch < o.patch) {
return -1;
} else if (patch > o.patch) {
return 1;
} else { // equal patch
return Double.compare(revision, o.revision);
}
}
}
}
}
}
Loaded 100 of 217 files, more files were not shown because too many files have changed in this diff. Show more