Compare commits

...
285 Commits
Author SHA1 Message Date
md678685 8bc55387dd Bump version to 2.17.0 2019-06-26 16:50:11 +01:00
md678685 0584353bfa Bump version to 2.17-pre1 2019-06-26 15:32:08 +01:00
md678685 2938330222 Load and save kit use timestamps consistently
Fixes #2301.

The kit's name was previously sanitised/lowercased when accessed but not when saved. This fixes that. ensuring the kit delay will be reported correctly.

Tested on 1.14.3 - does not appear to break existing kit delays.
2019-06-26 12:54:19 +01:00
md678685 ef7393036e Update to 1.14.3 2019-06-26 11:49:10 +01:00
Josh Roy 0409f5bc4a Update 1.14.3 version string (#2624)
Closes #2624.
2019-06-26 11:48:50 +01:00
Josh Roy 8ff1ebd7c2 Fix version regex on 1.14.3 (#2622) @JRoy 2019-06-25 07:18:16 +01:00
md678685 9089fe8be3 Attempt to fall back to Material.getMaterial(int) below 1.13
Fixes #2615.
2019-06-24 09:41:33 +01:00
Johnny Cao 74d96ce624 Fixes #2121 - Allow players to teleport into a location with water if configured (#2520)
# Description of #2520
This is a continuation of #2457, accidentally hit rebase and recommitted a load of commits from the 2.x log into my repo...

I've reverted the code and added the configuration option, modifying the `LocationUtil#HOLLOW_MATERIALS` as necessary when the config is loaded.

New demo: streamable.com/pm50r
```
[16:01:00 INFO]: Server version: 1.13.2-R0.1-SNAPSHOT git-Spigot-3cb9dcb-77ca7ca (MC: 1.13.2)
[16:01:00 INFO]: EssentialsX version: 2.16.1.154
[16:01:00 INFO]: Vault is not installed. Chat and permissions may not work.
```

# Description of #2457
Fixes #2121.

Prior to the addition of this patch, teleporting from another world through commands such as `/spawn` and `/home` would cause players to be teleported to the surface of the water. After this patch, using the same command will correctly teleport them to the original location.

In seeing that the addition of water would cause the `HOLLOW_MATERIALS` set to be identical to the `TRANSPARENT_MATERIALS`, I have removed the latter's usage and simply added water to the former.

I'm not exactly sure if adding water to `HOLLOW_MATERIALS` is the right decision, but it fixes the issue, and I personally don't really see any point in not having water in the list. I imagine some people might use this as a way to drop players on the surface of the water, but they can fix that issue quite easily by actually going to the surface and setting the location there. I also can see that water is not necessarily a "safe" location because players can drown, but I really see no other alternative. 

The only reason it works like normal in the same world is because the safe location method exempts locations in the same world as the teleporting player, and thus this check is never even performed in the first place for those players anyway.

**Demo**
```
[16:22:49 INFO]: CONSOLE issued server command: /ess version
[16:22:49 INFO]: Server version: 1.13.2-R0.1-SNAPSHOT git-Paper-"16db0e6a" (MC: 1.13.2)
[16:22:49 INFO]: EssentialsX version: 2.16.1.9
[16:22:49 INFO]: LuckPerms version: 4.3.73
[16:22:49 INFO]: Vault is not installed. Chat and permissions may not work.
```
https://streamable.com/71072
2019-06-17 11:28:12 +01:00
md678685 8b7bcbb880 Don't update user activity on physical interactions
Fixes #2578.
2019-06-17 11:06:45 +01:00
md678685 dbd86155fb Only accept square recipes in /condense
Fixes #1194.
2019-06-16 13:28:02 +01:00
md678685 9b77c0802b Switch Travis to openjdk8 2019-06-16 11:25:25 +01:00
md678685 cd7fa79560 Don't warn about CloudNet SLPEs
Fixes #2592.
2019-06-16 11:13:32 +01:00
md678685 10e9879a64 Update to 1.14.x (#2510)
Add support for Spigot/Paper 1.14.2.
2019-06-16 10:15:12 +01:00
md678685 d1dcc47a27 Specify Java 8 for Travis build
Required due to BuildTools not supporting Java 9 or above for MC 1.8.x.
2019-06-16 10:12:35 +01:00
Pokechu22 7a73301a37 Add permissions for individual colors (#1441)
* Add tests for existing format behavior

* Replace formatting implementation

* Add permissions for individual color codes

Resolves #415

* Use format code names

* Fix escaping

* Mockito: test scope only

* Explicitly check the .magic permission

Once I switch to checking if a perm's set in the loop, the explicit check is needed for an * perm.

* Add support for removing individual colors

* Use `obfuscated` as the name for §k

`magic` is still accepted as the group name, so this is not a breaking change.
2019-06-09 15:56:58 +01:00
md678685 e1dec7d9e7 Fix items.json merging 2019-06-09 15:34:24 +01:00
md678685 99fefdb47d Re-add header to items.json 2019-06-09 15:18:16 +01:00
md678685 5ebce8965e Merge 1.13 and 1.14 items.json together
In 2.17.0, [essx-scripts genItemsFlat](https://github.com/md678685/essx-scripts/blob/master/src/genItemsFlat.js) is being replaced with [ItemDbGenerator](https://github.com/md678685/ItemDbGenerator). To ease migration, this is a file generated by merging the 1.14 entries from the new generator into the existing 1.13 file. This will be replaced by an items.json generated entirely by ItemDbGenerator eventually.
2019-06-09 15:10:12 +01:00
md678685 5a0b7285d4 Add FUNDING.yml Patreon link 2019-06-09 13:04:51 +01:00
md678685 829110e89a Implement missing OfflinePlayer methods 2019-06-09 12:59:32 +01:00
md678685 dc1a0b65fa Merge branch 'mc/1.14' of https://github.com/EssentialsX/Essentials into mc/1.14 2019-06-09 12:58:06 +01:00
md678685 b140826e60 Remove unused import in MaterialUtil 2019-06-09 12:21:40 +01:00
md678685 0d9387458d Remove unused import in AFK event 2019-06-09 12:21:25 +01:00
md678685 f2447a9134 Add fallbacks property to ItemData
Allows items.json to specify fallback names for materials on older versions.

Additionally make non-API methods inaccessible, as they shouldn't be needed by other plugins.
2019-05-31 15:57:51 +01:00
md678685 2ea3d8943e Update outdated meme 2019-05-30 19:34:18 +01:00
Drew Mitchell e4cc78a750 Implement PR #1682 - TPA Event (#1727) @DrewAMitchell
* Attempts to implement #1682 - TPARequestEvent
Awaiting further feedback. I've implemented the event, and elected to send a message to the requester of the TPA when the event gets cancelled.
* Fix formatting
* Fix up l18s errors, remove todos
* Clean up for merge
2019-05-30 19:17:57 +01:00
md678685 a08832cfc8 Implement /itemname command (#2573)
Implement /itemname command, across three PRs. Originally implemented by SupaHam, and updated by zsturgess and myself.
2019-05-30 19:16:43 +01:00
md678685 c97918df24 Add safe-usermap-names option to control usermap key sanitisation
This is necessary to stop players with Chinese characters in their username losing their balances.
2019-05-30 18:50:51 +01:00
Glare e9833d1cd2 Implement essentials.balancetop.exclude permission (#2499)
Closes #595.
2019-05-30 15:20:30 +01:00
md678685 111a18585d Allow clearing item names + add locale messages for /itemname 2019-05-30 15:12:52 +01:00
Zac Sturgess 155d3ec938 Update /itemname in plugin.yml
This contains changes from #2555 squashed into one commit.

Closes #2555.
2019-05-30 14:53:15 +01:00
Ali Moghnieh 8bafacbd51 Create /itemname command that names held items.
This contains changes from #672 minus messages, squashed into one commit.

Closes #672.
2019-05-30 14:53:06 +01:00
montlikadani 0e3f48ee54 Improve disposal, /bigtree and /fireball (#2461) @montlikadani
* Allow the Disposal inventory title to be configurable
* Add darkoak to `/bigtree`'s usage message
* Allow potions to be fired with `/fireball`

## Commits
* Update plugin.yml
* Update Commanddisposal.java
* Update messages.properties
* Update Commandfireball.java
* Update SignDisposal.java
* Fix import
* Remove colour code from disposal message
2019-05-30 14:03:12 +01:00
Trent Hensler b566b4a0c6 Update translations from Crowdin (#2571)
* New translations messages.properties (German)
* New translations messages.properties (Romanian)
* New translations messages.properties (Korean)
* New translations messages.properties (Latvian)
* New translations messages.properties (Lithuanian)
* New translations messages.properties (Norwegian)
* New translations messages.properties (Polish)
* New translations messages.properties (Portuguese)
* New translations messages.properties (Portuguese, Brazilian)
* New translations messages.properties (Russian)
* New translations messages.properties (Italian)
* New translations messages.properties (Serbian (Cyrillic))
* New translations messages.properties (Serbian (Latin))
* New translations messages.properties (Slovak)
* New translations messages.properties (Spanish)
* New translations messages.properties (Swedish)
* New translations messages.properties (Thai)
* New translations messages.properties (Turkish)
* New translations messages.properties (Japanese)
* New translations messages.properties (Icelandic)
* New translations messages.properties (Dutch)
* New translations messages.properties (Bulgarian)
* New translations messages.properties (Vietnamese)
* New translations messages.properties (French)
* New translations messages.properties (Hungarian)
* New translations messages.properties (English, United Kingdom)
* New translations messages.properties (English, United States)
* New translations messages.properties (Basque)
* New translations messages.properties (Bosnian)
* New translations messages.properties (Chinese Simplified)
* New translations messages.properties (Hebrew)
* New translations messages.properties (Chinese Traditional)
* New translations messages.properties (Chinese Traditional, Hong Kong)
* New translations messages.properties (Croatian)
* New translations messages.properties (Czech)
* New translations messages.properties (Danish)
* New translations messages.properties (Estonian)
* New translations messages.properties (Finnish)
* New translations messages.properties (Greek)
* New translations messages.properties (Ukrainian)
2019-05-28 17:56:17 +01:00
md678685 a9ed66d5e0 Add essentials.keepinv to plugin.yml 2019-05-28 12:24:07 +01:00
Josh Roy 94131edb32 Bump Bukkit to 1.14.2 (#2569)
* Bump to API 1.14.2

* Update v1_14_2_R01 as latest supported 1.14 build
2019-05-27 23:12:23 +01:00
md678685 e21863956c Fix checking for attached wall signs 2019-05-27 11:51:56 +01:00
md678685 4201e6ef85 Make all events async when not on primary thread
Fixes #2566, fixes #2556, fixes #2545.
2019-05-26 12:08:58 +01:00
Trent Hensler 5deb1de555 Allow AFK status test to pass. 2019-05-22 12:06:27 -07:00
md678685 c65534ebb1 Only make AfkStatusChangeEvent async when off primary thread 2019-05-22 11:39:26 +01:00
md678685 f22efce3ca Use MobCompat entries for other 1.11+ mobs 2019-05-18 23:51:40 +01:00
md678685 5f0909047d Use MobCompat.CAT throughout MobData 2019-05-18 22:45:43 +01:00
md678685 7cc4dc2f07 Make AfkStatusChangeEvent async 2019-05-18 20:56:57 +01:00
md678685 60ebe9e738 Add llama colour support; improve support for old game versions
Fixes issues with /spawnmob on older versions of the game.

(Also add llama colours, which were missing from the 1.11 update.)
2019-05-18 20:56:34 +01:00
minksuki a1297feb9d adds a permission node that keeps a player's inventory on death (#2531) @minksuki
Closes #2524.

Adds a permission node, `essentials.keepinv` so on player death their inventory will not be wiped.
2019-05-15 07:59:48 +01:00
Josh Roy 09598d0173 Update Bukkit to 1.14.1 (#2544)
* Update v1_14_1_R01 as latest supported 1.14 build

* Bump to API 1.14.1
2019-05-14 09:00:22 +01:00
md678685 35fc845040 Fix Metrics plugin name reporting 2019-05-13 19:15:33 +01:00
md678685 e59950966f Fix Metrics package name 2019-05-13 19:14:01 +01:00
md678685 98cc5b33a3 Update bStats Metrics to latest version
Now featuring server brand support!
2019-05-12 16:17:00 +01:00
Julian van Doorn d107d00ac3 Fix spawning shields with enchantments (#2515) @Argetan
* Moved comment to newline for style consistency.
* Fixed issue 2507 by checking if an enchantment is being applied.
* Added a couple newlines for readability.
* Removed faulty ifs).
2019-05-12 13:50:35 +01:00
md678685 ccc000a416 Add Villager variants, pt 2 2019-05-09 22:20:45 +01:00
md678685 7790f8818b Add Villager variants, pt 1 2019-05-09 15:12:51 +01:00
JRoy 72ca629cf1 Add 1.14 Enchantments 2019-05-09 13:36:09 +01:00
md678685 65017d7f5c Fix /kittycannon
The most important command of all!

(This hasn't been tested with 1.13 or below yet.)
2019-05-08 23:29:55 +01:00
md678685 6d4f7afc79 Improve VersionUtil prerelease handling
Actually includes updated regex this time! (I have no idea how I forgot to update it in cfba203981 - I had already written out the regex)

Incorporates part of https://github.com/EssentialsX/Essentials/pull/2523 - thanks @JRoy.
2019-05-08 23:26:40 +01:00
md678685 4fcb032791 Update FakeServer 2019-05-08 23:23:15 +01:00
md678685 0e668fa0f2 Fix plural suffixes for fish and foxes 2019-05-08 23:06:50 +01:00
md678685 68b933a501 Add Ocelot.Type fallbacks for all MobCompat.CatTypes 2019-05-08 23:06:28 +01:00
md678685 5236ad9f64 Remove redundant BABY_FOX 2019-05-08 22:56:25 +01:00
md678685 937c18fe1d Update FakeWorld 2019-05-08 22:43:57 +01:00
md678685 fb48aaba9d Initial cross-version mob compatibility
Incorporates part of https://github.com/EssentialsX/Essentials/pull/2523 - thanks @JRoy.
2019-05-08 22:40:51 +01:00
md678685 365efe4f2d Implement missing FakeWorld and OfflinePlayer methods 2019-05-08 13:49:54 +01:00
md678685 78b2dba42a Bump to API 1.14 2019-05-08 13:49:35 +01:00
Julian van Doorn f793b7607f OS X compatible buildtools.sh (#2513) @Argetan
* OS X compatible buildtools.sh

* Update buildtools.sh
2019-04-30 07:55:54 +01:00
md678685 c567bc22e9 Compile against 1.14-pre5 2019-04-24 14:30:53 +01:00
md678685 d282462547 Use MaterialUtil to check signs 2019-04-24 14:28:15 +01:00
md678685 af4cfd3fe9 Update bStats Metrics to use Gson 2019-04-24 13:54:33 +01:00
md678685 cfba203981 Add prerelease support to VersionUtil 2019-04-24 13:37:43 +01:00
Glare Masters d680ed7363 Check /tpacancel permissions before sending message (#2498)
Fixes #1354.
2019-04-23 09:22:50 +01:00
md678685 69232c0717 Fix missing formatting code in geoipCantFind 2019-04-22 15:24:31 +01:00
latiku b4baa28f01 fix geoip country returning "." if the user is joining from localhost (#2494) @latiku
Implements a check to see if the user's address is `localhost` or `127.0.0.1`, and if so return that the country is unknown.

**Edit by @md678685: fixes #2471.**
2019-04-22 09:38:06 +01:00
md678685 0aa11b58b9 Update items.json
Updated to md678685/essx-scripts@e6394a2884

* Fix overlapping armor/wooden pressure plate aliases
2019-04-19 15:10:10 +01:00
md678685 7b60b562b9 Update items.json
Update items.json to md678685/essx-scripts@581db130ef

Changes:
* Add pressure plate aliases
* Add "mushroomcow" aliases for mooshroom spawners
* Add zombie pigman spawner aliases
2019-04-19 14:49:36 +01:00
montlikadani 6377cbfb2b Remove stale messages and add/change formatting in others (#2486) 2019-04-18 13:25:25 -04:00
montlikadani 3f5f9cc717 Fixed when the mail has already cleared (#2063) 2019-04-18 13:18:42 -04:00
Johnny Cao eac1e9b574 Fixes #1928 - Auto-AFK issue: AFK timer not reset on disconnect (#2458)
Update activity regardless of cancel-afk-on-interact setting
2019-04-17 20:45:07 -04:00
Glare Masters 26d63da7aa [Feature] Implemented a message to say teleporting to home. (#2489)
[Feature] Implemented a message to say teleporting to home.
2019-04-17 19:14:44 -04:00
Joseph Hirschfeld 722181439e Merge pull request #1953 from Xeyame/#1899
Expand /exp command
2019-04-17 12:18:58 -04:00
Joseph Hirschfeld ddcb7041f1 Merge pull request #2455 from AgentTroll/patch-94
Fixes #94 - Player with same first letters conflict
2019-04-17 02:46:20 -04:00
Joseph Hirschfeld 8af33e0ae2 Merge pull request #2166 from mathiascode/commandevents
Use chat instead of dispatchCommand
2019-04-17 02:33:29 -04:00
Joseph Hirschfeld d01e12ac14 Merge pull request #2158 from pop4959/near-fix
Sort /near by nearest player.
2019-04-17 02:31:38 -04:00
Joseph Hirschfeld 8c0aa840ab Merge pull request #1949 from Ichbinjoe/2.x_feature_jail_no_teleport
[Feature] Add config optn. to disable jail free tp
2019-04-17 02:04:16 -04:00
md678685 05118e9498 Merge pull request #2484 from Xeyame/2.x
Allow using environment variable to set xmx flag in buildtools.sh
2019-04-16 15:47:23 +01:00
Xeyame 7838adf833 Allow using environment variable to set xmx flag 2019-04-16 16:34:57 +02:00
md678685 e230cee91e Add new item database API (#2472)
* Allow resolver functions to be added to item databases

* Allow resolvers to add item names to list

* Make getResolverNames package-private
2019-04-15 10:09:16 +01:00
md678685 8e4fc77244 Merge pull request #2469 from N3FS/feature/command-send
Add PlayerCommandSendEvent listener to hide commands in autocomplete
2019-04-15 10:07:49 +01:00
md678685 0d572036f8 New Crowdin translations (#2476)
* New translations messages.properties (English, United States)

* New translations messages.properties (Russian)

* New translations messages.properties (Korean)

* New translations messages.properties (Lithuanian)

* New translations messages.properties (Polish)

* New translations messages.properties (Portuguese)

* New translations messages.properties (Portuguese, Brazilian)

* New translations messages.properties (Romanian)

* New translations messages.properties (Serbian (Cyrillic))

* New translations messages.properties (Italian)

* New translations messages.properties (Serbian (Latin))

* New translations messages.properties (Slovak)

* New translations messages.properties (Spanish)

* New translations messages.properties (Swedish)

* New translations messages.properties (Thai)

* New translations messages.properties (Turkish)

* New translations messages.properties (Ukrainian)

* New translations messages.properties (Japanese)

* New translations messages.properties (Hungarian)

* New translations messages.properties (English, United Kingdom)

* New translations messages.properties (Chinese Traditional, Hong Kong)

* New translations messages.properties (German)

* New translations messages.properties (Norwegian)

* New translations messages.properties (Bulgarian)

* New translations messages.properties (Basque)

* New translations messages.properties (Bosnian)

* New translations messages.properties (Chinese Simplified)

* New translations messages.properties (Chinese Traditional)

* New translations messages.properties (Croatian)

* New translations messages.properties (Hebrew)

* New translations messages.properties (Czech)

* New translations messages.properties (Danish)

* New translations messages.properties (Dutch)

* New translations messages.properties (Estonian)

* New translations messages.properties (Finnish)

* New translations messages.properties (French)

* New translations messages.properties (Greek)

* New translations messages.properties (Vietnamese)
2019-04-07 21:21:29 +01:00
md678685 26fdd0ff6b Fix playerMutedFor[Reason] formatting codes 2019-04-07 21:19:45 +01:00
Trent Hensler 70a4aee930 New translations messages.properties (Vietnamese) 2019-04-07 13:11:55 -07:00
Trent Hensler 3631323aa7 New translations messages.properties (Greek) 2019-04-07 13:11:53 -07:00
Trent Hensler 1fd7d18056 New translations messages.properties (French) 2019-04-07 13:11:51 -07:00
Trent Hensler a60f67cd0a New translations messages.properties (Finnish) 2019-04-07 13:11:49 -07:00
Trent Hensler 5ba781d00e New translations messages.properties (Estonian) 2019-04-07 13:11:46 -07:00
Trent Hensler 17c5d25996 New translations messages.properties (Dutch) 2019-04-07 13:11:44 -07:00
Trent Hensler bd9f271eff New translations messages.properties (Danish) 2019-04-07 13:11:42 -07:00
Trent Hensler 89b4bd2405 New translations messages.properties (Czech) 2019-04-07 13:11:40 -07:00
Trent Hensler 4da9095c59 New translations messages.properties (Hebrew) 2019-04-07 13:11:37 -07:00
Trent Hensler 75e84a5797 New translations messages.properties (Croatian) 2019-04-07 13:11:35 -07:00
Trent Hensler 54d64dbb5f New translations messages.properties (Chinese Traditional) 2019-04-07 13:11:32 -07:00
Trent Hensler 03e746953c New translations messages.properties (Chinese Simplified) 2019-04-07 13:11:30 -07:00
Trent Hensler ec8a51b06c New translations messages.properties (Bosnian) 2019-04-07 13:11:28 -07:00
Trent Hensler 369c08a624 New translations messages.properties (Basque) 2019-04-07 13:11:26 -07:00
Trent Hensler 7a8e5e92d9 New translations messages.properties (Bulgarian) 2019-04-07 13:11:23 -07:00
Trent Hensler 185ec7ff2b New translations messages.properties (Norwegian) 2019-04-07 13:11:21 -07:00
Trent Hensler af986cc7b2 New translations messages.properties (German) 2019-04-07 13:11:18 -07:00
Trent Hensler 25d96ccfa7 New translations messages.properties (Chinese Traditional, Hong Kong) 2019-04-07 13:11:16 -07:00
Trent Hensler b45c42ef22 New translations messages.properties (English, United Kingdom) 2019-04-07 13:11:14 -07:00
Trent Hensler ea2ac3d483 New translations messages.properties (Hungarian) 2019-04-07 13:11:12 -07:00
Trent Hensler 873df96d0d New translations messages.properties (Japanese) 2019-04-07 13:11:10 -07:00
Trent Hensler d69495baa7 New translations messages.properties (Ukrainian) 2019-04-07 13:11:08 -07:00
Trent Hensler 06ff8f24fe New translations messages.properties (Turkish) 2019-04-07 13:11:06 -07:00
Trent Hensler b996608455 New translations messages.properties (Thai) 2019-04-07 13:11:04 -07:00
Trent Hensler 6c1c22132e New translations messages.properties (Swedish) 2019-04-07 13:11:02 -07:00
Trent Hensler 8b326d5852 New translations messages.properties (Spanish) 2019-04-07 13:11:00 -07:00
Trent Hensler dd34f65c98 New translations messages.properties (Slovak) 2019-04-07 13:10:58 -07:00
Trent Hensler 0bd0f853f3 New translations messages.properties (Serbian (Latin)) 2019-04-07 13:10:55 -07:00
Trent Hensler e7a75efaff New translations messages.properties (Italian) 2019-04-07 13:10:53 -07:00
Trent Hensler 2904b50061 New translations messages.properties (Serbian (Cyrillic)) 2019-04-07 13:10:51 -07:00
Trent Hensler 3b6ac632d9 New translations messages.properties (Romanian) 2019-04-07 13:10:48 -07:00
Trent Hensler 9ad3f0e0d7 New translations messages.properties (Portuguese, Brazilian) 2019-04-07 13:10:45 -07:00
Trent Hensler 9529a4ba02 New translations messages.properties (Portuguese) 2019-04-07 13:10:42 -07:00
Trent Hensler 69b9ab097b New translations messages.properties (Polish) 2019-04-07 13:10:40 -07:00
Trent Hensler 4b14c4bcc6 New translations messages.properties (Lithuanian) 2019-04-07 13:10:38 -07:00
Trent Hensler 5154c670c0 New translations messages.properties (Korean) 2019-04-07 13:10:36 -07:00
Trent Hensler 09b699cc9c New translations messages.properties (Russian) 2019-04-07 13:10:34 -07:00
Trent Hensler f2a212e3a4 New translations messages.properties (English, United States) 2019-04-07 13:10:31 -07:00
md678685 19ca946e3b Add Estonian alias to Crowdin config 2019-04-07 21:08:30 +01:00
md678685 e21be39c13 Add Basque alias to Crowdin config 2019-04-07 21:02:42 +01:00
md678685 8fcfff7abd Update Crowdin config 2019-04-07 21:01:22 +01:00
md678685 bcc150a014 Update l10n configs 2019-04-07 20:22:48 +01:00
md678685 3d97e93831 Implement missing OfflinePlayer location methods 2019-04-07 17:06:17 +01:00
md678685 9d93d4db54 Only log removed commands is debug enabled 2019-04-07 17:03:56 +01:00
md678685 0d8aec7eea Add PlayerCommandSendEvent listener to hide commands in autocomplete 2019-03-31 20:35:47 +01:00
md678685 7b165c6c2c Merge pull request #2450 from AgentTroll/patch-2414
Fixes #2414 - Warp signs no permission message
2019-03-15 12:11:17 +00:00
md678685 d3cee314c6 Merge pull request #2451 from AgentTroll/patch-2403
Fixes #2403 - Ability to execute /back for another player
2019-03-15 12:10:33 +00:00
md678685 4395245aab Merge pull request #2454 from AgentTroll/patch-2415
Fixes #2415 - Command for last reply message option
2019-03-15 12:10:10 +00:00
md678685 9d4b0a13c5 Merge remote-tracking branch 'origin/pr/1557' into 2.x 2019-03-15 11:59:35 +00:00
md678685 c908290c27 Simplify willMute condition 2019-03-15 11:58:30 +00:00
md678685 f5c21d1089 Merge branch '2.x' into final_mute_reason_issue#385 2019-03-15 11:52:50 +00:00
Johnny Cao 883fc75f47 Clarifies the last recipient config key 2019-03-10 01:42:10 -08:00
AgentTroll eaac3049af Fix getPlayer(...) for offline players having similar names 2019-03-09 18:50:55 -08:00
AgentTroll f68fb52af1 Add command to toggle reply player functionality 2019-03-09 15:39:45 -08:00
AgentTroll 863bd5a89e Add /back target capability 2019-03-08 22:41:59 -08:00
AgentTroll 50225624a5 Add message for failing sign warp permission check 2019-03-08 15:53:04 -08:00
md678685 25ddaef423 Merge pull request #2329 from triagonal/issue-2311
Implement config option for sleep ignoring AFK players
2019-03-08 22:15:53 +00:00
md678685 585f2bef07 Merge pull request #2310 from pop4959/command-tpauto
Implement tpauto command
2019-03-08 17:19:31 +00:00
md678685 017ea1a4fe Remove unnecessary types 2019-03-08 11:24:42 +00:00
md678685 3b4b5bcd8e Remove Lombok
Remove the (already minimal) usage of Lombok. This will ease development for people who don't already have their IDE set up for Lombok support.

It's also totally unnecessary - it took less than 60 seconds to generate the code needed to replace Lombok annotations in Jails and Spawns.
2019-03-08 11:24:42 +00:00
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
pop4959 74b0e71015 More efficient distance calculation 2019-02-26 19:54:19 -08: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
triagonal 3d004d2a81 change config setting name 2018-12-31 16:42:42 +11:00
triagonal d1bbebad3a updated config comments 2018-12-30 20:49:58 +11:00
triagonal 42714ff8af implement config toggle for afk users bypassing sleep 2018-12-30 20:38:34 +11:00
md678685 246fd03265 Fix typo in README 2018-12-23 23:33:46 +00:00
pop4959 64930e3771 Fix messages & add warning 2018-12-21 01:58:44 -08:00
pop4959 16381234e0 Implement tpauto command 2018-12-19 02:50:30 -08:00
md678685 22538ba7c9 Merge branch '1.13' into 2.x_feature_jail_no_teleport 2018-10-28 18:46:53 +00:00
mathias a9fe842242 Use chat instead of dispatchCommand 2018-09-18 16:39:58 +03:00
pop4959 0432546746 use less dependencies 2018-09-04 16:53:01 -07:00
pop4959 3395bab928 Sort /near by nearest player. 2018-09-02 23:09:22 -07:00
Joseph Hirschfeld 70387f73f6 [Feature] Add config optn. to disable jail free tp
Adds the teleport-back-when-freed-from-jail configuration option. When
set to true (default), as with previous versions will teleport the
player which was jailed back to their previous position when freed. When
false, Essentials will not teleport the player anywhere, leaving them
where they are.

Closes #1947
2018-04-03 01:27:09 -04:00
Xeyame 7adb931ea8 Expand /exp command 2018-04-02 14:29:43 +02:00
Taylor 5f7d226158 Merge pull request #17 from delbertina/mutes385test
Sorted messages files with the -f option and other tweaks ...
2018-01-21 17:02:26 -06:00
delbertina 0897ca57ff Removed redundant line in mute time try-catch. 2018-01-20 22:46:55 -06:00
delbertina cfcdb47529 One last tweak. New line at the end of the fr file. 2018-01-18 22:04:35 -06:00
delbertina 76f845f5f4 More tweaks. Newlines and ordering switches. 2018-01-18 22:02:39 -06:00
delbertina c65b7b6462 Fixed error in sorting with number in message name and newlines at end of files. 2018-01-18 21:52:30 -06:00
delbertina 67528b25a8 Sorted messages files with the -f option 2018-01-18 15:18:22 -06:00
CreedTheFreak b096ee9703 Merge remote-tracking branch 'delbertina/mutes385test' into final_mute_reason_issue#385
Merged changes into local branch for pushing up to the pull request of
mute reason.
2018-01-16 17:49:49 -08:00
delbertina 9e2bb0b277 Rebase with sorted messages 2018-01-16 19:27:45 -06:00
CreedTheFreak b8df59ae46 Updated the former pull request to include the specified formatting changes, and small edits to the hasMuteReason and Commandmute dealing with the muteReason. I also included the ability to see the mute reason from the seenOffline method which is identical to the seenOnline code. 2018-01-16 18:21:31 -06:00
delbertina 98f42c6974 Added reason stuff to msg command and deleted reference line in seen command. Oops! 2018-01-16 18:16:34 -06:00
delbertina db19788e21 Added 8 new messages for "...Reason" versions of mute messages and implemented em. 2018-01-16 18:16:33 -06:00
delbertina 67d17472e0 Fixed logic error in hasMuteReason and errors being thrown from seen and whois. 2018-01-16 18:04:22 -06:00
delbertina f68a6eb00d Added space before reason when a muted player tries to talk. 2018-01-16 18:04:22 -06:00
delbertina b5a6df4fe2 Added space when adding reason to string. 2018-01-16 18:04:21 -06:00
delbertina 290379651d Added space when adding reason to string. Dirty :/ 2018-01-16 17:59:14 -06:00
delbertina 6ffbb86169 Changed if else blocks to ternary operators. Not sure if way to avoid weird empty string usage. 2018-01-16 17:54:50 -06:00
delbertina d8b6f87087 Added method hasMuteReason in UserData. 2018-01-16 17:54:50 -06:00
delbertina 7aad95ec08 Changed muteFormat to muteReason.
Removed space at beginning of muteReason.
2018-01-16 17:54:49 -06:00
delbertina 574e1bc1e7 Fixed easy style issues. 2018-01-16 17:48:12 -06:00
CreedTheFreak 081c6f0263 Update plugin.yml mute command usage 2018-01-16 17:48:11 -06:00
delbertina fc590f82a2 Added check to display mute reason when notifying 2018-01-16 17:48:10 -06:00
delbertina 729af4bb4d Added mute format to all msg files 2018-01-16 17:48:09 -06:00
CreedTheFreak c8cb9b3735 fixed some wonky commit thing that happened, thus the following modifications are brought to you by Delbertina. 2018-01-16 17:21:54 -06:00
CreedTheFreak 4f8ea06db1 We have added the ability for the Mute to contain a reason, which is stored for the duration of the mute in the user's data file. Currently we need to add in the mute reason code into some other commands such as /afk and /me and /seen ect. We will also need to fix a problem with the reason when we dont add in a time frame for the mute, which should mute the player indefinatly rather then cancelling the mute and throwing a DataFormat exception. 2018-01-16 17:21:53 -06:00
CreedTheFreak 9378df0ff2 Started work on implementing the mute reason, and decided to write it to the UserData just like the Ban and TempBan reasons 2018-01-16 17:21:52 -06:00
CreedTheFreak 3444c8b0d6 Merge branch 'mute_reason_changes' into final_mute_reason_issue#385
Updating local changes made on mute_reason_changes into the final branch
2017-12-26 17:20:40 -08:00
CreedTheFreak 822315a279 Updated the former pull request to include the specified formatting changes, and small edits to the hasMuteReason and Commandmute dealing with the muteReason. I also included the ability to see the mute reason from the seenOffline method which is identical to the seenOnline code. 2017-12-26 16:09:46 -08:00
CreedTheFreak 732da86710 Merge remote-tracking branch 'magnarisa/final_mute_reason_issue#385' into mute_reason_changes
Updated a clean branch with the changes we have made so far.
2017-12-26 08:23:53 -08:00
CreedTheFreak 5fbc412542 Merge remote-tracking branch 'upstream/2.x' into final_mute_reason_issue#385 2017-12-26 08:16:46 -08:00
CreedTheFreak f0b262cbd5 Merge pull request #15 from delbertina/mutes385
Added 8 new messages for "...Reason" versions of mute messages
2017-12-23 22:13:57 -08:00
delbertina ff37ef3bc5 Added reason stuff to msg command and deleted reference line in seen command. Oops! 2017-12-24 00:03:36 -06:00
CreedTheFreak 68fab2c328 Merge branch 'mutes385' of https://github.com/delbertina/Essentials into final_mute_reason_issue#385
Testing PR Changes
2017-12-23 22:03:01 -08:00
CreedTheFreak f9d81c4302 Merge branch 'mutes385' of https://github.com/delbertina/Essentials into final_mute_reason_issue#385
Testing PR
2017-12-23 21:51:21 -08:00
delbertina 3d33bbc33d Added 8 new messages for "...Reason" versions of mute messages and implemented em. 2017-12-20 00:35:51 -06:00
CreedTheFreak 53c604c1b5 Merge pull request #14 from delbertina/mutes385
Fixed spacing
2017-12-18 18:53:57 -08:00
CreedTheFreak 2975118e5b Merge branch 'mutes385' of https://github.com/delbertina/Essentials into final_mute_reason_issue#385 2017-12-18 18:40:27 -08:00
delbertina e3ee9cb4c7 Fixed logic error in hasMuteReason and errors being thrown from seen and whois. 2017-12-18 20:37:34 -06:00
CreedTheFreak 297a616460 Merge branch 'mutes385' of https://github.com/delbertina/Essentials into final_mute_reason_issue#385 2017-12-16 23:48:27 -08:00
delbertina afe0ff0ca7 Added space before reason when a muted player tries to talk. 2017-12-17 01:46:43 -06:00
CreedTheFreak adf1bc291c Merge branch 'mutes385' of https://github.com/delbertina/Essentials into final_mute_reason_issue#385 2017-12-16 22:27:52 -08:00
delbertina 034ffbd0bc Added space when adding reason to string. 2017-12-17 00:16:06 -06:00
delbertina 127a7bb2ce Merge branch 'mutes385' of https://github.com/delbertina/Essentials into mutes385
Updated local copy
Conflicts:
	Essentials/src/com/earth2me/essentials/commands/Commandafk.java
	Essentials/src/com/earth2me/essentials/commands/Commandmail.java
	Essentials/src/com/earth2me/essentials/commands/Commandme.java
	Essentials/src/com/earth2me/essentials/commands/Commandr.java
	Essentials/src/com/earth2me/essentials/commands/Commandseen.java
	Essentials/src/com/earth2me/essentials/commands/Commandwhois.java
2017-12-17 00:02:52 -06:00
delbertina e8bfac0790 Added space when adding reason to string. Dirty :/ 2017-12-16 23:26:09 -06:00
CreedTheFreak 62d5dd3516 Merge remote-tracking branch 'magnarisa/final_mute_reason_issue#385' into final_mute_reason_issue#385
Updated my local repos for testing purposes
2017-12-16 19:43:56 -08:00
CreedTheFreak bcd66fec39 Merge pull request #12 from delbertina/mutes385
Address requested changes to formatting and logic
2017-12-16 19:40:27 -08:00
delbertina 849b329213 Changed if else blocks to ternary operators. Not sure if way to avoid weird empty string usage. 2017-12-02 20:35:44 -06:00
delbertina d555c1b081 Added method hasMuteReason in UserData. 2017-12-02 19:46:46 -06:00
delbertina 43cbab37f0 Changed muteFormat to muteReason.
Removed space at beginning of muteReason.
2017-11-26 01:32:22 -06:00
delbertina 6f7af90488 Fixed easy style issues. 2017-11-26 00:55:05 -06:00
CreedTheFreak fcda6c3b3b Merge pull request #11 from CreedTheFreak/final_mute_reason_issue#385
Update plugin.yml mute command usage
2017-09-17 15:39:01 -07:00
CreedTheFreak 910ef26c79 Update plugin.yml mute command usage 2017-09-17 15:36:06 -07:00
Taylor 1664da55a4 Merge pull request #10 from CreedTheFreak/commit_squashing
Final Implementation and the squasing of many commits
2017-09-17 16:55:14 -05:00
CreedTheFreak f8ea7f5e1f Implemented the ability to add a reason while muting a
player. The form of the mute is /mute [Player] [Time] [Reason] or /mute
[Player] [Reason] or /mute [Player] [Time] or /mute [Player]. These are
the various forms of the mute command and acts exactly like the old
command just with a reason.

The final adjustments to the MuteReason
2017-09-16 22:27:34 -07:00
delbertina b0205b9499 Added check to display mute reason when notifying 2017-09-03 23:02:56 -05:00
Taylor e05796f80e Merge pull request #4 from delbertina/msgs385
Added mute format to all msg files
2017-09-03 22:10:19 -05:00
delbertina a70fa78267 Added mute format to all msg files 2017-09-03 22:03:17 -05:00
CreedTheFreak e20693de60 Merge pull request #3 from CreedTheFreak/update_branch
Modifications Brought To you by Delbertina
2017-09-03 19:54:20 -07:00
CreedTheFreak f10a766442 fixed some wonky commit thing that happened, thus the following modifications are brought to you by Delbertina. 2017-09-03 19:49:57 -07:00
CreedTheFreak 86315fed8d Merge pull request #1 from CreedTheFreak/mute/jail_reason_issue#385
Mute reason issue#385
2017-09-03 14:46:40 -07:00
CreedTheFreak 4ff9fe8666 We have added the ability for the Mute to contain a reason, which is stored for the duration of the mute in the user's data file. Currently we need to add in the mute reason code into some other commands such as /afk and /me and /seen ect. We will also need to fix a problem with the reason when we dont add in a time frame for the mute, which should mute the player indefinatly rather then cancelling the mute and throwing a DataFormat exception. 2017-09-03 14:41:32 -07:00
CreedTheFreak 3512c4c8e6 Started work on implementing the mute reason, and decided to write it to the UserData just like the Ban and TempBan reasons 2017-09-02 20:04:25 -07:00
214 changed files with 46086 additions and 36510 deletions

No files matched your search

+13
View File
@@ -0,0 +1,13 @@
# Currently used
patreon: EssentialsX
# Currently not used
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
#open_collective: # Replace with a single Open Collective username
#ko_fi: # Replace with a single Ko-fi username
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
#liberapay: # Replace with a single Liberapay username
#issuehunt: # Replace with a single IssueHunt username
#otechie: # Replace with a single Otechie username
#custom: # Replace with a single custom sponsorship URL
+18 -53
View File
@@ -1,53 +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/kits.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/
+5 -15
View File
@@ -1,23 +1,13 @@
language: java
branches:
only:
- 2.x
- 1.13
jdk:
- openjdk8
cache:
directories:
- .buildtools
- $HOME/.m2
before_install:
- mkdir -p .buildtools
- cd .buildtools
- wget -O BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
- rm -r work/
- java -jar BuildTools.jar --rev 1.8
- java -jar BuildTools.jar --rev 1.8.3
- java -jar BuildTools.jar --rev 1.9
- java -jar BuildTools.jar --rev 1.9.4
- java -jar BuildTools.jar --rev 1.13.1
- cd ..
- chmod +x scripts/buildtools.sh
- scripts/buildtools.sh
+27 -31
View File
@@ -6,25 +6,18 @@
<parent>
<groupId>net.ess3</groupId>
<artifactId>EssentialsXParent</artifactId>
<version>2.16.0</version>
<version>2.17.0</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>3.7.0</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>3.1.0</version>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
@@ -41,6 +34,15 @@
</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>
@@ -48,26 +50,32 @@
<dependencies>
<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.16.0</version>
<version>2.17.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>UpdatedMetaProvider</artifactId>
<version>2.16.0</version>
<version>2.17.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>1_8_R1Provider</artifactId>
<version>2.16.0</version>
<version>2.17.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
@@ -79,7 +87,7 @@
<dependency>
<groupId>net.ess3</groupId>
<artifactId>1_8_R2Provider</artifactId>
<version>2.16.0</version>
<version>2.17.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
@@ -91,32 +99,20 @@
<dependency>
<groupId>net.ess3</groupId>
<artifactId>LegacyProvider</artifactId>
<version>2.16.0</version>
<version>2.17.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>ReflectionProvider</artifactId>
<version>2.16.0</version>
<version>2.17.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>FlattenedProvider</artifactId>
<version>2.16.0</version>
<version>2.17.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
</repositories>
</project>
@@ -1,7 +1,5 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
@@ -15,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);
@@ -231,10 +230,43 @@ public class Enchantments {
ALIASENCHANTMENTS.put("channel", channelling);
}
} catch (IllegalArgumentException ignored) {}
try { // 1.14
Enchantment multishot = Enchantment.getByName("MULTISHOT");
if (multishot != null) {
ENCHANTMENTS.put("multishot", multishot);
ALIASENCHANTMENTS.put("tripleshot", multishot);
}
Enchantment quickCharge = Enchantment.getByName("QUICK_CHARGE");
if (quickCharge != null) {
ENCHANTMENTS.put("quickcharge", quickCharge);
ALIASENCHANTMENTS.put("quickdraw", quickCharge);
ALIASENCHANTMENTS.put("fastcharge", quickCharge);
ALIASENCHANTMENTS.put("fastdraw", quickCharge);
}
Enchantment piercing = Enchantment.getByName("PIERCING");
if (piercing != null) {
ENCHANTMENTS.put("piercing", piercing);
}
} 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 = Enchantment.getByKey(NamespacedKey.minecraft(name.toLowerCase()));
Enchantment enchantment = null;
if (isFlat) { // 1.13+ only
enchantment = Enchantment.getByKey(NamespacedKey.minecraft(name.toLowerCase()));
}
if (enchantment == null) {
enchantment = Enchantment.getByName(name.toUpperCase());
}
@@ -196,27 +196,34 @@ 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 = getItemDbFromConfig();
confList.add(itemDb);
execTimer.mark("Init(Worth/ItemDB)");
jails = new Jails(this);
confList.add(jails);
execTimer.mark("Init(Jails)");
@@ -241,6 +248,10 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
), "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"));
@@ -92,7 +92,7 @@ public class EssentialsEntityListener implements Listener {
class PowerToolInteractTask implements Runnable {
@Override
public void run() {
attacker.getServer().dispatchCommand(attacker.getBase(), command);
attacker.getBase().chat("/" + command);
LOGGER.log(Level.INFO, String.format("[PT] %s issued server command: /%s", attacker.getName(), command));
}
}
@@ -159,6 +159,14 @@ public class EssentialsEntityListener implements Listener {
}
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerDeathInvEvent(final PlayerDeathEvent event) {
final User user = ess.getUser(event.getEntity());
if (user.isAuthorized("essentials.keepinv")) {
event.setKeepInventory(true);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onFoodLevelChange(final FoodLevelChangeEvent event) {
if (event.getEntity() instanceof Player) {
@@ -7,13 +7,9 @@ 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 org.bukkit.BanEntry;
import org.bukkit.BanList;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.*;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
@@ -34,11 +30,7 @@ import org.bukkit.inventory.PlayerInventory;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -57,10 +49,15 @@ public class EssentialsPlayerListener implements Listener {
public void registerEvents() {
ess.getServer().getPluginManager().registerEvents(this, ess);
if (isEntityPickupEvent()) {
ess.getServer().getPluginManager().registerEvents(new PlayerListener1_12(), ess);
ess.getServer().getPluginManager().registerEvents(new PickupListener1_12(), ess);
} else {
ess.getServer().getPluginManager().registerEvents(new PlayerListenerPre1_12(), ess);
ess.getServer().getPluginManager().registerEvents(new PickupListenerPre1_12(), ess);
}
if (isCommandSendEvent()) {
ess.getServer().getPluginManager().registerEvents(new CommandSendListener(), ess);
}
}
@@ -80,7 +77,9 @@ public class EssentialsPlayerListener implements Listener {
final User user = ess.getUser(event.getPlayer());
if (user.isMuted()) {
event.setCancelled(true);
user.sendMessage(tl("voiceSilenced"));
user.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
LOGGER.info(tl("mutedUserSpeaks", user.getName(), event.getMessage()));
}
try {
@@ -181,7 +180,7 @@ public class EssentialsPlayerListener implements Listener {
}
}
user.updateActivityOnInteract(false);
user.updateActivity(false);
if (!user.isHidden()) {
user.setLastLogout(System.currentTimeMillis());
}
@@ -219,7 +218,7 @@ public class EssentialsPlayerListener implements Listener {
final long currentTime = System.currentTimeMillis();
dUser.checkMuteTimeout(currentTime);
dUser.updateActivityOnInteract(false);
dUser.updateActivity(false);
dUser.stopTransaction();
class DelayJoinTask implements Runnable {
@@ -597,11 +596,13 @@ public class EssentialsPlayerListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerInteract(final PlayerInteractEvent event) {
boolean updateActivity = true;
switch (event.getAction()) {
case RIGHT_CLICK_BLOCK:
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()));
}
@@ -623,8 +624,14 @@ public class EssentialsPlayerListener implements Listener {
}
}
break;
case PHYSICAL:
updateActivity = false;
break;
}
if (updateActivity) {
ess.getUser(event.getPlayer()).updateActivityOnInteract(true);
}
}
// This method allows the /jump lock feature to work, allows teleporting while flying #EasterEgg
@@ -641,7 +648,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());
@@ -671,7 +678,7 @@ public class EssentialsPlayerListener implements Listener {
class PowerToolUseTask implements Runnable {
@Override
public void run() {
user.getServer().dispatchCommand(user.getBase(), command);
user.getBase().chat("/" + command);
LOGGER.log(Level.INFO, String.format("[PT] %s issued server command: /%s", user.getName(), command));
}
}
@@ -727,6 +734,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;
@@ -802,8 +810,16 @@ public class EssentialsPlayerListener implements Listener {
}
}
private final class PlayerListenerPre1_12 implements Listener {
private static boolean isCommandSendEvent() {
try {
Class.forName("org.bukkit.event.player.PlayerCommandSendEvent");
return true;
} catch (ClassNotFoundException ignored) {
return false;
}
}
private final class PickupListenerPre1_12 implements Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerPickupItem(final org.bukkit.event.player.PlayerPickupItemEvent event) {
if (ess.getSettings().getDisableItemPickupWhileAfk()) {
@@ -814,8 +830,7 @@ public class EssentialsPlayerListener implements Listener {
}
}
private final class PlayerListener1_12 implements Listener {
private final class PickupListener1_12 implements Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerPickupItem(final org.bukkit.event.entity.EntityPickupItemEvent event) {
if (ess.getSettings().getDisableItemPickupWhileAfk() && event.getEntity() instanceof Player) {
@@ -825,4 +840,36 @@ public class EssentialsPlayerListener implements Listener {
}
}
}
private final class CommandSendListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL)
public void onCommandSend(final PlayerCommandSendEvent event) {
User user = ess.getUser(event.getPlayer());
ArrayList<String> removedCmds = new ArrayList<>(event.getCommands());
event.getCommands().removeIf(str -> shouldHideFromUser(str, user));
if (ess.getSettings().isDebug()) {
removedCmds.removeAll(event.getCommands());
ess.getLogger().info("Removed commands: " + removedCmds.toString());
}
}
/**
* Returns true if all of the following are true:
* - The command is a plugin command
* - The plugin command is from Essentials
* - There is no known alternative OR the alternative is overridden by Essentials
* - The user is not allowed to perform the given Essentials command
*/
private boolean shouldHideFromUser(String commandLabel, User user) {
PluginCommand command = ess.getServer().getPluginCommand(commandLabel);
return command != null
&& command.getPlugin().getName().equals("Essentials")
&& (ess.getSettings().isCommandOverridden(commandLabel) || (ess.getAlternativeCommandsHandler().getAlternative(commandLabel) == null))
&& !user.isAuthorized("essentials." + command.getName());
}
}
}
@@ -10,12 +10,18 @@ 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
"de.dytanic.cloudnet.bridge.BukkitBootstrap" // CloudNet v2 doing... something
);
private final transient IEssentials ess;
private boolean unsupportedLogged = false;
private boolean npeWarned = false;
@@ -31,13 +37,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 +52,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 +79,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) {
@@ -185,6 +185,8 @@ public interface ISettings extends IConf {
boolean cancelAfkOnInteract();
boolean sleepIgnoresAfkPlayers();
boolean isAfkListName();
String getAfkListName();
@@ -313,6 +315,8 @@ public interface ISettings extends IConf {
boolean isConfirmCommandEnabledByDefault(String commandName);
boolean isTeleportBackWhenFreedFromJail();
boolean isCompassTowardsHomePerm();
boolean isAllowWorldInBroadcastworld();
@@ -322,4 +326,8 @@ public interface ISettings extends IConf {
boolean isForceEnableRecipe();
boolean allowOldIdSigns();
boolean isWaterSafe();
boolean isSafeUsermap();
}
@@ -22,6 +22,8 @@ public interface IUser {
boolean isAuthorized(IEssentialsCommand cmd, String permissionPrefix);
boolean isPermissionSet(String node);
void healCooldown() throws Exception;
void giveMoney(BigDecimal value) throws MaxMoneyException;
@@ -184,5 +186,9 @@ public interface IUser {
void setPromptingClearConfirm(boolean prompt);
boolean isLastMessageReplyRecipient();
void setLastMessageReplyRecipient(boolean enabled);
Map<User, BigDecimal> getConfirmingPayments();
}
@@ -208,13 +208,19 @@ public class MetaItemStack {
stack.setItemMeta(meta);
} else if (split.length > 1 && split[0].equalsIgnoreCase("itemflags") && hasMetaPermission(sender, "itemflags", false, true, ess)) {
addItemFlags(string);
} else if (MaterialUtil.isFirework(stack.getType())) {//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 (MaterialUtil.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 (MaterialUtil.isBanner(stack.getType())) {
//WARNING - Meta for banners will be ignored after this point.
addBannerMeta(sender, false, string, ess);
if (stack.getType().toString().equals("SHIELD") && Enchantments.getByName(split[0]) != null) {
parseEnchantmentStrings(sender, allowUnsafe, split, ess);
} else {
//WARNING - Meta for banners will be ignored after this point.
addBannerMeta(sender, false, string, ess);
}
} 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("#"))) {
+21 -13
View File
@@ -1,10 +1,10 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.EnumUtil;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.*;
import java.util.*;
import java.util.logging.Level;
@@ -77,12 +77,19 @@ public enum Mob {
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"),
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"),
CAT("Cat", Enemies.FRIENDLY, "CAT"),
FOX("Fox", Enemies.FRIENDLY, "es", "FOX"),
PANDA("Panda", Enemies.NEUTRAL, "PANDA"),
PILLAGER("Pillager", Enemies.ENEMY, "PILLAGER"),
RAVAGER("Ravager", Enemies.ENEMY, "RAVAGER"),
TRADER_LLAMA("TraderLlama", Enemies.FRIENDLY, "TRADER_LLAMA"),
WANDERING_TRADER("WanderingTrader", Enemies.FRIENDLY, "WANDERING_TRADER")
;
public static final Logger logger = Logger.getLogger("Essentials");
@@ -100,16 +107,17 @@ public enum Mob {
this.bukkitType = type;
}
Mob(String n, Enemies en, String s, String typeName) {
this.suffix = s;
this.name = n;
this.type = en;
bukkitType = EnumUtil.getEntityType(typeName);
}
Mob(String n, Enemies en, String typeName) {
this.name = n;
this.type = en;
EntityType entityType;
try {
entityType = EntityType.valueOf(typeName);
} catch (IllegalArgumentException ignored) {
entityType = null;
}
bukkitType = entityType;
bukkitType = EnumUtil.getEntityType(typeName);
}
public String suffix = "s";
@@ -0,0 +1,224 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.EnumUtil;
import net.ess3.nms.refl.ReflUtil;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Villager;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static com.earth2me.essentials.utils.EnumUtil.getEntityType;
public class MobCompat {
// Constants for mobs added in later versions
public static final EntityType LLAMA = getEntityType("LLAMA");
public static final EntityType PARROT = getEntityType("PARROT");
public static final EntityType TROPICAL_FISH = getEntityType("TROPICAL_FISH");
public static final EntityType PANDA = getEntityType("PANDA");
public static final EntityType TRADER_LLAMA = getEntityType("TRADER_LLAMA");
// Constants for mobs that have changed since earlier versions
public static final EntityType CAT = getEntityType("CAT", "OCELOT");
public enum CatType {
// These are (loosely) Mojang names for the cats
SIAMESE("SIAMESE", "SIAMESE_CAT"),
WHITE("WHITE", "SIAMESE_CAT"),
RED("RED", "RED_CAT"),
TABBY("TABBY", "RED_CAT"),
TUXEDO("BLACK", "BLACK_CAT"),
BRITISH_SHORTHAIR("BRITISH_SHORTHAIR", "SIAMESE_CAT"),
CALICO("CALICO", "RED_CAT"),
PERSIAN("PERSIAN", "RED_CAT"),
RAGDOLL("RAGDOLL", "SIAMESE_CAT"),
JELLIE("JELLIE", "SIAMESE_CAT"),
BLACK("ALL_BLACK", "BLACK_CAT"),
;
private final String catTypeName;
private final String ocelotTypeName;
CatType(final String catTypeName, final String ocelotTypeName) {
this.catTypeName = catTypeName;
this.ocelotTypeName = ocelotTypeName;
}
}
public enum VillagerProfession {
// These are 1.14+ villager professions mapped to their respective pre-V&P profession and career
NONE("FARMER", "FARMER", "NONE"),
ARMORER("BLACKSMITH", "ARMORER"),
BUTCHER("FARMER", "BUTCHER"),
CARTOGRAPHER("LIBRARIAN", "CARTOGRAPHER"),
CLERIC("PRIEST", "CLERIC"),
FARMER("FARMER", "FARMER"),
FISHERMAN("FARMER", "FISHERMAN"),
FLETCHER("FARMER", "FLETCHER"),
LEATHERWORKER("BUTCHER", "LEATHERWORKER"),
LIBRARIAN("LIBRARIAN", "LIBRARIAN"),
MASON(null, null, "MASON"),
NITWIT("NITWIT", "NITWIT"),
SHEPHERD("FARMER", "SHEPHERD"),
TOOLSMITH("BLACKSMITH", "TOOL_SMITH", "TOOLSMITH"),
WEAPONSMITH("BLACKSMITH", "WEAPON_SMITH", "WEAPONSMITH")
;
private String oldProfession;
private String oldCareer;
private String newProfession;
VillagerProfession(final String oldProfession, final String career) {
this.oldProfession = oldProfession;
this.oldCareer = career;
this.newProfession = career;
}
VillagerProfession(final String oldProfession, final String oldCareer, final String newProfession) {
this.oldProfession = oldProfession;
this.oldCareer = oldCareer;
this.newProfession = newProfession;
}
private Villager.Profession asEnum() {
return EnumUtil.valueOf(Villager.Profession.class, newProfession, oldProfession);
}
}
// Older cats are Ocelots, whereas 1.14+ cats are Cats
private static Class catClass = ReflUtil.getClassCached("org.bukkit.entity.Cat");
private static Class catTypeClass = ReflUtil.getClassCached("org.bukkit.entity.Cat.Type");
private static Method catSetTypeMethod = (catClass == null || catTypeClass == null) ? null : ReflUtil.getMethodCached(catClass, "setCatType", catTypeClass);
private static boolean isNewCat() {
return (catClass != null && catTypeClass != null && catSetTypeMethod != null);
}
public static void setCatType(final Entity entity, final CatType type) {
if (isNewCat()) {
try {
catSetTypeMethod.invoke(entity, EnumUtil.valueOf(catTypeClass, type.catTypeName));
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
} else {
((Ocelot) entity).setCatType(Ocelot.Type.valueOf(type.ocelotTypeName));
}
}
// Older villagers have professions and careers, 1.14+ villagers only have professions
private static Class villagerCareerClass = ReflUtil.getClassCached("org.bukkit.entity.Villager.Career");
private static Method villagerSetCareerMethod = (villagerCareerClass == null) ? null : ReflUtil.getMethodCached(Villager.class, "setCareer", villagerCareerClass);
private static boolean isCareerVillager() {
return (villagerCareerClass != null && villagerSetCareerMethod != null);
}
public static void setVillagerProfession(final Entity entity, final VillagerProfession profession) {
if (!isCareerVillager()) {
((Villager) entity).setProfession(profession.asEnum());
} else {
((Villager) entity).setProfession(profession.asEnum());
try {
villagerSetCareerMethod.invoke(entity, EnumUtil.valueOf(villagerCareerClass, profession.oldCareer));
} catch (Exception e) {
e.printStackTrace();
}
}
}
// Only 1.14+ villagers have biome variants
public static void setVillagerType(final Entity entity, final String type) {
Class typeEnum = ReflUtil.getClassCached("org.bukkit.entity.Villager.Type");
if (typeEnum == null) return;
Method villagerSetTypeMethod = ReflUtil.getMethodCached(Villager.class, "setVillagerType", typeEnum);
try {
villagerSetTypeMethod.invoke(entity, EnumUtil.valueOf(typeEnum, type));
} catch (Exception e) {
e.printStackTrace();
}
}
// Llamas only exist in 1.11+
public static void setLlamaColor(final Entity entity, final String color) {
Class llamaClass = ReflUtil.getClassCached("org.bukkit.entity.Llama");
if (llamaClass == null) return;
Class colorEnum = ReflUtil.getClassCached("org.bukkit.entity.Llama.Color");
Method setVariantMethod = ReflUtil.getMethodCached(llamaClass, "setColor");
try {
setVariantMethod.invoke(entity, EnumUtil.valueOf(colorEnum, color));
} catch (Exception e) {
e.printStackTrace();
}
}
// Parrots only exist in 1.12+
public static void setParrotVariant(final Entity entity, final String variant) {
Class parrotClass = ReflUtil.getClassCached("org.bukkit.entity.Parrot");
if (parrotClass == null) return;
Class variantEnum = ReflUtil.getClassCached("org.bukkit.entity.Parrot.Variant");
Method setVariantMethod = ReflUtil.getMethodCached(parrotClass, "setVariant");
try {
setVariantMethod.invoke(entity, EnumUtil.valueOf(variantEnum, variant));
} catch (Exception e) {
e.printStackTrace();
}
}
// Tropical fish only exist in 1.13+
public static void setTropicalFishPattern(final Entity entity, final String pattern) {
Class tropicalFishClass = ReflUtil.getClassCached("org.bukkit.entity.TropicalFish");
if (tropicalFishClass == null) return;
Class patternEnum = ReflUtil.getClassCached("org.bukkit.entity.TropicalFish.Pattern");
Method setPatternMethod = ReflUtil.getMethodCached(tropicalFishClass, "setPattern");
try {
setPatternMethod.invoke(entity, EnumUtil.valueOf(patternEnum, pattern));
} catch (Exception e) {
e.printStackTrace();
}
}
// Mushroom cow variant API only exists in 1.14+
public static void setMooshroomVariant(final Entity entity, final String variant) {
Class mushroomCowClass = ReflUtil.getClassCached("org.bukkit.entity.MushroomCow");
Class variantEnum = ReflUtil.getClassCached("org.bukkit.entity.MushroomCow.Variant");
if (mushroomCowClass == null || variantEnum == null) return;
Method setVariantMethod = ReflUtil.getMethodCached(mushroomCowClass, "setVariant");
try {
setVariantMethod.invoke(entity, EnumUtil.valueOf(variantEnum, variant));
} catch (Exception e) {
e.printStackTrace();
}
}
// Pandas only exists in 1.14+
public static void setPandaGene(final Entity entity, final String gene, final boolean mainGene) {
Class pandaClass = ReflUtil.getClassCached("org.bukkit.entity.Panda");
if (pandaClass == null) return;
Class geneEnum = ReflUtil.getClassCached("org.bukkit.entity.Panda.Gene");
Method setGeneMethod;
if (mainGene) {
setGeneMethod = ReflUtil.getMethodCached(pandaClass, "setMainGene");
} else {
setGeneMethod = ReflUtil.getMethodCached(pandaClass, "setHiddenGene");
}
try {
setGeneMethod.invoke(entity, EnumUtil.valueOf(geneEnum, gene));
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -17,8 +17,10 @@ import static com.earth2me.essentials.I18n.tl;
public enum MobData {
BABY_AGEABLE("baby", Ageable.class, Data.BABY, true),
ADULT_AGEABLE("adult", Ageable.class, Data.ADULT, true),
BABY_CAT("kitten", MobCompat.CAT, Data.BABY, false),
BABY_PIG("piglet", EntityType.PIG, Data.BABY, false),
BABY_WOLF("puppy", EntityType.WOLF, Data.BABY, false),
BABY_CHICKEN("chick", EntityType.CHICKEN, Data.BABY, false),
@@ -57,13 +59,19 @@ public enum MobData {
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),
ORANGE_CAT("orange", EntityType.OCELOT, Ocelot.Type.RED_CAT, false),
TABBY_CAT("tabby", EntityType.OCELOT, Ocelot.Type.RED_CAT, false),
BLACK_CAT("black", EntityType.OCELOT, Ocelot.Type.BLACK_CAT, true),
TUXEDO_CAT("tuxedo", EntityType.OCELOT, Ocelot.Type.BLACK_CAT, false),
SIAMESE_CAT("siamese", MobCompat.CAT, MobCompat.CatType.SIAMESE, true),
WHITE_CAT("white", MobCompat.CAT, MobCompat.CatType.WHITE, false),
RED_CAT("red", MobCompat.CAT, MobCompat.CatType.RED, true),
ORANGE_CAT("orange", MobCompat.CAT, MobCompat.CatType.RED, false),
TABBY_CAT("tabby", MobCompat.CAT, MobCompat.CatType.TABBY, true),
BLACK_CAT("black", MobCompat.CAT, MobCompat.CatType.BLACK, true),
TUXEDO_CAT("tuxedo", MobCompat.CAT, MobCompat.CatType.TUXEDO, true),
BRITISH_SHORTHAIR_CAT("britishshorthair", MobCompat.CAT, MobCompat.CatType.BRITISH_SHORTHAIR, true),
CALICO_CAT("calico", MobCompat.CAT, MobCompat.CatType.CALICO, true),
PERSIAN_CAT("persian", MobCompat.CAT, MobCompat.CatType.PERSIAN, true),
RAGDOLL_CAT("ragdoll", MobCompat.CAT, MobCompat.CatType.RAGDOLL, true),
JELLIE_CAT("jellie", MobCompat.CAT, MobCompat.CatType.JELLIE, true),
ALL_BLACK_CAT("allblack", MobCompat.CAT, MobCompat.CatType.BLACK, true),
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),
@@ -83,31 +91,69 @@ public enum MobData {
SADDLE_PIG("saddle", EntityType.PIG, Data.PIGSADDLE, true),
ANGRY_WOLF("angry", EntityType.WOLF, Data.ANGRY, true),
RABID_WOLF("rabid", EntityType.WOLF, Data.ANGRY, false),
FARMER_VILLAGER("farmer", EntityType.VILLAGER, Villager.Profession.FARMER, true),
LIBRARIAN_VILLAGER("librarian", EntityType.VILLAGER, Villager.Profession.LIBRARIAN, true),
PRIEST_VILLAGER("priest", EntityType.VILLAGER, Villager.Profession.PRIEST, true),
FATHER_VILLAGER("father", EntityType.VILLAGER, Villager.Profession.PRIEST, false),
SMITH_VILLAGER("smith", EntityType.VILLAGER, Villager.Profession.BLACKSMITH, true),
BUTCHER_VILLAGER("butcher", EntityType.VILLAGER, Villager.Profession.BUTCHER, true),
VILLAGER("villager", EntityType.VILLAGER, MobCompat.VillagerProfession.NONE, true),
ARMORER_VILLAGER("armorer", EntityType.VILLAGER, MobCompat.VillagerProfession.ARMORER, true),
BUTCHER_VILLAGER("butcher", EntityType.VILLAGER, MobCompat.VillagerProfession.BUTCHER, true),
CARTOGRAPHER_VILLAGER("cartographer", EntityType.VILLAGER, MobCompat.VillagerProfession.CARTOGRAPHER, true),
CLERIC_VILLAGER("cleric", EntityType.VILLAGER, MobCompat.VillagerProfession.CLERIC, true),
FARMER_VILLAGER("farmer", EntityType.VILLAGER, MobCompat.VillagerProfession.FARMER, true),
FISHERMAN_VILLAGER("fisherman", EntityType.VILLAGER, MobCompat.VillagerProfession.FISHERMAN, true),
FLETCHER_VILLAGER("fletcher", EntityType.VILLAGER, MobCompat.VillagerProfession.FLETCHER, true),
LEATHERWORKER_VILLAGER("leatherworker", EntityType.VILLAGER, MobCompat.VillagerProfession.LEATHERWORKER, true),
LIBRARIAN_VILLAGER("librarian", EntityType.VILLAGER, MobCompat.VillagerProfession.LIBRARIAN, true),
MASON_VILLAGER("mason", EntityType.VILLAGER, MobCompat.VillagerProfession.MASON, true),
NITWIT_VILLAGER("nitwit", EntityType.VILLAGER, MobCompat.VillagerProfession.NITWIT, true),
SHEPHERD_VILLAGER("shepherd", EntityType.VILLAGER, MobCompat.VillagerProfession.SHEPHERD, true),
TOOLSMITH_VILLAGER("toolsmith", EntityType.VILLAGER, MobCompat.VillagerProfession.TOOLSMITH, true),
WEAPONSMITH_VILLAGER("weaponsmith", EntityType.VILLAGER, MobCompat.VillagerProfession.WEAPONSMITH, true),
DESERT_VILLAGER("desert", EntityType.VILLAGER, "villagertype:DESERT", true),
JUNGLE_VILLAGER("jungle", EntityType.VILLAGER, "villagertype:JUNGLE", true),
PLAINS_VILLAGER("plains", EntityType.VILLAGER, "villagertype:PLAINS", true),
SAVANNA_VILLAGER("savanna", EntityType.VILLAGER, "villagertype:SAVANNA", true),
SNOWY_VILLAGER("snowy", EntityType.VILLAGER, "villagertype:SNOWY", true),
SWAMP_VILLAGER("swamp", EntityType.VILLAGER, "villagertype:SWAMP", true),
TAIGA_VILLAGER("taiga", EntityType.VILLAGER, "villagertype:TAIGA", true),
SIZE_SLIME("", "<1-100>", EntityType.SLIME.getEntityClass(), Data.SIZE, true),
NUM_EXPERIENCE_ORB("", "<1-2000000000>", EntityType.EXPERIENCE_ORB, Data.EXP, true),
RED_PARROT("red", EntityType.PARROT, Parrot.Variant.RED, true),
GREEN_PARROT("green", EntityType.PARROT, Parrot.Variant.GREEN, true),
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);
RED_PARROT("red", MobCompat.PARROT, "parrot:RED", true),
GREEN_PARROT("green", MobCompat.PARROT, "parrot:GREEN", true),
BLUE_PARROT("blue", MobCompat.PARROT, "parrot:BLUE", true),
CYAN_PARROT("cyan", MobCompat.PARROT, "parrot:CYAN", true),
GRAY_PARROT("gray", MobCompat.PARROT, "parrot:GRAY", true),
KOB_TROPICAL_FISH("kob", MobCompat.TROPICAL_FISH, "tropicalfish:KOB", true),
SUNSTREAK_TROPICAL_FISH("sunstreak", MobCompat.TROPICAL_FISH, "tropicalfish:SUNSTREAK", true),
SNOOPER_TROPICAL_FISH("snooper", MobCompat.TROPICAL_FISH, "tropicalfish:SNOOPER", true),
DASHER_TROPICAL_FISH("dasher", MobCompat.TROPICAL_FISH, "tropicalfish:DASHER", true),
BRINELY_TROPICAL_FISH("brinely", MobCompat.TROPICAL_FISH, "tropicalfish:BRINELY", true),
SPOTTY_TROPICAL_FISH("spotty", MobCompat.TROPICAL_FISH, "tropicalfish:SPOTTY", true),
FLOPPER_TROPICAL_FISH("flopper", MobCompat.TROPICAL_FISH, "tropicalfish:FLOPPER", true),
STRIPEY_TROPICAL_FISH("stripey", MobCompat.TROPICAL_FISH, "tropicalfish:STRIPEY", true),
GLITTER_TROPICAL_FISH("glitter", MobCompat.TROPICAL_FISH, "tropicalfish:GLITTER", true),
BLOCKFISH_TROPICAL_FISH("blockfish", MobCompat.TROPICAL_FISH, "tropicalfish:BLOCKFISH", true),
BETTY_TROPICAL_FISH("betty", MobCompat.TROPICAL_FISH, "tropicalfish:BETTY", true),
CLAYFISH_TROPICAL_FISH("clayfish", MobCompat.TROPICAL_FISH, "tropicalfish:CLAYFISH", true),
BROWN_MUSHROOM_COW("brown", EntityType.MUSHROOM_COW, "mooshroom:BROWN", true),
RED_MUSHROOM_COW("red", EntityType.MUSHROOM_COW, "mooshroom:RED", true),
AGGRESSIVE_PANDA_MAIN("aggressive", MobCompat.PANDA, "pandamain:AGGRESSIVE", true),
LAZY_PANDA_MAIN("lazy", MobCompat.PANDA, "pandamain:LAZY", true),
WORRIED_PANDA_MAIN("worried", MobCompat.PANDA, "pandamain:WORRIED", true),
PLAYFUL_PANDA_MAIN("playful", MobCompat.PANDA, "pandamain:PLAYFUL", true),
BROWN_PANDA_MAIN("brown", MobCompat.PANDA, "pandamain:BROWN", true),
WEAK_PANDA_MAIN("weak", MobCompat.PANDA, "pandamain:WEAK", true),
AGGRESSIVE_PANDA_HIDDEN("aggressive_hidden", MobCompat.PANDA, "pandahidden:AGGRESSIVE", true),
LAZY_PANDA_HIDDEN("lazy_hidden", MobCompat.PANDA, "pandahidden:LAZY", true),
WORRIED_PANDA_HIDDEN("worried_hidden", MobCompat.PANDA, "pandahidden:WORRIED", true),
PLAYFUL_PANDA_HIDDEN("playful_hidden", MobCompat.PANDA, "pandahidden:PLAYFUL", true),
BROWN_PANDA_HIDDEN("brown_hidden", MobCompat.PANDA, "pandahidden:BROWN", true),
WEAK_PANDA_HIDDEN("weak_hidden", MobCompat.PANDA, "pandahidden:WEAK", true),
CREAMY_LLAMA("creamy", MobCompat.LLAMA, "llama:CREAMY", true),
WHITE_LLAMA("white", MobCompat.LLAMA, "llama:WHITE", true),
BROWN_LLAMA("brown", MobCompat.LLAMA, "llama:BROWN", true),
GRAY_LLAMA("gray", MobCompat.LLAMA, "llama:GRAY", true),
CREAMY_TRADER_LLAMA("creamy", MobCompat.TRADER_LLAMA, "llama:CREAMY", true),
WHITE_TRADER_LLAMA("white", MobCompat.TRADER_LLAMA, "llama:WHITE", true),
BROWN_TRADER_LLAMA("brown", MobCompat.TRADER_LLAMA, "llama:BROWN", true),
GRAY_TRADER_LLAMA("gray", MobCompat.TRADER_LLAMA, "llama:GRAY", true)
;
@@ -127,6 +173,8 @@ public enum MobData {
SIZE
}
public static final Logger logger = Logger.getLogger("Essentials");
MobData(String n, Object type, Object value, boolean isPublic) {
@@ -157,9 +205,11 @@ public enum MobData {
public static LinkedHashMap<String, MobData> getPossibleData(final Entity spawned, boolean publicOnly) {
LinkedHashMap<String, MobData> mobList = new LinkedHashMap<String, MobData>();
for (MobData data : MobData.values()) {
if (data.type instanceof EntityType && spawned.getType().equals(data.type) && ((publicOnly && data.isPublic) || !publicOnly)) {
if (data.type == null || (publicOnly && !data.isPublic)) continue;
if (data.type instanceof EntityType && spawned.getType().equals(data.type)) {
mobList.put(data.nickname.toLowerCase(Locale.ENGLISH), data);
} else if (data.type instanceof Class && ((Class) data.type).isAssignableFrom(spawned.getClass()) && ((publicOnly && data.isPublic) || !publicOnly)) {
} else if (data.type instanceof Class && ((Class) data.type).isAssignableFrom(spawned.getClass())) {
mobList.put(data.nickname.toLowerCase(Locale.ENGLISH), data);
}
}
@@ -250,10 +300,10 @@ public enum MobData {
((Horse) spawned).setColor((Horse.Color) this.value);
} else if (this.value instanceof Horse.Style) {
((Horse) spawned).setStyle((Horse.Style) this.value);
} else if (this.value instanceof Ocelot.Type) {
((Ocelot) spawned).setCatType((Ocelot.Type) this.value);
} else if (this.value instanceof Villager.Profession) {
((Villager) spawned).setProfession((Villager.Profession) this.value);
} else if (this.value instanceof MobCompat.CatType) {
MobCompat.setCatType(spawned, (MobCompat.CatType) this.value);
} else if (this.value instanceof MobCompat.VillagerProfession) {
MobCompat.setVillagerProfession(spawned, (MobCompat.VillagerProfession) this.value);
} else if (this.value instanceof Material) {
if (this.type.equals(EntityType.HORSE)) {
((Horse) spawned).setTamed(true);
@@ -263,10 +313,33 @@ public enum MobData {
InventoryWorkaround.setItemInMainHand(invent, new ItemStack((Material) this.value, 1));
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
}
} 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);
} else if (this.value instanceof String) {
final String[] split = ((String) this.value).split(":");
switch (split[0]) {
case "parrot":
MobCompat.setParrotVariant(spawned, split[1]);
break;
case "tropicalfish":
MobCompat.setTropicalFishPattern(spawned, split[1]);
break;
case "mooshroom":
MobCompat.setMooshroomVariant(spawned, split[1]);
break;
case "pandamain":
MobCompat.setPandaGene(spawned, split[1], true);
break;
case "pandahidden":
MobCompat.setPandaGene(spawned, split[1], false);
break;
case "llama":
MobCompat.setLlamaColor(spawned, split[1]);
break;
case "villagertype":
MobCompat.setVillagerType(spawned, split[1]);
break;
}
} else {
logger.warning("Unknown mob data type: " + this.toString());
}
}
}
@@ -14,6 +14,7 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.conversations.Conversation;
import org.bukkit.conversations.ConversationAbandonedEvent;
import org.bukkit.entity.*;
import org.bukkit.entity.memory.MemoryKey;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.*;
@@ -23,6 +24,7 @@ import org.bukkit.metadata.MetadataValue;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@@ -133,15 +135,24 @@ public class OfflinePlayer implements Player {
return world;
}
@Override
public void setRotation(float yaw, float pitch) {
location.setYaw(yaw);
location.setPitch(pitch);
}
public void setLocation(Location loc) {
location = loc;
world = loc.getWorld();
}
public void teleportTo(Location lctn) {
location = lctn;
world = location.getWorld();
}
public void teleportTo(Entity entity) {
teleportTo(entity.getLocation());
}
@Override
@@ -153,6 +164,11 @@ public class OfflinePlayer implements Player {
return null;
}
@Override
public Pose getPose() {
return null;
}
@Override
public boolean performCommand(String string) {
return false;
@@ -787,6 +803,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) {
}
@@ -1311,6 +1342,16 @@ public class OfflinePlayer implements Player {
return false;
}
@Override
public <T> T getMemory(MemoryKey<T> memoryKey) {
return null;
}
@Override
public <T> void setMemory(MemoryKey<T> memoryKey, T t) {
}
@Override
public <T extends Projectile> T launchProjectile(Class<? extends T> type, Vector vector) {
return null;
@@ -1320,6 +1361,11 @@ public class OfflinePlayer implements Player {
public void sendSignChange(Location arg0, String[] arg1) throws IllegalArgumentException {
}
@Override
public void sendSignChange(Location loc, String[] lines, DyeColor dyeColor) throws IllegalArgumentException {
}
@Override
public Location getBedSpawnLocation() {
return null;
@@ -1590,4 +1636,13 @@ public class OfflinePlayer implements Player {
@Override
public void updateCommands() {
}
@Override
public void openBook(ItemStack book) {
}
@Override
public PersistentDataContainer getPersistentDataContainer() {
return null;
}
}
@@ -1,13 +1,15 @@
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.LocationUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -22,21 +24,29 @@ import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.earth2me.essentials.I18n.tl;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import static com.earth2me.essentials.I18n.tl;
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;
@@ -493,6 +503,7 @@ public class Settings implements net.ess3.api.ISettings {
cancelAfkOnInteract = _cancelAfkOnInteract();
cancelAfkOnMove = _cancelAfkOnMove();
getFreezeAfkPlayers = _getFreezeAfkPlayers();
sleepIgnoresAfkPlayers = _sleepIgnoresAfkPlayers();
afkListName = _getAfkListName();
isAfkListName = !afkListName.equalsIgnoreCase("none");
itemSpawnBl = _getItemSpawnBlacklist();
@@ -535,14 +546,21 @@ public class Settings implements net.ess3.api.ISettings {
currencyFormat = _getCurrencyFormat();
unprotectedSigns = _getUnprotectedSign();
defaultEnabledConfirmCommands = _getDefaultEnabledConfirmCommands();
teleportBackWhenFreedFromJail = _isTeleportBackWhenFreedFromJail();
isCompassTowardsHomePerm = _isCompassTowardsHomePerm();
isAllowWorldInBroadcastworld = _isAllowWorldInBroadcastworld();
itemDbType = _getItemDbType();
forceEnableRecipe = _isForceEnableRecipe();
allowOldIdSigns = _allowOldIdSigns();
isWaterSafe = _isWaterSafe();
isSafeUsermap = _isSafeUsermap();
}
private List<Material> itemSpawnBl = new ArrayList<Material>();
void _lateLoadItemSpawnBlacklist() {
itemSpawnBl = _getItemSpawnBlacklist();
}
private List<Material> itemSpawnBl = new ArrayList<>();
@Override
public List<Material> itemSpawnBlacklist() {
@@ -551,7 +569,8 @@ public class Settings implements net.ess3.api.ISettings {
private List<Material> _getItemSpawnBlacklist() {
final List<Material> epItemSpwn = new ArrayList<>();
if (ess.getItemDb() == null) {
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;
}
@@ -561,7 +580,7 @@ public class Settings implements net.ess3.api.ISettings {
continue;
}
try {
final ItemStack iStack = ess.getItemDb().get(itemName);
final ItemStack iStack = itemDb.get(itemName);
epItemSpwn.add(iStack.getType());
} catch (Exception ex) {
logger.log(Level.SEVERE, tl("unknownItemInList", itemName, "item-spawn-blacklist"), ex);
@@ -686,12 +705,20 @@ public class Settings implements net.ess3.api.ISettings {
if (itemName.isEmpty()) {
continue;
}
ItemStack itemStack;
try {
itemStack = ess.getItemDb().get(itemName);
list.add(itemStack.getType());
} 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;
@@ -879,6 +906,17 @@ public class Settings implements net.ess3.api.ISettings {
return config.getBoolean("cancel-afk-on-interact", true);
}
private boolean sleepIgnoresAfkPlayers;
@Override
public boolean sleepIgnoresAfkPlayers() {
return sleepIgnoresAfkPlayers;
}
private boolean _sleepIgnoresAfkPlayers() {
return config.getBoolean("sleep-ignores-afk-players", true);
}
private String afkListName;
private boolean isAfkListName;
@@ -1448,6 +1486,17 @@ public class Settings implements net.ess3.api.ISettings {
return getDefaultEnabledConfirmCommands().contains(commandName.toLowerCase());
}
private boolean teleportBackWhenFreedFromJail;
private boolean _isTeleportBackWhenFreedFromJail() {
return config.getBoolean("teleport-back-when-freed-from-jail", true);
}
@Override
public boolean isTeleportBackWhenFreedFromJail() {
return teleportBackWhenFreedFromJail;
}
private boolean isCompassTowardsHomePerm;
private boolean _isCompassTowardsHomePerm() {
@@ -1502,4 +1551,29 @@ public class Settings implements net.ess3.api.ISettings {
public boolean allowOldIdSigns() {
return allowOldIdSigns;
}
private boolean isWaterSafe;
private boolean _isWaterSafe() {
boolean _isWaterSafe = config.getBoolean("is-water-safe", false);
LocationUtil.setIsWaterSafe(_isWaterSafe);
return _isWaterSafe;
}
@Override
public boolean isWaterSafe() {
return isWaterSafe;
}
private boolean isSafeUsermap;
private boolean _isSafeUsermap() {
return config.getBoolean("safe-usermap-names", true);
}
@Override
public boolean isSafeUsermap() {
return isSafeUsermap;
}
}
@@ -2,7 +2,9 @@ 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;
@@ -18,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;
@@ -49,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.
@@ -124,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);
}
}
}
@@ -209,6 +211,39 @@ public class Teleport implements net.ess3.api.ITeleport {
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
}
private void teleportOther(IUser teleporter, IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause) throws Exception {
double delay = ess.getSettings().getTeleportDelay();
Trade cashCharge = chargeFor;
if (teleporter != null && chargeFor != null) {
chargeFor.isAffordableFor(teleporter);
//This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world.
if (!chargeFor.getCommandCost(teleporter).equals(BigDecimal.ZERO)) {
//By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport.
cashCharge = new Trade(chargeFor.getCommandCost(teleporter), ess);
}
}
cooldown(true);
if (delay <= 0 || teleporter == null
|| teleporter.isAuthorized("essentials.teleport.timer.bypass")
|| teleportOwner.isAuthorized("essentials.teleport.timer.bypass")
|| teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
cooldown(false);
now(teleportee, target, cause);
if (teleporter != null && cashCharge != null) {
cashCharge.charge(teleporter);
}
return;
}
cancel(false);
warnUser(teleportee, delay);
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
}
//The respawn function is a wrapper used to handle tp fallback, on /jail and /home
@Override
public void respawn(final Trade chargeFor, TeleportCause cause) throws Exception {
@@ -231,7 +266,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) {
@@ -267,10 +302,16 @@ public class Teleport implements net.ess3.api.ITeleport {
//The back function is a wrapper used to teleportPlayer a player /back to their previous location.
@Override
public void back(Trade chargeFor) throws Exception {
back(teleportOwner, chargeFor);
}
//This function is a wrapper over the other back function for cases where another player performs back for them
@Override
public void back(IUser teleporter, Trade chargeFor) throws Exception {
tpType = TeleportType.BACK;
final Location loc = teleportOwner.getLastLocation();
teleportOwner.sendMessage(tl("backUsageMsg", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
teleport(teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND);
teleportOther(teleporter, teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND);
}
//This function is used to throw a user back after a jail sentence
@@ -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;
}
@@ -97,6 +97,11 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
return result;
}
@Override
public boolean isPermissionSet(final String node) {
return isPermSetCheck(node);
}
private boolean isAuthorizedCheck(final String node) {
if (base instanceof OfflinePlayer) {
@@ -116,6 +121,24 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
}
}
private boolean isPermSetCheck(final String node) {
if (base instanceof OfflinePlayer) {
return false;
}
try {
return ess.getPermissionsHandler().isPermissionSet(base, node);
} catch (Exception ex) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage(), ex);
} else {
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage());
}
return false;
}
}
@Override
public void healCooldown() throws Exception {
final Calendar now = new GregorianCalendar();
@@ -465,7 +488,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
return;
}
this.getBase().setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") ? true : set);
this.getBase().setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") || set && ess.getSettings().sleepIgnoresAfkPlayers());
if (set && !isAfk()) {
afkPosition = this.getLocation();
this.afkSince = System.currentTimeMillis();
@@ -522,12 +545,14 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
setJailed(false);
sendMessage(tl("haveBeenReleased"));
setJail(null);
try {
getTeleport().back();
} catch (Exception ex) {
if (ess.getSettings().isTeleportBackWhenFreedFromJail()) {
try {
getTeleport().respawn(null, TeleportCause.PLUGIN);
} catch (Exception ex1) {
getTeleport().back();
} catch (Exception ex) {
try {
getTeleport().respawn(null, TeleportCause.PLUGIN);
} catch (Exception ex1) {
}
}
}
return true;
@@ -546,6 +571,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
setMuteTimeout(0);
sendMessage(tl("canTalkAgain"));
setMuted(false);
setMuteReason(null);
return true;
}
}
@@ -879,7 +905,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();
@@ -74,6 +74,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
godmode = _getGodModeEnabled();
muted = _getMuted();
muteTimeout = _getMuteTimeout();
muteReason = _getMuteReason();
jailed = _getJailed();
jailTimeout = _getJailTimeout();
lastLogin = _getLastLogin();
@@ -93,6 +94,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
acceptingPay = _getAcceptingPay();
confirmPay = _getConfirmPay();
confirmClear = _getConfirmClear();
lastMessageReplyRecipient = _getLastMessageReplyRecipient();
}
private BigDecimal money;
@@ -446,6 +448,22 @@ public abstract class UserData extends PlayerExtension implements IConf {
config.save();
}
private boolean autoTeleportEnabled;
private boolean _getAutoTeleportEnabled() {
return config.getBoolean("teleportauto", false);
}
public boolean isAutoTeleportEnabled() {
return autoTeleportEnabled;
}
public void setAutoTeleportEnabled(boolean set) {
autoTeleportEnabled = set;
config.setProperty("teleportauto", set);
config.save();
}
private List<String> ignoredPlayers;
public List<String> _getIgnoredPlayers() {
@@ -503,6 +521,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
}
private boolean muted;
private String muteReason;
public boolean _getMuted() {
return config.getBoolean("muted", false);
@@ -522,6 +541,29 @@ public abstract class UserData extends PlayerExtension implements IConf {
config.save();
}
public String _getMuteReason() {
return config.getString("muteReason");
}
public String getMuteReason() {
return muteReason;
}
public void setMuteReason(String reason) {
if (reason == null) {
config.removeProperty("muteReason");
muteReason = null;
} else {
muteReason = reason;
config.setProperty("muteReason", reason);
}
config.save();
}
public boolean hasMuteReason(){
return muteReason != null;
}
private long muteTimeout;
private long _getMuteTimeout() {
@@ -759,15 +801,16 @@ public abstract class UserData extends PlayerExtension implements IConf {
}
public long getKitTimestamp(String name) {
name = name.replace('.', '_').replace('/', '_');
name = name.replace('.', '_').replace('/', '_').toLowerCase(Locale.ENGLISH);
if (kitTimestamps != null && kitTimestamps.containsKey(name)) {
return kitTimestamps.get(name);
}
return 0l;
return 0L;
}
public void setKitTimestamp(final String name, final long time) {
kitTimestamps.put(name.toLowerCase(Locale.ENGLISH), time);
public void setKitTimestamp(String name, final long time) {
name = name.replace('.', '_').replace('/', '_').toLowerCase(Locale.ENGLISH);
kitTimestamps.put(name, time);
config.setProperty("timestamps.kits", kitTimestamps);
config.save();
}
@@ -941,6 +984,22 @@ public abstract class UserData extends PlayerExtension implements IConf {
save();
}
private boolean lastMessageReplyRecipient;
private boolean _getLastMessageReplyRecipient() {
return config.getBoolean("last-message-reply-recipient", ess.getSettings().isLastMessageReplyRecipient());
}
public boolean isLastMessageReplyRecipient() {
return this.lastMessageReplyRecipient;
}
public void setLastMessageReplyRecipient(boolean enabled) {
this.lastMessageReplyRecipient = enabled;
config.setProperty("last-message-reply-recipient", enabled);
save();
}
public UUID getConfigUUID() {
return config.uuid;
}
@@ -123,7 +123,7 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
if (uuid != null) {
keys.add(uuid);
if (name != null && name.length() > 0) {
final String keyName = StringUtil.safeString(name);
final String keyName = ess.getSettings().isSafeUsermap() ? StringUtil.safeString(name) : name;
if (!names.containsKey(keyName)) {
names.put(keyName, uuid);
uuidMap.writeUUIDMap();
@@ -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;
}
/**
@@ -33,6 +33,9 @@ public interface IItemDb {
/**
* Create a stack from the given name with the maximum stack size for that material.
*
* Note that this will always check against resolver functions from other plugins as well.
* To avoid this behaviour, use net.ess3.api.IItemDb#get(String name, boolean useResolvers).
*
* @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
@@ -153,4 +156,11 @@ public interface IItemDb {
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();
}
@@ -110,6 +110,19 @@ public interface ITeleport {
*/
void back(Trade chargeFor) throws Exception;
/**
* Teleport wrapper used to handle /back teleports that
* are executed by a different player with this
* instance of teleport as a target.
*
* @param teleporter - The user performing the /back command.
* This value may be {@code null} to indicate console.
* @param chargeFor - What the {@code teleporter} will be charged if teleportPlayer is successful
*
* @throws Exception
*/
void back(IUser teleporter, Trade chargeFor) throws Exception;
/**
* Teleport wrapper used to handle throwing user home after a jail sentence
*
@@ -51,7 +51,7 @@ public class Commandafk extends EssentialsCommand {
private void toggleAfk(User sender, User user, String message) throws Exception {
if (message != null && sender != null) {
if (sender.isMuted()) {
throw new Exception(tl("voiceSilenced"));
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReason", sender.getMuteReason()) : tl("voiceSilenced"));
}
if (!sender.isAuthorized("essentials.afk.message")) {
throw new Exception(tl("noPermToAFKMessage"));
@@ -1,8 +1,15 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static com.earth2me.essentials.I18n.tl;
@@ -13,24 +20,82 @@ public class Commandback extends EssentialsCommand {
}
@Override
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
CommandSource sender = user.getSource();
if (args.length > 0 && user.isAuthorized("essentials.back.others")) {
this.parseCommand(server, sender, args, true);
return;
}
teleportBack(sender, user);
}
@Override
protected void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
if (args.length < 1) {
throw new NotEnoughArgumentsException();
}
this.parseCommand(server, sender, args, true);
}
private void parseCommand(Server server, CommandSource sender, String[] args, boolean allowOthers) throws Exception {
Collection<Player> players = new ArrayList<>();
if (allowOthers && args.length > 0 && args[0].trim().length() > 2) {
players = server.matchPlayer(args[0].trim());
}
if (players.size() < 1) {
throw new PlayerNotFoundException();
}
for (Player player : players) {
sender.sendMessage(tl("backOther", player.getName()));
teleportBack(sender, ess.getUser(player));
}
}
private void teleportBack(CommandSource sender, User user) throws Exception {
if (user.getLastLocation() == null) {
throw new Exception(tl("noLocationFound"));
}
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));
User requester = null;
if (sender.isPlayer()) {
requester = ess.getUser(sender.getPlayer());
if (user.getWorld() != user.getLastLocation().getWorld() && this.ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + lastWorldName)) {
throw new Exception(tl("noPerm", "essentials.worlds." + lastWorldName));
}
if (!requester.isAuthorized("essentials.back.into." + lastWorldName)) {
throw new Exception(tl("noPerm", "essentials.back.into." + lastWorldName));
}
}
if (!user.isAuthorized("essentials.back.into." + lastWorldName)) {
throw new Exception(tl("noPerm", "essentials.back.into." + lastWorldName));
if (requester == null) {
user.getTeleport().back(null, null);
} else if (!requester.equals(user)) {
Trade charge = new Trade(this.getName(), this.ess);
charge.isAffordableFor(requester);
user.getTeleport().back(requester, charge);
} else {
Trade charge = new Trade(this.getName(), this.ess);
charge.isAffordableFor(user);
user.getTeleport().back(charge);
}
final Trade charge = new Trade(this.getName(), ess);
charge.isAffordableFor(user);
user.getTeleport().back(charge);
throw new NoChargeException();
}
@Override
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
if (user.isAuthorized("essentials.back.others") && args.length == 1) {
return getPlayers(server, user);
} else {
return Collections.emptyList();
}
}
}
@@ -102,11 +102,13 @@ public class Commandbalancetop extends EssentialsCommand {
// Don't list NPCs in output
continue;
}
final BigDecimal userMoney = user.getMoney();
user.updateMoneyCache(userMoney);
totalMoney = totalMoney.add(userMoney);
final String name = user.isHidden() ? user.getName() : user.getDisplayName();
balances.put(name, userMoney);
if (!user.isAuthorized("essentials.balancetop.exclude")) {
final BigDecimal userMoney = user.getMoney();
user.updateMoneyCache(userMoney);
totalMoney = totalMoney.add(userMoney);
final String name = user.isHidden() ? user.getName() : user.getDisplayName();
balances.put(name, userMoney);
}
}
}
}
@@ -135,6 +135,10 @@ public class Commandcondense extends EssentialsCommand {
if (recipe instanceof ShapedRecipe) {
ShapedRecipe sRecipe = (ShapedRecipe) recipe;
if (sRecipe.getShape().length != sRecipe.getShape()[0].length()) {
// Only accept square recipes
return null;
}
inputList = sRecipe.getIngredientMap().values();
} else if (recipe instanceof ShapelessRecipe) {
ShapelessRecipe slRecipe = (ShapelessRecipe) recipe;
@@ -14,7 +14,7 @@ public class Commanddisposal extends EssentialsCommand {
@Override
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
user.sendMessage(tl("openingDisposal"));
user.getBase().openInventory(ess.getServer().createInventory(user.getBase(), 36, "Disposal"));
user.getBase().openInventory(ess.getServer().createInventory(user.getBase(), 36, tl("disposal")));
}
}
@@ -23,7 +23,7 @@ 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");
private final Sound NOTE_HARP = EnumUtil.valueOf(Sound.class, "BLOCK_NOTE_BLOCK_HARP", "BLOCK_NOTE_HARP", "NOTE_PIANO");
public Commandessentials() {
super("essentials");
@@ -36,6 +36,18 @@ public class Commandexp extends EssentialsCommand {
} else {
setExp(user.getSource(), user, args[1], true);
}
} else if (args.length > 1 && args[0].equalsIgnoreCase("take") && user.isAuthorized("essentials.exp.take")) {
if (args.length == 3 && user.isAuthorized("essentials.exp.take.others")) {
expMatch(server, user.getSource(), args[1], "-" + args[2], true);
} else {
setExp(user.getSource(), user, "-" + args[1], true);
}
} else if (args.length < 3 && args[0].equalsIgnoreCase("reset") && user.isAuthorized("essentials.exp.reset")) {
if (args.length == 2 && user.isAuthorized("essentials.exp.reset.others")) {
expMatch(server, user.getSource(), args[1], "0", false);
} else {
setExp(user.getSource(), user, "0", false);
}
} else if (args[0].equalsIgnoreCase("show")) {
if (args.length >= 2 && user.isAuthorized("essentials.exp.others")) {
String match = args[1].trim();
@@ -159,6 +171,12 @@ public class Commandexp extends EssentialsCommand {
if (user.isAuthorized("essentials.exp.give")) {
options.add("give");
}
if (user.isAuthorized("essentials.exp.take")) {
options.add("take");
}
if (user.isAuthorized("essentials.exp.reset")) {
options.add("reset");
}
return options;
} else if (args.length == 2) {
if ((args[0].equalsIgnoreCase("set") && user.isAuthorized("essentials.exp.set")) || (args[0].equalsIgnoreCase("give") && user.isAuthorized("essentials.exp.give"))) {
@@ -184,7 +202,7 @@ public class Commandexp extends EssentialsCommand {
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1) {
// TODO: This seems somewhat buggy, both setting and showing - right now, ignoring that
return Lists.newArrayList("set", "give", "show");
return Lists.newArrayList("set", "give", "show", "take", "reset");
} else if (args.length == 2) {
if (args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("give")) {
String levellessArg = args[1].toLowerCase(Locale.ENGLISH).replace("l", "");
@@ -34,6 +34,10 @@ public class Commandfireball extends EssentialsCommand {
type = ThrownExpBottle.class;
} else if (args[0].equalsIgnoreCase("large")) {
type = LargeFireball.class;
} else if (args[0].equalsIgnoreCase("splashpotion")) {
type = SplashPotion.class;
} else if (args[0].equalsIgnoreCase("lingeringpotion")) {
type = LingeringPotion.class;
}
}
final Vector direction = user.getBase().getEyeLocation().getDirection().multiply(speed);
@@ -45,7 +49,7 @@ public class Commandfireball extends EssentialsCommand {
@Override
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
if (args.length == 1) {
return Lists.newArrayList("small", "arrow", "skull", "egg", "snowball", "expbottle", "large");
return Lists.newArrayList("small", "arrow", "skull", "egg", "snowball", "expbottle", "large", "splashpotion", "lingeringpotion");
} else {
return Collections.emptyList();
}
@@ -44,7 +44,7 @@ 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().getInventory().getItemInMainHand();
final ItemStack stack = user.getItemInHand();
if (MaterialUtil.isFirework(stack.getType())) {
if (args.length > 0) {
if (args[0].equalsIgnoreCase("clear")) {
@@ -33,8 +33,8 @@ public class Commandhat extends EssentialsCommand {
user.sendMessage(tl("hatRemoved"));
}
} else {
if (user.getBase().getInventory().getItemInMainHand().getType() != Material.AIR) {
final ItemStack hand = user.getBase().getInventory().getItemInMainHand();
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();
@@ -95,6 +95,7 @@ public class Commandhome extends EssentialsCommand {
throw new Exception(tl("noPerm", "essentials.worlds." + loc.getWorld().getName()));
}
user.getTeleport().teleport(loc, charge, TeleportCause.COMMAND);
user.sendMessage(tl("teleportHome", home));
}
@Override
@@ -24,7 +24,7 @@ public class Commanditemdb extends EssentialsCommand {
if (args.length < 1) {
if (sender.isPlayer() && sender.getPlayer() != null) {
itemHeld = true;
itemStack = sender.getPlayer().getInventory().getItemInMainHand();
itemStack = ess.getUser(sender.getPlayer()).getItemInHand();
}
if (itemStack == null) {
throw new NotEnoughArgumentsException();
@@ -33,10 +33,16 @@ public class Commanditemdb extends EssentialsCommand {
itemStack = ess.getItemDb().get(args[0]);
}
sender.sendMessage(tl("itemType", itemStack.getType().toString()));
String itemId = "none";
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
final String itemId = itemStack.getType().getId() + ":" + itemStack.getDurability();
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));
}
@@ -0,0 +1,40 @@
package com.earth2me.essentials.commands;
import static com.earth2me.essentials.I18n.tl;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.I18n;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.FormatUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Locale;
public class Commanditemname extends EssentialsCommand {
public Commanditemname() {
super("itemname");
}
@Override
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
ItemStack item = user.getBase().getItemInHand();
if (item.getType().name().contains("AIR")) {
user.sendMessage(tl("itemnameInvalidItem", item.getType().toString().toLowerCase(Locale.ENGLISH).replace('_', ' ')));
return;
}
String name = FormatUtil.formatString(user, "essentials.itemname", getFinalArg(args, 0)).trim();
if (name.isEmpty()) name = null;
ItemMeta im = item.getItemMeta();
im.setDisplayName(name);
item.setItemMeta(im);
user.sendMessage(name == null ? tl("itemnameClear") : tl("itemnameSuccess", name));
}
}
@@ -4,7 +4,11 @@ import com.earth2me.essentials.Mob;
import com.earth2me.essentials.User;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Tameable;
import java.util.Random;
@@ -18,16 +22,7 @@ public class Commandkittycannon extends EssentialsCommand {
@Override
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
final Mob cat = Mob.OCELOT;
final Ocelot ocelot = (Ocelot) cat.spawn(user.getWorld(), server, user.getBase().getEyeLocation());
if (ocelot == null) {
return;
}
final int i = random.nextInt(Ocelot.Type.values().length);
ocelot.setCatType(Ocelot.Type.values()[i]);
ocelot.setTamed(true);
ocelot.setBaby();
ocelot.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2));
final Entity ocelot = Mob.CAT.getType() == null ? spawnOcelot(user.getWorld(), server, user) : spawnCat(user.getWorld(), server, user);
class KittyCannonExplodeTask implements Runnable {
@Override
@@ -40,4 +35,32 @@ public class Commandkittycannon extends EssentialsCommand {
ess.scheduleSyncDelayedTask(new KittyCannonExplodeTask(), 20);
}
private static Ocelot spawnOcelot(World world, Server server, User user) throws Mob.MobException {
final Ocelot ocelot = (Ocelot) Mob.OCELOT.spawn(user.getWorld(), server, user.getBase().getEyeLocation());
if (ocelot == null) {
return null;
}
final int i = random.nextInt(Ocelot.Type.values().length);
ocelot.setCatType(Ocelot.Type.values()[i]);
((Tameable) ocelot).setTamed(true);
ocelot.setBaby();
ocelot.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2));
return ocelot;
}
private static Entity spawnCat(World world, Server server, User user) throws Mob.MobException {
final Cat cat = (Cat) Mob.CAT.spawn(user.getWorld(), server, user.getBase().getEyeLocation());
if (cat == null) {
return null;
}
final int i = random.nextInt(Cat.Type.values().length);
cat.setCatType(Cat.Type.values()[i]);
cat.setTamed(true);
cat.setBaby();
cat.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2));
return cat;
}
}
@@ -48,7 +48,7 @@ public class Commandmail extends EssentialsCommand {
}
if (user.isMuted()) {
throw new Exception(tl("voiceSilenced"));
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
}
User u = getPlayer(server, args[1], true, true);
@@ -87,6 +87,11 @@ public class Commandmail extends EssentialsCommand {
return;
}
if (args.length >= 1 && "clear".equalsIgnoreCase(args[0])) {
if (user.getMails() == null || user.getMails().isEmpty()) {
user.sendMessage(tl("noMail"));
throw new NoChargeException();
}
user.setMails(null);
user.sendMessage(tl("mailCleared"));
return;
@@ -105,11 +110,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 +123,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;
}
@@ -24,7 +24,7 @@ public class Commandme extends EssentialsCommand {
@Override
public void run(Server server, User user, String commandLabel, String[] args) throws Exception {
if (user.isMuted()) {
throw new Exception(tl("voiceSilenced"));
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
}
if (args.length < 1) {
@@ -16,7 +16,7 @@ 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().getInventory().getItemInMainHand();
final ItemStack stack = user.getItemInHand();
if (stack == null) {
throw new Exception(tl("cantSpawnItem", "Air"));
}
@@ -29,7 +29,7 @@ public class Commandmsg extends EssentialsLoopCommand {
if (sender.isPlayer()) {
User user = ess.getUser(sender.getPlayer());
if (user.isMuted()) {
throw new Exception(tl("voiceSilenced"));
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
}
message = FormatUtil.formatMessage(user, "essentials.msg", message);
canWildcard = user.isAuthorized("essentials.msg.multiple");
@@ -41,7 +41,7 @@ public class Commandmute extends EssentialsCommand {
}
}
final boolean willMute = (args.length > 1) ? true : !user.getMuted();
final boolean willMute = (args.length > 1) || !user.getMuted();
final User controller = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : null;
final MuteStatusChangeEvent event = new MuteStatusChangeEvent(user, controller, willMute);
ess.getServer().getPluginManager().callEvent(event);
@@ -50,11 +50,22 @@ public class Commandmute extends EssentialsCommand {
long muteTimestamp = 0;
if (args.length > 1) {
final String time = getFinalArg(args, 1);
muteTimestamp = DateUtil.parseDateDiff(time, true);
final String time = args[1];
String muteReason;
try {
muteTimestamp = DateUtil.parseDateDiff(time, true);
muteReason = getFinalArg(args, 2);
} catch (Exception e) {
muteReason = getFinalArg(args, 1);
}
user.setMuteReason(muteReason.isEmpty() ? null : muteReason);
user.setMuted(true);
} else {
user.setMuted(!user.getMuted());
if (!user.getMuted()) {
user.setMuteReason(null);
}
}
user.setMuteTimeout(muteTimestamp);
final boolean muted = user.getMuted();
@@ -66,17 +77,35 @@ public class Commandmute extends EssentialsCommand {
if (muted) {
if (muteTimestamp > 0) {
sender.sendMessage(tl("mutedPlayerFor", user.getDisplayName(), muteTime));
user.sendMessage(tl("playerMutedFor", muteTime));
if (!user.hasMuteReason()) {
sender.sendMessage(tl("mutedPlayerFor", user.getDisplayName(), muteTime));
user.sendMessage(tl("playerMutedFor", muteTime));
} else {
sender.sendMessage(tl("mutedPlayerForReason", user.getDisplayName(), muteTime, user.getMuteReason()));
user.sendMessage(tl("playerMutedForReason", muteTime, user.getMuteReason()));
}
} else {
sender.sendMessage(tl("mutedPlayer", user.getDisplayName()));
user.sendMessage(tl("playerMuted"));
if (!user.hasMuteReason()) {
sender.sendMessage(tl("mutedPlayer", user.getDisplayName()));
user.sendMessage(tl("playerMuted"));
} else {
sender.sendMessage(tl("mutedPlayerReason", user.getDisplayName(), user.getMuteReason()));
user.sendMessage(tl("playerMutedReason", user.getMuteReason()));
}
}
final String message;
if (muteTimestamp > 0) {
message = tl("muteNotifyFor", sender.getSender().getName(), user.getName(), muteTime);
if (!user.hasMuteReason()) {
message = tl("muteNotifyFor", sender.getSender().getName(), user.getName(), muteTime);
} else {
message = tl("muteNotifyForReason", sender.getSender().getName(), user.getName(), muteTime, user.getMuteReason());
}
} else {
message = tl("muteNotify", sender.getSender().getName(), user.getName());
if (!user.hasMuteReason()) {
message = tl("muteNotify", sender.getSender().getName(), user.getName());
} else {
message = tl("muteNotifyReason", sender.getSender().getName(), user.getName(), user.getMuteReason());
}
}
server.getLogger().log(Level.INFO, message);
ess.broadcastMessage("essentials.mute.notify", message);
@@ -9,6 +9,8 @@ import org.bukkit.World;
import java.util.Collections;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import static com.earth2me.essentials.I18n.tl;
@@ -83,6 +85,8 @@ public class Commandnear extends EssentialsCommand {
final long radiusSquared = radius * radius;
boolean showHidden = user.canInteractVanished();
Queue<User> nearbyPlayers = new PriorityQueue<>((o1, o2) -> (int) (o1.getLocation().distanceSquared(loc) - o2.getLocation().distanceSquared(loc)));
for (User player : ess.getOnlineUsers()) {
if (!player.equals(user) && (!player.isHidden(user.getBase()) || showHidden || user.getBase().canSee(player.getBase()))) {
final Location playerLoc = player.getLocation();
@@ -92,13 +96,19 @@ public class Commandnear extends EssentialsCommand {
final long delta = (long) playerLoc.distanceSquared(loc);
if (delta < radiusSquared) {
if (output.length() > 0) {
output.append(", ");
}
output.append(player.getDisplayName()).append("§f(§4").append((long) Math.sqrt(delta)).append("m§f)");
nearbyPlayers.offer(player);
}
}
}
while (!nearbyPlayers.isEmpty()) {
if (output.length() > 0) {
output.append(", ");
}
User nearbyPlayer = nearbyPlayers.poll();
output.append(nearbyPlayer.getDisplayName()).append("§f(§4").append((long) nearbyPlayer.getLocation().distance(loc)).append("m§f)");
}
return output.length() > 1 ? output.toString() : tl("none");
}
@@ -28,7 +28,7 @@ public class Commandr extends EssentialsCommand {
User user = ess.getUser(sender.getPlayer());
if (user.isMuted()) {
throw new Exception(tl("voiceSilenced"));
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
}
message = FormatUtil.formatMessage(user, "essentials.msg", message);
@@ -39,7 +39,7 @@ public class Commandrepair extends EssentialsCommand {
}
public void repairHand(User user) throws Exception {
final ItemStack item = user.getBase().getInventory().getItemInMainHand();
final ItemStack item = user.getItemInHand();
if (item == null || item.getType().isBlock() || item.getDurability() == 0) {
throw new Exception(tl("repairInvalidType"));
}
@@ -0,0 +1,37 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import org.bukkit.Server;
import static com.earth2me.essentials.I18n.tl;
public class Commandrtoggle extends EssentialsToggleCommand {
public Commandrtoggle() {
super("rtoggle", "essentials.rtoggle.others");
}
@Override
public void run(Server server, User user, String commandLabel, String[] args) throws Exception {
handleToggleWithArgs(server, user, args);
}
@Override
public void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
toggleOtherPlayers(server, sender, args);
}
@Override
void togglePlayer(CommandSource sender, User user, Boolean enabled) throws NotEnoughArgumentsException {
if (enabled == null) {
enabled = !user.isLastMessageReplyRecipient();
}
user.setLastMessageReplyRecipient(enabled);
user.sendMessage(!enabled ? tl("replyLastRecipientDisabled") : tl("replyLastRecipientEnabled"));
if (!sender.isPlayer() || !user.getBase().equals(sender.getPlayer())) {
sender.sendMessage(!enabled ? tl("replyLastRecipientDisabledFor", user.getDisplayName()) : tl("replyLastRecipientEnabledFor", user.getDisplayName()));
}
}
}
@@ -117,7 +117,12 @@ public class Commandseen extends EssentialsCommand {
sender.sendMessage(tl("whoisJail", (user.getJailTimeout() > 0 ? DateUtil.formatDateDiff(user.getJailTimeout()) : tl("true"))));
}
if (user.isMuted()) {
sender.sendMessage(tl("whoisMuted", (user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : tl("true"))));
long muteTimeout = user.getMuteTimeout();
if (!user.hasMuteReason()) {
sender.sendMessage(tl("whoisMuted", (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true"))));
} else {
sender.sendMessage(tl("whoisMutedReason", (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true")), user.getMuteReason()));
}
}
final String location = user.getGeoLocation();
if (location != null && (!(sender.isPlayer()) || ess.getUser(sender.getPlayer()).isAuthorized("essentials.geoip.show"))) {
@@ -159,6 +164,15 @@ public class Commandseen extends EssentialsCommand {
}
}
if (user.isMuted()) {
long muteTimeout = user.getMuteTimeout();
if (!user.hasMuteReason()) {
sender.sendMessage(tl("whoisMuted", (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true"))));
} else {
sender.sendMessage(tl("whoisMutedReason", (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true")), user.getMuteReason()));
}
}
final String location = user.getGeoLocation();
if (location != null && (!(sender.isPlayer()) || ess.getUser(sender.getPlayer()).isAuthorized("essentials.geoip.show"))) {
sender.sendMessage(tl("whoisGeoLocation", location));
@@ -36,7 +36,7 @@ public class Commandskull extends EssentialsCommand {
owner = user.getName();
}
ItemStack itemSkull = user.getBase().getInventory().getItemInMainHand();
ItemStack itemSkull = user.getItemInHand();
SkullMeta metaSkull = null;
boolean spawn = false;
@@ -56,7 +56,7 @@ public class Commandsudo extends EssentialsLoopCommand {
@Override
public void run() {
try {
ess.getServer().dispatchCommand(user.getBase(), command);
user.getBase().chat("/" + command);
} catch (Exception e) {
sender.sendMessage(tl("errorCallingCommand", command));
}
@@ -1,7 +1,11 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.Teleport;
import com.earth2me.essentials.Trade;
import com.earth2me.essentials.User;
import net.ess3.api.events.TPARequestEvent;
import org.bukkit.Server;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.Collections;
import java.util.List;
@@ -32,11 +36,25 @@ public class Commandtpa extends EssentialsCommand {
}
// Don't let sender request teleport twice to the same player.
if (user.getConfigUUID().equals(player.getTeleportRequest()) && player.hasOutstandingTeleportRequest() // Check timeout
&& player.isTpRequestHere() == false) { // Make sure the last teleport request was actually tpa and not tpahere
&& !player.isTpRequestHere()) { // Make sure the last teleport request was actually tpa and not tpahere
throw new Exception(tl("requestSentAlready", player.getDisplayName()));
}
if (player.isAutoTeleportEnabled() && !player.isIgnoredPlayer(user)) {
final Trade charge = new Trade(this.getName(), ess);
Teleport teleport = user.getTeleport();
teleport.setTpType(Teleport.TeleportType.TPA);
teleport.teleport(player.getBase(), charge, PlayerTeleportEvent.TeleportCause.COMMAND);
player.sendMessage(tl("requestAcceptedAuto", user.getDisplayName()));
user.sendMessage(tl("requestAcceptedFromAuto", player.getDisplayName()));
return;
}
if (!player.isIgnoredPlayer(user)) {
TPARequestEvent tpaEvent = new TPARequestEvent(user.getSource(), player, false);
ess.getServer().getPluginManager().callEvent(tpaEvent);
if (tpaEvent.isCancelled()) {
throw new Exception(tl("teleportRequestCancelled", player.getDisplayName()));
}
player.requestTeleport(user, false);
player.sendMessage(tl("teleportRequest", user.getDisplayName()));
player.sendMessage(tl("typeTpaccept"));
@@ -46,7 +64,9 @@ public class Commandtpa extends EssentialsCommand {
}
}
user.sendMessage(tl("requestSent", player.getDisplayName()));
user.sendMessage(tl("typeTpacancel"));
if (user.isAuthorized("essentials.tpacancel")) {
user.sendMessage(tl("typeTpacancel"));
}
}
@Override
@@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import net.ess3.api.events.TPARequestEvent;
import org.bukkit.Server;
import java.util.Collections;
@@ -42,6 +43,12 @@ public class Commandtpaall extends EssentialsCommand {
continue;
}
try {
TPARequestEvent tpaEvent = new TPARequestEvent(sender, player, true);
ess.getServer().getPluginManager().callEvent(tpaEvent);
if (tpaEvent.isCancelled()) {
sender.sendMessage(tl("teleportRequestCancelled", player.getDisplayName()));
continue;
}
player.requestTeleport(target, true);
player.sendMessage(tl("teleportHereRequest", target.getDisplayName()));
player.sendMessage(tl("typeTpaccept"));
@@ -1,6 +1,7 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.User;
import net.ess3.api.events.TPARequestEvent;
import org.bukkit.Server;
import java.util.Collections;
@@ -32,10 +33,15 @@ public class Commandtpahere extends EssentialsCommand {
}
// Don't let sender request teleport twice to the same player.
if (user.getConfigUUID().equals(player.getTeleportRequest()) && player.hasOutstandingTeleportRequest() // Check timeout
&& player.isTpRequestHere() == true) { // Make sure the last teleport request was actually tpahere and not tpa
&& player.isTpRequestHere()) { // Make sure the last teleport request was actually tpahere and not tpa
throw new Exception(tl("requestSentAlready", player.getDisplayName()));
}
if (!player.isIgnoredPlayer(user)) {
TPARequestEvent tpaEvent = new TPARequestEvent(user.getSource(), player, true);
ess.getServer().getPluginManager().callEvent(tpaEvent);
if (tpaEvent.isCancelled()) {
throw new Exception(tl("teleportRequestCancelled", player.getDisplayName()));
}
player.requestTeleport(user, true);
player.sendMessage(tl("teleportHereRequest", user.getDisplayName()));
player.sendMessage(tl("typeTpaccept"));
@@ -0,0 +1,41 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import org.bukkit.Server;
import static com.earth2me.essentials.I18n.tl;
public class Commandtpauto extends EssentialsToggleCommand {
public Commandtpauto() {
super("tpauto", "essentials.tpauto.others");
}
@Override
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
toggleOtherPlayers(server, sender, args);
}
@Override
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
handleToggleWithArgs(server, user, args);
}
@Override
void togglePlayer(CommandSource sender, User user, Boolean enabled) {
if (enabled == null) {
enabled = !user.isAutoTeleportEnabled();
}
user.setAutoTeleportEnabled(enabled);
user.sendMessage(enabled ? tl("autoTeleportEnabled") : tl("autoTeleportDisabled"));
if (enabled && !user.isTeleportEnabled()) {
user.sendMessage(tl("teleportationDisabledWarning"));
}
if (!sender.isPlayer() || !user.getBase().equals(sender.getPlayer())) {
sender.sendMessage(enabled ? tl("autoTeleportEnabledFor", user.getDisplayName()) : tl("autoTeleportDisabledFor", user.getDisplayName()));
}
}
}
@@ -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);
@@ -63,8 +63,14 @@ public class Commandwhois extends EssentialsCommand {
sender.sendMessage(tl("whoisAFK", tl("false")));
}
sender.sendMessage(tl("whoisJail", (user.isJailed() ? user.getJailTimeout() > 0 ? DateUtil.formatDateDiff(user.getJailTimeout()) : tl("true") : tl("false"))));
sender.sendMessage(tl("whoisMuted", (user.isMuted() ? user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : tl("true") : tl("false"))));
long muteTimeout = user.getMuteTimeout();
if (!user.hasMuteReason()) {
sender.sendMessage(tl("whoisMuted", (user.isMuted() ? (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true")) : tl("false"))));
} else {
sender.sendMessage(tl("whoisMutedReason", (user.isMuted() ? (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true")) : tl("false")),
user.getMuteReason()));
}
}
@Override
@@ -104,7 +104,11 @@ public abstract class EssentialsCommand implements IEssentialsCommand {
try {
exPlayer = server.getPlayer(UUID.fromString(searchTerm));
} catch (IllegalArgumentException ex) {
exPlayer = server.getPlayer(searchTerm);
if (getOffline) {
exPlayer = server.getPlayerExact(searchTerm);
} else {
exPlayer = server.getPlayer(searchTerm);
}
}
if (exPlayer != null) {
@@ -112,7 +112,7 @@ public class FakeWorld implements World {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
//@Override
public boolean unloadChunk(int i, int i1, boolean bln, boolean bln1) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -122,7 +122,7 @@ public class FakeWorld implements World {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
//@Override
public boolean unloadChunkRequest(int i, int i1, boolean bln) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -168,7 +168,7 @@ public class FakeWorld implements World {
}
@Override
public <T extends Arrow> T spawnArrow(Location location, Vector vector, float v, float v1, Class<T> aClass) {
public <T extends AbstractArrow> T spawnArrow(Location location, Vector direction, float speed, float spread, Class<T> clazz) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -1,32 +1,114 @@
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 net.ess3.api.IEssentials;
import net.ess3.api.PluginKey;
import org.bukkit.*;
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.plugin.Plugin;
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 java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.earth2me.essentials.I18n.tl;
public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
protected final IEssentials ess;
protected boolean ready = false;
private Map<PluginKey, ItemResolver> resolverMap = new HashMap<>();
AbstractItemDb(IEssentials ess) {
this.ess = ess;
}
@Override
public void registerResolver(Plugin plugin, String name, ItemResolver resolver) throws Exception {
PluginKey key = PluginKey.fromKey(plugin, name);
if (resolverMap.containsKey(key)) {
throw new Exception("Tried to add a duplicate resolver with name " + key.toString());
}
resolverMap.put(key, resolver);
}
@Override
public void unregisterResolver(Plugin plugin, String name) throws Exception {
PluginKey key = PluginKey.fromKey(plugin, name);
if (!resolverMap.containsKey(key)) {
throw new Exception("Tried to remove nonexistent resolver with name " + key.toString());
}
resolverMap.remove(key);
}
@Override
public boolean isResolverPresent(Plugin plugin, String name) {
return resolverMap.containsKey(PluginKey.fromKey(plugin, name));
}
@Override
public Map<PluginKey, ItemResolver> getResolvers() {
return new HashMap<>(resolverMap);
}
@Override
public Map<PluginKey, ItemResolver> getResolvers(Plugin plugin) {
Map<PluginKey, ItemResolver> matchingResolvers = new HashMap<>();
for (PluginKey key : resolverMap.keySet()) {
if (key.getPlugin().equals(plugin)) {
matchingResolvers.put(key, resolverMap.get(key));
}
}
return matchingResolvers;
}
@Override
public ItemResolver getResolver(Plugin plugin, String name) {
return resolverMap.get(PluginKey.fromKey(plugin, name));
}
@Override
public ItemStack get(String id) throws Exception {
return get(id, true);
}
ItemStack tryResolvers(String id) {
for (PluginKey key : resolverMap.keySet()) {
if (ess.getSettings().isDebug()) {
ess.getLogger().info(String.format("Trying resolver '%s' for item '%s'...", key, id));
}
Function<String, ItemStack> resolver = resolverMap.get(key);
ItemStack stack = resolver.apply(id);
if (stack != null) {
return stack;
}
}
return null;
}
Collection<String> getResolverNames() {
return resolverMap.values().stream()
.map(ItemResolver::getNames)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
@Override
public List<ItemStack> getMatching(User user, String[] args) throws Exception {
List<ItemStack> is = new ArrayList<>();
@@ -62,7 +144,7 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
@Override
public String serialize(ItemStack is) {
String mat = is.getType().name();
String mat = name(is);
if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_12_2_R01) && is.getData().getData() != 0) {
mat = mat + ":" + is.getData().getData();
}
@@ -224,4 +306,9 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
return sb.toString().trim().replaceAll("§", "&");
}
@Override
public boolean isReady() {
return ready;
}
}
@@ -1,6 +1,7 @@
package com.earth2me.essentials.items;
import com.earth2me.essentials.ManagedFile;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
@@ -8,11 +9,11 @@ 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.inventory.meta.Repairable;
import org.bukkit.potion.PotionData;
import java.util.*;
@@ -24,8 +25,6 @@ import static com.earth2me.essentials.I18n.tl;
public class FlatItemDb extends AbstractItemDb {
protected static final Logger LOGGER = Logger.getLogger("Essentials");
private final transient IEssentials ess;
private static Gson gson = new Gson();
// Maps primary name to ItemData
@@ -40,7 +39,7 @@ public class FlatItemDb extends AbstractItemDb {
private transient ManagedFile file = null;
public FlatItemDb(final IEssentials ess) {
this.ess = ess;
super(ess);
}
@Override
@@ -57,19 +56,22 @@ public class FlatItemDb extends AbstractItemDb {
this.reset();
String json = file.getLines().stream()
.filter(line -> !line.startsWith("#"))
.collect(Collectors.joining());
.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) {
private void loadJSON(String source) {
JsonObject map = (new JsonParser()).parse(source).getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : map.entrySet()) {
@@ -98,7 +100,14 @@ public class FlatItemDb extends AbstractItemDb {
}
@Override
public ItemStack get(String id) throws Exception {
public ItemStack get(String id, boolean useResolvers) throws Exception {
if (useResolvers) {
ItemStack resolved = tryResolvers(id);
if (resolved != null) {
return resolved;
}
}
id = id.toLowerCase();
final String[] split = id.split(":");
@@ -108,12 +117,14 @@ public class FlatItemDb extends AbstractItemDb {
throw new Exception(tl("unknownItemName", id));
}
PotionData potionData = data.getPotionData();
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) {
@@ -130,6 +141,13 @@ public class FlatItemDb extends AbstractItemDb {
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;
}
@@ -161,14 +179,7 @@ public class FlatItemDb extends AbstractItemDb {
@Override
public String name(ItemStack item) {
Material type = item.getType();
PotionData potion = null;
if (MaterialUtil.isPotion(type) && item.getItemMeta() instanceof PotionMeta) {
potion = ((PotionMeta) item.getItemMeta()).getBasePotionData();
}
ItemData data = new ItemData(type, potion);
ItemData data = lookup(item);
for (Map.Entry<String, ItemData> entry : items.entrySet()) {
if (entry.getValue().equals(data)) {
@@ -181,24 +192,51 @@ public class FlatItemDb extends AbstractItemDb {
@Override
@Deprecated
public int getLegacyId(Material material) throws Exception {
public int getLegacyId(Material material) {
throw new UnsupportedOperationException("Legacy IDs aren't supported on this version.");
}
private 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);
Set<String> names = new HashSet<>(allAliases);
names.addAll(getResolverNames());
return names;
}
public static class ItemData {
private Material material;
private PotionData potionData;
private String[] fallbacks = null;
private PotionData potionData = null;
private EntityType entity = null;
public ItemData(Material material, PotionData potionData) {
ItemData(Material material) {
this.material = material;
}
ItemData(Material material, PotionData potionData) {
this.material = material;
this.potionData = potionData;
}
ItemData(Material material, EntityType entity) {
this.material = material;
this.entity = entity;
}
@Override
public int hashCode() {
return (31 * material.hashCode()) ^ potionData.hashCode();
@@ -213,10 +251,15 @@ public class FlatItemDb extends AbstractItemDb {
return false;
}
ItemData that = (ItemData) o;
return this.material == that.getMaterial() && potionDataEquals(that);
return this.getMaterial() == that.getMaterial() && potionDataEquals(that) && entityEquals(that);
}
public Material getMaterial() {
if (material == null && fallbacks != null) {
material = EnumUtil.getMaterial(fallbacks);
fallbacks = null; // If fallback fails, don't keep trying to look up fallbacks
}
return material;
}
@@ -224,6 +267,10 @@ public class FlatItemDb extends AbstractItemDb {
return this.potionData;
}
public EntityType getEntity() {
return this.entity;
}
private boolean potionDataEquals(ItemData o) {
if (this.potionData == null && o.getPotionData() == null) {
return true;
@@ -233,5 +280,15 @@ public class FlatItemDb extends AbstractItemDb {
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;
}
}
}
}
@@ -20,7 +20,6 @@ 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<>();
@@ -32,7 +31,7 @@ public class LegacyItemDb extends AbstractItemDb {
private final transient Pattern csvSplitPattern = Pattern.compile("(\"([^\"]*)\"|[^,]*)(,|$)");
public LegacyItemDb(final IEssentials ess) {
this.ess = ess;
super(ess);
file = new ManagedFile("items.csv", ess);
}
@@ -44,6 +43,7 @@ public class LegacyItemDb extends AbstractItemDb {
return;
}
ready = false;
durabilities.clear();
items.clear();
names.clear();
@@ -90,18 +90,13 @@ public class LegacyItemDb extends AbstractItemDb {
continue;
}
Material material = Material.matchMaterial(itemName);
if (material == null) {
LOGGER.warning(String.format("Failed to find material for %s", itemName));
continue;
}
durabilities.put(itemName, data);
items.put(itemName, numeric);
if (nbt != null) {
nbtData.put(itemName, nbt);
}
ItemData itemData = new ItemData(material, numeric, data);
ItemData itemData = new ItemData(numeric, data);
if (names.containsKey(itemData)) {
List<String> nameList = names.get(itemData);
nameList.add(itemName);
@@ -120,10 +115,19 @@ public class LegacyItemDb extends AbstractItemDb {
}
LOGGER.info(String.format("Loaded %s items from items.csv.", listNames().size()));
ready = true;
}
@Override
public ItemStack get(final String id) throws Exception {
public ItemStack get(final String id, final boolean useResolvers) throws Exception {
if (useResolvers) {
ItemStack resolved = tryResolvers(id);
if (resolved != null) {
return resolved;
}
}
int itemid = 0;
String itemname;
short metaData = 0;
@@ -152,6 +156,13 @@ public class LegacyItemDb extends AbstractItemDb {
}
}
if (itemid < 1) {
Material matFromName = EnumUtil.getMaterial(itemname.toUpperCase());
if (matFromName != null) {
itemid = matFromName.getId();
}
}
if (itemid < 1) {
throw new Exception(tl("unknownItemName", itemname));
}
@@ -161,7 +172,7 @@ public class LegacyItemDb extends AbstractItemDb {
throw new Exception(tl("unknownItemId", itemid));
}
Material mat = data.getMaterial();
Material mat = getFromLegacy(itemid, (byte) metaData);
ItemStack retval = new ItemStack(mat);
if (nbtData.containsKey(itemname)) {
String nbt = nbtData.get(itemname);
@@ -198,10 +209,10 @@ public class LegacyItemDb extends AbstractItemDb {
@Override
public List<String> nameList(ItemStack item) {
ItemData itemData = new ItemData(item.getType(), item.getDurability());
ItemData itemData = new ItemData(item.getType().getId(), item.getDurability());
List<String> nameList = names.get(itemData);
if (nameList == null) {
itemData = new ItemData(item.getType(), (short) 0);
itemData = new ItemData(item.getType().getId(), (short) 0);
nameList = names.get(itemData);
if (nameList == null) {
return null;
@@ -213,10 +224,10 @@ public class LegacyItemDb extends AbstractItemDb {
@Override
public String name(ItemStack item) {
ItemData itemData = new ItemData(item.getType(), item.getDurability());
ItemData itemData = new ItemData(item.getType().getId(), item.getDurability());
String name = primaryName.get(itemData);
if (name == null) {
itemData = new ItemData(item.getType(), (short) 0);
itemData = new ItemData(item.getType().getId(), (short) 0);
name = primaryName.get(itemData);
if (name == null) {
return null;
@@ -225,16 +236,6 @@ public class LegacyItemDb extends AbstractItemDb {
return name;
}
@Override
public Material getFromLegacy(final int id, final byte damage) {
ItemData data = this.legacyIds.get(id);
if (data == null) {
return null;
}
return data.getMaterial();
}
@Override
public int getLegacyId(Material material) throws Exception {
for(Map.Entry<String, Integer> entry : items.entrySet()) {
@@ -248,33 +249,22 @@ public class LegacyItemDb extends AbstractItemDb {
@Override
public Collection<String> listNames() {
return primaryName.values();
Collection<String> values = primaryName.values();
values.addAll(getResolverNames());
return values;
}
static class ItemData {
final private Material material;
private int legacyId;
private int itemNo;
final private short itemData;
ItemData(Material material, short itemData) {
this.material = material;
ItemData(final int itemNo, final short itemData) {
this.itemNo = itemNo;
this.itemData = itemData;
}
@Deprecated
ItemData(Material material, final int legacyId, final short itemData) {
this.material = material;
this.legacyId = legacyId;
this.itemData = itemData;
}
public Material getMaterial() {
return material;
}
@Deprecated
public int getItemNo() {
return legacyId;
return itemNo;
}
public short getItemData() {
@@ -283,7 +273,7 @@ public class LegacyItemDb extends AbstractItemDb {
@Override
public int hashCode() {
return (31 * material.hashCode()) ^ itemData;
return (31 * itemNo) ^ itemData;
}
@Override
@@ -295,7 +285,7 @@ public class LegacyItemDb extends AbstractItemDb {
return false;
}
ItemData pairo = (ItemData) o;
return this.material == pairo.getMaterial() && this.itemData == pairo.getItemData();
return this.itemNo == pairo.getItemNo() && this.itemData == pairo.getItemData();
}
}
@@ -1,14 +1,13 @@
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;
import java.lang.ref.WeakReference;
import static com.earth2me.essentials.I18n.tl;
/**
* Represents a simple reusable implementation of {@link IMessageRecipient}. This class provides functionality for the following methods:
* <ul>
@@ -120,11 +119,13 @@ public class SimpleMessageRecipient implements IMessageRecipient {
User user = getUser(this);
boolean afk = false;
boolean isLastMessageReplyRecipient = ess.getSettings().isLastMessageReplyRecipient();
if (user != null) {
if (user.isIgnoreMsg() && sender instanceof IUser && !((IUser) sender).isAuthorized("essentials.msgtoggle.bypass")) { // Don't ignore console and senders with permission
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();
isLastMessageReplyRecipient = user.isLastMessageReplyRecipient();
// Check whether this recipient ignores the sender, only if the sender is not the console.
if (sender instanceof IUser && user.isIgnoredPlayer((IUser) sender)) {
return MessageResponse.SENDER_IGNORED;
@@ -133,7 +134,7 @@ public class SimpleMessageRecipient implements IMessageRecipient {
// Display the formatted message to this recipient.
sendMessage(tl("msgFormat", sender.getDisplayName(), tl("me"), message));
if (ess.getSettings().isLastMessageReplyRecipient()) {
if (isLastMessageReplyRecipient) {
// 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;
@@ -1,13 +1,14 @@
package com.earth2me.essentials.metrics;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
@@ -186,24 +187,24 @@ public class Metrics {
*
* @return The plugin specific data.
*/
public JSONObject getPluginData() {
JSONObject data = new JSONObject();
public JsonObject getPluginData() {
JsonObject data = new JsonObject();
String pluginName = "EssentialsX";
String pluginName = plugin.getDescription().getName().replace("Essentials", "EssentialsX");
String pluginVersion = plugin.getDescription().getVersion();
data.put("pluginName", pluginName); // Append the name of the plugin
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
JSONArray customCharts = new JSONArray();
data.addProperty("pluginName", pluginName); // Append the name of the plugin
data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin
JsonArray customCharts = new JsonArray();
for (CustomChart customChart : charts) {
// Add the data of the custom charts
JSONObject chart = customChart.getRequestJsonObject();
JsonObject chart = customChart.getRequestJsonObject();
if (chart == null) { // If the chart is null, we skip it
continue;
}
customCharts.add(chart);
}
data.put("customCharts", customCharts);
data.add("customCharts", customCharts);
return data;
}
@@ -213,7 +214,7 @@ public class Metrics {
*
* @return The server specific data.
*/
private JSONObject getServerData() {
private JsonObject getServerData() {
// Minecraft specific data
int playerAmount;
try {
@@ -228,6 +229,7 @@ public class Metrics {
}
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
String bukkitVersion = Bukkit.getVersion();
String bukkitName = Bukkit.getName();
// OS/Java specific data
String javaVersion = System.getProperty("java.version");
@@ -236,19 +238,20 @@ public class Metrics {
String osVersion = System.getProperty("os.version");
int coreCount = Runtime.getRuntime().availableProcessors();
JSONObject data = new JSONObject();
JsonObject data = new JsonObject();
data.put("serverUUID", serverUUID);
data.addProperty("serverUUID", serverUUID);
data.put("playerAmount", playerAmount);
data.put("onlineMode", onlineMode);
data.put("bukkitVersion", bukkitVersion);
data.addProperty("playerAmount", playerAmount);
data.addProperty("onlineMode", onlineMode);
data.addProperty("bukkitVersion", bukkitVersion);
data.addProperty("bukkitName", bukkitName);
data.put("javaVersion", javaVersion);
data.put("osName", osName);
data.put("osArch", osArch);
data.put("osVersion", osVersion);
data.put("coreCount", coreCount);
data.addProperty("javaVersion", javaVersion);
data.addProperty("osName", osName);
data.addProperty("osArch", osArch);
data.addProperty("osVersion", osVersion);
data.addProperty("coreCount", coreCount);
return data;
}
@@ -257,9 +260,9 @@ public class Metrics {
* Collects the data and sends it afterwards.
*/
private void submitData() {
final JSONObject data = getServerData();
final JsonObject data = getServerData();
JSONArray pluginData = new JSONArray();
JsonArray pluginData = new JsonArray();
// Search for all other bStats Metrics classes to get their plugin data
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
@@ -267,26 +270,43 @@ public class Metrics {
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try {
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
if (plugin instanceof JsonObject) {
pluginData.add((JsonObject) plugin);
} else { // old bstats version compatibility
try {
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
jsonStringGetter.setAccessible(true);
String jsonString = (String) jsonStringGetter.invoke(plugin);
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
pluginData.add(object);
}
} catch (ClassNotFoundException e) {
// minecraft version 1.14+
if (logFailedRequests) {
this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e);
}
continue; // continue looping since we cannot do any other thing.
}
}
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
}
} catch (NoSuchFieldException ignored) { }
}
data.put("plugins", pluginData);
data.add("plugins", pluginData);
// Create a new thread for the connection to the bStats server
new Thread(new Runnable() {
@Override
public void run() {
try {
// Send the data
sendData(plugin, data);
} catch (Exception e) {
// Something went wrong! :(
if (logFailedRequests) {
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
}
new Thread(() -> {
try {
// Send the data
sendData(plugin, data);
} catch (Exception e) {
// Something went wrong! :(
if (logFailedRequests) {
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
}
}
}).start();
@@ -299,7 +319,7 @@ public class Metrics {
* @param data The data to send.
* @throws Exception If the request failed.
*/
private static void sendData(Plugin plugin, JSONObject data) throws Exception {
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
if (data == null) {
throw new IllegalArgumentException("Data cannot be null!");
}
@@ -382,16 +402,16 @@ public class Metrics {
this.chartId = chartId;
}
private JSONObject getRequestJsonObject() {
JSONObject chart = new JSONObject();
chart.put("chartId", chartId);
private JsonObject getRequestJsonObject() {
JsonObject chart = new JsonObject();
chart.addProperty("chartId", chartId);
try {
JSONObject data = getChartData();
JsonObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
chart.put("data", data);
chart.add("data", data);
} catch (Throwable t) {
if (logFailedRequests) {
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
@@ -401,7 +421,7 @@ public class Metrics {
return chart;
}
protected abstract JSONObject getChartData() throws Exception;
protected abstract JsonObject getChartData() throws Exception;
}
@@ -424,14 +444,14 @@ public class Metrics {
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
data.put("value", value);
data.addProperty("value", value);
return data;
}
}
@@ -455,9 +475,9 @@ public class Metrics {
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
@@ -469,13 +489,13 @@ public class Metrics {
continue; // Skip this invalid
}
allSkipped = false;
values.put(entry.getKey(), entry.getValue());
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
data.add("values", values);
return data;
}
}
@@ -499,9 +519,9 @@ public class Metrics {
}
@Override
public JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
public JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
@@ -509,22 +529,22 @@ public class Metrics {
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JSONObject value = new JSONObject();
JsonObject value = new JsonObject();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
value.put(valueEntry.getKey(), valueEntry.getValue());
value.addProperty(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
values.put(entryValues.getKey(), value);
values.add(entryValues.getKey(), value);
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
data.add("values", values);
return data;
}
}
@@ -548,14 +568,14 @@ public class Metrics {
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
data.put("value", value);
data.addProperty("value", value);
return data;
}
@@ -580,9 +600,9 @@ public class Metrics {
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
@@ -594,13 +614,13 @@ public class Metrics {
continue; // Skip this invalid
}
allSkipped = false;
values.put(entry.getKey(), entry.getValue());
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
data.add("values", values);
return data;
}
@@ -625,20 +645,20 @@ public class Metrics {
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
JSONArray categoryValues = new JSONArray();
JsonArray categoryValues = new JsonArray();
categoryValues.add(entry.getValue());
values.put(entry.getKey(), categoryValues);
values.add(entry.getKey(), categoryValues);
}
data.put("values", values);
data.add("values", values);
return data;
}
@@ -663,9 +683,9 @@ public class Metrics {
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
@@ -677,17 +697,17 @@ public class Metrics {
continue; // Skip this invalid
}
allSkipped = false;
JSONArray categoryValues = new JSONArray();
JsonArray categoryValues = new JsonArray();
for (int categoryValue : entry.getValue()) {
categoryValues.add(categoryValue);
}
values.put(entry.getKey(), categoryValues);
values.add(entry.getKey(), categoryValues);
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
data.add("values", values);
return data;
}
}
@@ -16,6 +16,9 @@ public interface IPermissionsHandler {
boolean hasPermission(Player base, String node);
// Does not check for * permissions
boolean isPermissionSet(Player base, String node);
String getPrefix(Player base);
String getSuffix(Player base);
@@ -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;
@@ -62,6 +62,11 @@ public class PermissionsHandler implements IPermissionsHandler {
return handler.hasPermission(base, node);
}
@Override
public boolean isPermissionSet(final Player base, final String node) {
return handler.isPermissionSet(base, node);
}
@Override
public String getPrefix(final Player base) {
final long start = System.nanoTime();
@@ -92,10 +97,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 +160,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;
}
}
@@ -49,6 +49,11 @@ public class SuperpermsHandler implements IPermissionsHandler {
}
}
@Override
public boolean isPermissionSet(final Player base, final String node) {
return base.isPermissionSet(node);
}
@Override
public String getPrefix(final Player base) {
return 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();
@@ -79,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;
@@ -114,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);
@@ -124,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.
*/
@@ -140,7 +140,7 @@ public class Methods {
int count = 0;
boolean match = false;
Plugin plugin = null;
Plugin plugin;
for (String name : getDependencies()) {
if (hasMethod()) {
@@ -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;
}
@@ -2,15 +2,39 @@ package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.MapValueType;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.bukkit.Location;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Data @EqualsAndHashCode(callSuper = false) public class Jails implements StorageObject {
public class Jails implements StorageObject {
@MapValueType(Location.class)
private Map<String, Location> jails = new HashMap<String, Location>();
private Map<String, Location> jails = new HashMap<>();
public Map<String, Location> getJails() {
return jails;
}
public void setJails(Map<String, Location> jails) {
this.jails = jails;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Jails jails1 = (Jails) o;
return Objects.equals(jails, jails1.jails);
}
@Override
public int hashCode() {
return Objects.hash(jails);
}
}
@@ -2,14 +2,38 @@ package com.earth2me.essentials.settings;
import com.earth2me.essentials.storage.MapValueType;
import com.earth2me.essentials.storage.StorageObject;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.bukkit.Location;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Data @EqualsAndHashCode(callSuper = false) public class Spawns implements StorageObject {
public class Spawns implements StorageObject {
@MapValueType(Location.class)
private Map<String, Location> spawns = new HashMap<>();
public Map<String, Location> getSpawns() {
return spawns;
}
public void setSpawns(Map<String, Location> spawns) {
this.spawns = spawns;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Spawns spawns1 = (Spawns) o;
return Objects.equals(spawns, spawns1.spawns);
}
@Override
public int hashCode() {
return Objects.hash(spawns);
}
}
@@ -1,7 +1,7 @@
package com.earth2me.essentials.signs;
import com.earth2me.essentials.*;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials;
import net.ess3.api.MaxMoneyException;
@@ -13,6 +13,7 @@ import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.entity.Player;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.inventory.ItemStack;
@@ -26,7 +27,6 @@ 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;
@@ -206,16 +206,15 @@ public class EssentialsSign {
protected static boolean checkIfBlockBreaksSigns(final Block block) {
final Block sign = block.getRelative(BlockFace.UP);
if (sign.getType() == SIGN_POST && isValidSign(new BlockSign(sign))) {
if (MaterialUtil.isSignPost(sign.getType()) && isValidSign(new BlockSign(sign))) {
return true;
}
final BlockFace[] directions = new BlockFace[]{BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
for (BlockFace blockFace : directions) {
final Block signblock = block.getRelative(blockFace);
if (signblock.getType() == Material.WALL_SIGN) {
final Block signBlock = block.getRelative(blockFace);
if (MaterialUtil.isWallSign(signBlock.getType())) {
try {
final org.bukkit.material.Sign signMat = (org.bukkit.material.Sign) signblock.getState().getData();
if (signMat != null && signMat.getFacing() == blockFace && isValidSign(new BlockSign(signblock))) {
if (getWallSignFacing(signBlock) == blockFace && isValidSign(new BlockSign(signBlock))) {
return true;
}
} catch (NullPointerException ex) {
@@ -297,12 +296,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, true, 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"));
@@ -402,6 +405,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);
@@ -424,7 +431,7 @@ public class EssentialsSign {
sign.setLine(index, quantity + " exp");
return new Trade(quantity, ess);
} else {
final ItemStack stack = getItemStack(item, quantity, true, ess);
final ItemStack stack = getItemStack(item, quantity, allowId, ess);
sign.setLine(index, quantity + " " + item);
return new Trade(stack, ess);
}
@@ -437,6 +444,16 @@ public class EssentialsSign {
ess.showError(sender, exception, "\\ sign: " + signName);
}
private static BlockFace getWallSignFacing(Block block) {
try {
final WallSign signData = (WallSign) block.getState().getBlockData();
return signData.getFacing();
} catch (NoClassDefFoundError e) {
final org.bukkit.material.Sign signMat = (org.bukkit.material.Sign) block.getState().getData();
return signMat.getFacing();
}
}
static class EventSign implements ISign {
private final transient SignChangeEvent event;
@@ -4,6 +4,7 @@ import com.earth2me.essentials.I18n;
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.ChatColor;
@@ -22,8 +23,6 @@ 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 = EnumUtil.getMaterial("SIGN", "SIGN_POST");
private final transient IEssentials ess;
public SignBlockListener(IEssentials ess) {
@@ -55,7 +54,7 @@ public class SignBlockListener implements Listener {
}
final Material mat = block.getType();
if (mat == SIGN_POST || mat == WALL_SIGN) {
if (MaterialUtil.isSign(mat)) {
final Sign csign = (Sign) block.getState();
for (EssentialsSign sign : ess.getSettings().enabledSigns()) {
@@ -143,12 +142,12 @@ public class SignBlockListener implements Listener {
}
final Block against = event.getBlockAgainst();
if ((against.getType() == WALL_SIGN || against.getType() == SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(against))) {
if (MaterialUtil.isSign(against.getType()) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(against))) {
event.setCancelled(true);
return;
}
final Block block = event.getBlock();
if (block.getType() == WALL_SIGN || block.getType() == SIGN_POST) {
if (MaterialUtil.isSign(block.getType())) {
return;
}
for (EssentialsSign sign : ess.getSettings().enabledSigns()) {
@@ -167,7 +166,7 @@ public class SignBlockListener implements Listener {
}
final Block block = event.getBlock();
if (((block.getType() == WALL_SIGN || block.getType() == SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
if ((MaterialUtil.isSign(block.getType()) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
event.setCancelled(true);
return;
}
@@ -187,7 +186,7 @@ public class SignBlockListener implements Listener {
}
final Block block = event.getBlock();
if (((block.getType() == WALL_SIGN || block.getType() == SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
if ((MaterialUtil.isSign(block.getType()) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
event.setCancelled(true);
return;
}
@@ -207,7 +206,7 @@ public class SignBlockListener implements Listener {
}
for (Block block : event.getBlocks()) {
if (((block.getType() == WALL_SIGN || block.getType() == SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
if ((MaterialUtil.isSign(block.getType()) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
event.setCancelled(true);
return;
}
@@ -232,7 +231,7 @@ public class SignBlockListener implements Listener {
final Block[] affectedBlocks = new Block[]{pistonBaseBlock, pistonBaseBlock.getRelative(event.getDirection()), event.getRetractLocation().getBlock()};
for (Block block : affectedBlocks) {
if (((block.getType() == WALL_SIGN || block.getType() == SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
if ((MaterialUtil.isSign(block.getType()) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
event.setCancelled(true);
return;
}
@@ -3,6 +3,8 @@ package com.earth2me.essentials.signs;
import com.earth2me.essentials.User;
import net.ess3.api.IEssentials;
import static com.earth2me.essentials.I18n.tl;
public class SignDisposal extends EssentialsSign {
public SignDisposal() {
@@ -11,7 +13,7 @@ public class SignDisposal extends EssentialsSign {
@Override
protected boolean onSignInteract(final ISign sign, final User player, final String username, final IEssentials ess) {
player.getBase().openInventory(ess.getServer().createInventory(player.getBase(), 36, "Disposal"));
player.getBase().openInventory(ess.getServer().createInventory(player.getBase(), 36, tl("disposal")));
return true;
}
}
@@ -1,6 +1,7 @@
package com.earth2me.essentials.signs;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import net.ess3.api.IEssentials;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -13,7 +14,6 @@ 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) {
@@ -28,7 +28,7 @@ public class SignEntityListener implements Listener {
}
for (Block block : event.blockList()) {
if (((block.getType() == Material.WALL_SIGN || block.getType() == SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
if ((MaterialUtil.isSign(block.getType()) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
event.setCancelled(true);
return;
}
@@ -49,7 +49,7 @@ public class SignEntityListener implements Listener {
}
final Block block = event.getBlock();
if (((block.getType() == Material.WALL_SIGN || block.getType() == SIGN_POST) && EssentialsSign.isValidSign(ess, new EssentialsSign.BlockSign(block))) || EssentialsSign.checkIfBlockBreaksSigns(block)) {
if ((MaterialUtil.isSign(block.getType()) && 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));
}
@@ -75,7 +75,7 @@ public class SignProtection extends EssentialsSign {
final Block sign = entry.getKey().getBlock();
if (!hasAdjacentBlock(sign, block)) {
block.setType(Material.AIR);
final Trade trade = new Trade(new ItemStack(Material.SIGN, 1), ess);
final Trade trade = new Trade(new ItemStack(sign.getType(), 1), ess);
trade.pay(player, OverflowType.DROP);
}
}
@@ -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, true, ess);
final ItemStack item = getItemStack(split[1], stackamount, allowId, ess);
int amount = getInteger(split[2]);
if (amountType == AmountType.ROUNDED) {
amount -= amount % stackamount;
@@ -40,16 +40,24 @@ public class SignWarp extends EssentialsSign {
protected boolean onSignInteract(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException, ChargeException {
final String warpName = sign.getLine(1);
final String group = sign.getLine(2);
if ((!group.isEmpty() && ("§2Everyone".equals(group) || player.inGroup(group))) || (group.isEmpty() && (!ess.getSettings().getPerWarpPermission() || player.isAuthorized("essentials.warps." + warpName)))) {
final Trade charge = getTrade(sign, 3, ess);
try {
player.getTeleport().warp(player, warpName, charge, TeleportCause.PLUGIN);
Trade.log("Sign", "Warp", "Interact", username, null, username, charge, sign.getBlock().getLocation(), ess);
} catch (Exception ex) {
throw new SignException(ex.getMessage(), ex);
if (!group.isEmpty()) {
if (!"§2Everyone".equals(group) && !player.inGroup(group)) {
throw new SignException(tl("warpUsePermission"));
}
} else {
if (ess.getSettings().getPerWarpPermission() && !player.isAuthorized("essentials.warps." + warpName)) {
throw new SignException(tl("warpUsePermission"));
}
return true;
}
return false;
final Trade charge = getTrade(sign, 3, ess);
try {
player.getTeleport().warp(player, warpName, charge, TeleportCause.PLUGIN);
Trade.log("Sign", "Warp", "Interact", username, null, username, charge, sign.getBlock().getLocation(), ess);
} catch (Exception ex) {
throw new SignException(ex.getMessage(), ex);
}
return true;
}
}
@@ -2,6 +2,7 @@ package com.earth2me.essentials.utils;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.entity.EntityType;
import java.lang.reflect.Field;
import java.util.HashSet;
@@ -12,7 +13,7 @@ public class EnumUtil {
/**
* Returns the field matching the first provided enum name that exists within the given
* enum class.
* 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
@@ -78,4 +79,7 @@ public class EnumUtil {
return valueOf(Statistic.class, names);
}
public static EntityType getEntityType(String... names) {
return valueOf(EntityType.class, names);
}
}
@@ -3,23 +3,25 @@ package com.earth2me.essentials.utils;
import net.ess3.api.IUser;
import org.bukkit.ChatColor;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FormatUtil {
private static final Set<ChatColor> COLORS = EnumSet.of(ChatColor.BLACK, ChatColor.DARK_BLUE, ChatColor.DARK_GREEN, ChatColor.DARK_AQUA, ChatColor.DARK_RED, ChatColor.DARK_PURPLE, ChatColor.GOLD, ChatColor.GRAY, ChatColor.DARK_GRAY, ChatColor.BLUE, ChatColor.GREEN, ChatColor.AQUA, ChatColor.RED, ChatColor.LIGHT_PURPLE, ChatColor.YELLOW, ChatColor.WHITE);
private static final Set<ChatColor> FORMATS = EnumSet.of(ChatColor.BOLD, ChatColor.STRIKETHROUGH, ChatColor.UNDERLINE, ChatColor.ITALIC, ChatColor.RESET);
private static final Set<ChatColor> MAGIC = EnumSet.of(ChatColor.MAGIC);
//Vanilla patterns used to strip existing formats
static final transient Pattern VANILLA_COLOR_PATTERN = Pattern.compile("\u00a7+[0-9A-Fa-f]");
static final transient Pattern VANILLA_MAGIC_PATTERN = Pattern.compile("\u00a7+[Kk]");
static final transient Pattern VANILLA_FORMAT_PATTERN = Pattern.compile("\u00a7+[L-ORl-or]");
private static final Pattern STRIP_ALL_PATTERN = Pattern.compile("\u00a7+([0-9a-fk-orA-FK-OR])");
//Essentials '&' convention colour codes
static final transient Pattern REPLACE_ALL_PATTERN = Pattern.compile("(?<!&)&([0-9a-fk-orA-FK-OR])");
static final transient Pattern REPLACE_COLOR_PATTERN = Pattern.compile("(?<!&)&([0-9a-fA-F])");
static final transient Pattern REPLACE_MAGIC_PATTERN = Pattern.compile("(?<!&)&([Kk])");
static final transient Pattern REPLACE_FORMAT_PATTERN = Pattern.compile("(?<!&)&([l-orL-OR])");
static final transient Pattern REPLACE_PATTERN = Pattern.compile("&&(?=[0-9a-fk-orA-FK-OR])");
private static final Pattern REPLACE_ALL_PATTERN = Pattern.compile("(&)?&([0-9a-fk-orA-FK-OR])");
//Used to prepare xmpp output
static final transient Pattern LOGCOLOR_PATTERN = Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]");
static final transient Pattern URL_PATTERN = Pattern.compile("((?:(?:https?)://)?[\\w-_\\.]{2,})\\.([a-zA-Z]{2,3}(?:/\\S+)?)");
private static final Pattern LOGCOLOR_PATTERN = Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]");
private static final Pattern URL_PATTERN = Pattern.compile("((?:(?:https?)://)?[\\w-_\\.]{2,})\\.([a-zA-Z]{2,3}(?:/\\S+)?)");
public static final Pattern IPPATTERN = Pattern.compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
//This method is used to simply strip the native minecraft colour codes
@@ -55,33 +57,88 @@ public class FormatUtil {
if (input == null) {
return null;
}
return replaceColor(input, REPLACE_ALL_PATTERN);
return replaceColor(input, EnumSet.allOf(ChatColor.class));
}
static String replaceColor(final String input, final Pattern pattern) {
return REPLACE_PATTERN.matcher(pattern.matcher(input).replaceAll("\u00a7$1")).replaceAll("&");
static String replaceColor(final String input, final Set<ChatColor> supported) {
StringBuffer builder = new StringBuffer();
Matcher matcher = REPLACE_ALL_PATTERN.matcher(input);
searchLoop: while (matcher.find()) {
boolean isEscaped = (matcher.group(1) != null);
if (!isEscaped) {
char code = matcher.group(2).toLowerCase(Locale.ROOT).charAt(0);
for (ChatColor color : supported) {
if (color.getChar() == code) {
matcher.appendReplacement(builder, "\u00a7$2");
continue searchLoop;
}
}
}
// Don't change & to section sign (or replace two &'s with one)
matcher.appendReplacement(builder, "&$2");
}
matcher.appendTail(builder);
return builder.toString();
}
static String stripColor(final String input, final Set<ChatColor> strip) {
StringBuffer builder = new StringBuffer();
Matcher matcher = STRIP_ALL_PATTERN.matcher(input);
searchLoop: while (matcher.find()) {
char code = matcher.group(1).toLowerCase(Locale.ROOT).charAt(0);
for (ChatColor color : strip) {
if (color.getChar() == code) {
matcher.appendReplacement(builder, "");
continue searchLoop;
}
}
// Don't replace
matcher.appendReplacement(builder, "$0");
}
matcher.appendTail(builder);
return builder.toString();
}
//This is the general permission sensitive message format function, does not touch urls.
public static String formatString(final IUser user, final String permBase, final String input) {
if (input == null) {
public static String formatString(final IUser user, final String permBase, String message) {
if (message == null) {
return null;
}
String message;
EnumSet<ChatColor> supported = EnumSet.noneOf(ChatColor.class);
if (user.isAuthorized(permBase + ".color")) {
message = replaceColor(input, REPLACE_COLOR_PATTERN);
} else {
message = stripColor(input, VANILLA_COLOR_PATTERN);
}
if (user.isAuthorized(permBase + ".magic")) {
message = replaceColor(message, REPLACE_MAGIC_PATTERN);
} else {
message = stripColor(message, VANILLA_MAGIC_PATTERN);
supported.addAll(COLORS);
}
if (user.isAuthorized(permBase + ".format")) {
message = replaceColor(message, REPLACE_FORMAT_PATTERN);
} else {
message = stripColor(message, VANILLA_FORMAT_PATTERN);
supported.addAll(FORMATS);
}
if (user.isAuthorized(permBase + ".magic")) {
supported.addAll(MAGIC);
}
for (ChatColor chatColor : ChatColor.values()) {
String colorName = chatColor.name();
if (chatColor == ChatColor.MAGIC) {
// Bukkit's name doesn't match with vanilla's
colorName = "obfuscated";
}
final String node = permBase + "." + colorName.toLowerCase(Locale.ROOT);
// Only handle individual colors that are explicitly added or removed.
if (!user.isPermissionSet(node)) {
continue;
}
if (user.isAuthorized(node)) {
supported.add(chatColor);
} else {
supported.remove(chatColor);
}
}
EnumSet<ChatColor> strip = EnumSet.complementOf(supported);
if (!supported.isEmpty()) {
message = replaceColor(message, supported);
}
if (!strip.isEmpty()) {
message = stripColor(message, strip);
}
return message;
}
@@ -16,8 +16,12 @@ import static com.earth2me.essentials.I18n.tl;
public class LocationUtil {
// Water types used for TRANSPARENT_MATERIALS and is-water-safe config option
private static final Set<Material> WATER_TYPES =
EnumUtil.getAllMatching(Material.class, "WATER", "FLOWING_WATER");
// 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 {
@@ -29,10 +33,14 @@ public class LocationUtil {
}
TRANSPARENT_MATERIALS.addAll(HOLLOW_MATERIALS);
TRANSPARENT_MATERIALS.add(Material.WATER);
try {
TRANSPARENT_MATERIALS.add(Material.valueOf("FLOWING_WATER"));
} catch (Exception ignored) { // 1.13 WATER uses Levelled
TRANSPARENT_MATERIALS.addAll(WATER_TYPES);
}
public static void setIsWaterSafe(boolean isWaterSafe) {
if (isWaterSafe) {
HOLLOW_MATERIALS.addAll(WATER_TYPES);
} else {
HOLLOW_MATERIALS.removeAll(WATER_TYPES);
}
}
@@ -49,7 +57,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;
@@ -57,7 +65,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++) {
@@ -65,30 +73,22 @@ 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 = null;
try {
block = entity.getTargetBlock(TRANSPARENT_MATERIALS, 300);
} catch (NoSuchMethodError e) {
// failing now :(
}
} 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) {
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());
}
@@ -124,8 +124,7 @@ public class LocationUtil {
if (below.getType() == Material.valueOf("FLOWING_LAVA")) {
return true;
}
} catch (Exception ignored) { // 1.13 LAVA uses Levelled
}
} catch (Exception ignored) {} // 1.13 LAVA uses Levelled
Material PORTAL = EnumUtil.getMaterial("NETHER_PORTAL", "PORTAL");
@@ -159,7 +158,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 {
@@ -3,8 +3,12 @@ package com.earth2me.essentials.utils;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;
@@ -21,7 +25,8 @@ public class MaterialUtil {
// 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;
private static final Set<Material> SIGN_POSTS;
private static final Set<Material> WALL_SIGNS;
public static final Material SPAWNER = EnumUtil.getMaterial("MOB_SPAWNER", "SPAWNER");
@@ -55,7 +60,14 @@ public class MaterialUtil {
POTIONS = EnumUtil.getAllMatching(Material.class, "POTION", "SPLASH_POTION",
"LINGERING_POTION", "TIPPED_ARROW");
SIGNS = EnumUtil.getAllMatching(Material.class, "SIGN", "SIGN_POST", "WALL_SIGN");
SIGN_POSTS = EnumUtil.getAllMatching(Material.class, "SIGN", "SIGN_POST",
"ACACIA_SIGN", "BIRCH_SIGN",
"DARK_OAK_SIGN", "JUNGLE_SIGN",
"OAK_SIGN", "SPRUCE_SIGN");
WALL_SIGNS = EnumUtil.getAllMatching(Material.class, "WALL_SIGN",
"ACACIA_WALL_SIGN", "BIRCH_WALL_SIGN", "DARK_OAK_WALL_SIGN", "JUNGLE_WALL_SIGN",
"OAK_WALL_SIGN", "SPRUCE_WALL_SIGN");
}
public static boolean isBed(Material material) {
@@ -94,8 +106,16 @@ public class MaterialUtil {
return POTIONS.contains(material);
}
public static boolean isSignPost(Material material) {
return SIGN_POSTS.contains(material);
}
public static boolean isWallSign(Material material) {
return WALL_SIGNS.contains(material);
}
public static boolean isSign(Material material) {
return SIGNS.contains(material);
return isSignPost(material) || isWallSign(material);
}
public static boolean isSkull(Material material) {
@@ -103,11 +123,22 @@ public class MaterialUtil {
}
public static Material convertFromLegacy(int id, byte damage) {
return EnumSet.allOf(Material.class).stream()
.filter(material -> material.getId() == id)
.findFirst()
.map(material -> Bukkit.getUnsafe().fromLegacy(new MaterialData(material, damage)))
.orElse(null);
for (Material material : EnumSet.allOf(Material.class)) {
if (material.getId() == id) {
try {
return Bukkit.getUnsafe().fromLegacy(new MaterialData(material, damage));
} catch (NoSuchMethodError error) {
break;
}
}
}
try {
Method getMaterialFromId = Material.class.getDeclaredMethod("getMaterial", int.class);
return (Material) getMaterialFromId.invoke(null, id);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {}
return null;
}
public static DyeColor getColorOf(Material material) {
@@ -12,6 +12,7 @@ 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");
@@ -19,11 +20,20 @@ public class VersionUtil {
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");
public static final BukkitVersion v1_14_R01 = BukkitVersion.fromString("1.14-R0.1-SNAPSHOT");
public static final BukkitVersion v1_14_1_R01 = BukkitVersion.fromString("1.14.1-R0.1-SNAPSHOT");
public static final BukkitVersion v1_14_2_R01 = BukkitVersion.fromString("1.14.2-R0.1-SNAPSHOT");
public static final BukkitVersion v1_14_3_R01 = BukkitVersion.fromString("1.14.3-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 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, v1_14_3_R01);
private static BukkitVersion serverVersion = null;
public static BukkitVersion getServerBukkitVersion() {
return BukkitVersion.fromString(Bukkit.getServer().getBukkitVersion());
if (serverVersion == null) {
serverVersion = BukkitVersion.fromString(Bukkit.getServer().getBukkitVersion());
}
return serverVersion;
}
public static boolean isServerSupported() {
@@ -31,10 +41,11 @@ public class VersionUtil {
}
public static class BukkitVersion implements Comparable<BukkitVersion> {
private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.?([0-9]*)-R([\\d.]+)(?:-SNAPSHOT)?");
private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.?([0-9]*)?(?:-pre(\\d))?(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?");
private final int major;
private final int minor;
private final int prerelease;
private final int patch;
private final double revision;
@@ -45,17 +56,30 @@ public class VersionUtil {
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());
matcher = VERSION_PATTERN.matcher(v1_14_R01.toString());
Preconditions.checkArgument(matcher.matches(), string + " is not in valid version format. e.g. 1.8.8-R0.1");
}
return new BukkitVersion(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3)), Double.parseDouble(matcher.group(4)));
return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.groupCount() < 5 ? "" : matcher.group(5), matcher.group(4));
}
private BukkitVersion(int major, int minor, int patch, double revision) {
private static BukkitVersion from(String major, String minor, String patch, String revision, String prerelease) {
if (patch == null || patch.isEmpty()) patch = "0";
if (revision == null || revision.isEmpty()) revision = "0";
if (prerelease == null || prerelease.isEmpty()) prerelease = "-1";
return new BukkitVersion(Integer.parseInt(major),
Integer.parseInt(minor),
Integer.parseInt(patch),
Double.parseDouble(revision),
Integer.parseInt(prerelease));
}
private BukkitVersion(int major, int minor, int patch, double revision, int prerelease) {
this.major = major;
this.minor = minor;
this.patch = patch;
this.revision = revision;
this.prerelease = prerelease;
}
public boolean isHigherThan(BukkitVersion o) {
@@ -90,6 +114,10 @@ public class VersionUtil {
return revision;
}
public int getPrerelease() {
return prerelease;
}
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -100,19 +128,27 @@ public class VersionUtil {
}
BukkitVersion that = (BukkitVersion) o;
return major == that.major &&
minor == that.minor &&
patch == that.patch &&
revision == that.revision;
minor == that.minor &&
patch == that.patch &&
revision == that.revision &&
prerelease == that.prerelease;
}
@Override
public int hashCode() {
return Objects.hashCode(major, minor, patch, revision);
return Objects.hashCode(major, minor, patch, revision, prerelease);
}
@Override
public String toString() {
return major + "." + minor + "." + patch + "-R" + revision;
StringBuilder sb = new StringBuilder(major + "." + minor);
if (patch != 0) {
sb.append(".").append(patch);
}
if (prerelease != -1) {
sb.append("-pre").append(prerelease);
}
return sb.append("-R").append(revision).toString();
}
@Override
@@ -132,7 +168,13 @@ public class VersionUtil {
} else if (patch > o.patch) {
return 1;
} else { // equal patch
return Double.compare(revision, o.revision);
if (prerelease < o.prerelease) {
return -1;
} else if (prerelease > o.prerelease) {
return 1;
} else { // equal prerelease
return Double.compare(revision, o.revision);
}
}
}
}
+27 -8
View File
@@ -281,6 +281,12 @@ player-commands:
- worth
- xmpp
# Use this option to force superperms-based permissions handler regardless of detected installed perms plugin.
# This is useful if you want superperms-based permissions (with wildcards) for custom permissions plugins.
# If you wish to use EssentialsX's built-in permissions using the `player-commands` section above, set this to false.
# Default is true.
use-bukkit-permissions: true
# When this option is enabled, one-time use kits (ie. delay < 0) will be
# removed from the /kit list when a player can no longer use it
skip-used-one-time-kits-from-kit-list: false
@@ -405,6 +411,11 @@ cancel-afk-on-interact: true
# Disable this to reduce server lag.
cancel-afk-on-move: true
# Should AFK players be ignored when other players are trying to sleep?
# When this setting is false, players won't be able to skip the night if some players are AFK.
# Users with the permission node essentials.sleepingignored will always be ignored.
sleep-ignores-afk-players: true
# Set the player's list name when they are AFK. This is none by default which specifies that Essentials
# should not interfere with the AFK player's list name.
# You may use color codes, use {USERNAME} the player's name or {PLAYER} for the player's displayname.
@@ -475,11 +486,13 @@ mails-per-minute: 1000
# Set to -1 to disable, and essentials.tempban.unlimited can be used to override.
max-tempban-time: -1
# Changes /reply functionality. If true, /r goes to the person you messaged last, otherwise the first person that messaged you.
# Changes the default /reply functionality. This can be changed on a per-player basis using /rtoggle.
# If true, /r goes to the person you messaged last, otherwise the first person that messaged you.
# If false, /r goes to the last person that messaged you.
last-message-reply-recipient: true
# If last-message-reply-recipient is true, this specifies the duration, in seconds, that would need to elapse for the
# If last-message-reply-recipient is enabled for a particular player,
# this specifies the duration, in seconds, that would need to elapse for the
# reply-recipient to update when receiving a message.
# Default is 180 (3 minutes)
last-message-reply-recipient-timeout: 180
@@ -531,6 +544,9 @@ default-enabled-confirm-commands:
#- pay
#- clearinventory
# Whether or not to teleport a player back to their previous position after they have been freed from jail.
teleport-back-when-freed-from-jail: true
# Set the timeout, in seconds for players to accept a tpa before the request is cancelled.
# Set to 0 for no timeout.
tpa-accept-cancellation: 120
@@ -543,6 +559,15 @@ allow-direct-hat: true
# This doesn't affect running the command from the console, where a world is always required.
allow-world-in-broadcastworld: true
# Consider water blocks as "safe," therefore allowing players to teleport
# using commands such as /home or /spawn to a location that is occupied
# by water blocks
is-water-safe: false
# Should the usermap try to sanitise usernames before saving them?
# You should only change this to false if you use Minecraft China.
safe-usermap-names: true
############################################################
# +------------------------------------------------------+ #
# | EssentialsHome | #
@@ -617,12 +642,6 @@ min-money: -10000
# Enable this to log all interactions with trade/buy/sell signs and sell command.
economy-log-enabled: false
# Use this option to force superperms-based permissions handler regardless of detected installed perms plugin.
# This is useful if you want superperms-based permissions (with wildcards) for custom permissions plugins.
# If you wish to use EssentialsX' built-in permissions using the `player-commands` section above, set this to false.
# Default is true.
use-bukkit-permissions: true
# Minimum acceptable amount to be used in /pay.
minimum-pay-amount: 0.001
-3
View File
@@ -1901,9 +1901,6 @@ plantren,91,0
glowpumpkin,91,0
gpumpkin,91,0
lpumpkin,91,0
lockedchest,95,0
lockchest,95,0
jokechest,95,0
whiteglass,95,0
whitesglass,95,0
whitestainedglass,95,0
1 #version: ${full.version}
1901 glowpumpkin,91,0
1902 gpumpkin,91,0
1903 lpumpkin,91,0
lockedchest,95,0
lockchest,95,0
jokechest,95,0
1904 whiteglass,95,0
1905 whitesglass,95,0
1906 whitestainedglass,95,0
+24797 -20757
View File
File diff suppressed because it is too large. Load diff
+56 -50
View File
@@ -1,7 +1,6 @@
#X-Generator: crowdin.net
#version: ${full.version}
# Single quotes have to be doubled: ''
# Translations start here
# by:
action=\u00a75* {0} \u00a75{1}
addedToAccount=\u00a7a{0} has been added to your account.
@@ -19,7 +18,8 @@ antiBuildInteract=\u00a74You are not permitted to interact with\u00a7c {0}\u00a7
antiBuildPlace=\u00a74You are not permitted to place\u00a7c {0} \u00a74here.
antiBuildUse=\u00a74You are not permitted to use\u00a7c {0}\u00a74.
autoAfkKickReason=You have been kicked for idling more than {0} minutes.
backAfterDeath=\u00a76Use the /back command to return to your death point.
backAfterDeath=\u00a76Use the\u00a7c /back\u00a76 command to return to your death point.
backOther=\u00a76Returned\u00a7c {0}\u00a76 to previous location.
backupDisabled=\u00a74An external backup script has not been configured.
backupFinished=\u00a76Backup finished.
backupStarted=\u00a76Backup started.
@@ -42,9 +42,7 @@ blockList=\u00a76Essentials relayed the following commands to another plugin\:
bookAuthorSet=\u00a76Author of the book set to {0}.
bookLocked=\u00a76This book is now locked.
bookTitleSet=\u00a76Title of the book set to {0}.
broadcast=\u00a7r\u00a76[\u00a74Broadcast\u00a76]\u00a7a {0}
buildAlert=\u00a74You are not permitted to build.
bukkitFormatChanged=Bukkit version format changed. Version not checked.
broadcast=\u00a76[\u00a74Broadcast\u00a76]\u00a7a {0}
burnMsg=\u00a76You set\u00a7c {0} \u00a76on fire for\u00a7c {1} seconds\u00a76.
cannotStackMob=\u00a74You do not have permission to stack multiple mobs.
canTalkAgain=\u00a76You can now talk again.
@@ -52,7 +50,6 @@ cantFindGeoIpDB=Can''t find GeoIP database\!
cantGamemode=\u00a74You do not have permission to change to gamemode {0}
cantReadGeoIpDB=Failed to read GeoIP database\!
cantSpawnItem=\u00a74You are not allowed to spawn the item\u00a7c {0}\u00a74.
chatTypeAdmin=[A]
chatTypeLocal=[L]
chatTypeSpy=[Spy]
cleaned=Userfiles Cleaned.
@@ -63,7 +60,7 @@ commandCooldown=\u00a7cYou cannot type that command for {0}.
commandFailed=Command {0} failed\:
commandHelpFailedForPlugin=Error getting help for plugin\: {0}
commandNotLoaded=\u00a74Command {0} is improperly loaded.
compassBearing=\u00a76Bearing\: {0} ({1} degrees).
compassBearing=\u00a76Bearing\: {0} ({1} degrees).
configFileMoveError=Failed to move config.yml to backup location.
configFileRenameError=Failed to rename temp file to config.yml.
confirmClear=\u00a77To \u00a7lCONFIRM\u00a77 inventory clear, please repeat command: \u00a76{0}
@@ -72,7 +69,6 @@ connectedPlayers=\u00a76Connected players\u00a7r
connectionFailed=Failed to open connection.
cooldownWithMessage=\u00a74Cooldown\: {0}
coordsKeyword={0}, {1}, {2}
corruptNodeInConfig=\u00a74Notice\: Your configuration file has a corrupt {0} node.
couldNotFindTemplate=\u00a74Could not find template {0}
createdKit=\u00a76Created kit \u00a7c{0} \u00a76with \u00a7c{1} \u00a76entries and delay \u00a7c{2}
createKitFailed=\u00a74Error occurred whilst creating kit {0}.
@@ -100,7 +96,8 @@ depthBelowSea=\u00a76You are\u00a7c {0} \u00a76block(s) below sea level.
destinationNotSet=Destination not set\!
disabled=disabled
disabledToSpawnMob=\u00a74Spawning this mob was disabled in the config file.
disableUnlimited=\u00a76Disabled unlimited placing of\u00a7c {0} \u00a76for {1}.
disableUnlimited=\u00a76Disabled unlimited placing of\u00a7c {0} \u00a76for\u00a7c {1}\u00a76.
disposal=Disposal
distance=\u00a76Distance\: {0}
dontMoveMessage=\u00a76Teleportation will commence in\u00a7c {0}\u00a76. Don''t move.
downloadingGeoIp=Downloading GeoIP database... this might take a while (country\: 1.7 MB, city\: 30MB)
@@ -145,11 +142,12 @@ gcmax=\u00a76Maximum memory\:\u00a7c {0} MB.
gctotal=\u00a76Allocated memory\:\u00a7c {0} MB.
gcWorld=\u00a76{0} "\u00a7c{1}\u00a76"\: \u00a7c{2}\u00a76 chunks, \u00a7c{3}\u00a76 entities, \u00a7c{4}\u00a76 tiles.
geoipJoinFormat=\u00a76Player \u00a7c{0} \u00a76comes from \u00a7c{1}\u00a76.
geoipCantFind=\u00a76Player \u00a7c{0} \u00a76comes from \u00a7aan unknown country\u00a76.
geoIpUrlEmpty=GeoIP download url is empty.
geoIpUrlInvalid=GeoIP download url is invalid.
givenSkull=\u00a76You have been given the skull of \u00a7c{0}\u00a76.
giveSpawn=\u00a76Giving\u00a7c {0} \u00a76of\u00a7c {1} to\u00a7c {2}\u00a76.
giveSpawnFailure=\u00a74Not enough space, \u00a7c{0} \u00a7c{1} \u00a74was lost.
giveSpawn=\u00a76Giving\u00a7c {0} \u00a76of\u00a7c {1} \u00a76to\u00a7c {2}\u00a76.
giveSpawnFailure=\u00a74Not enough space, \u00a7c{0} {1} \u00a74was lost.
godDisabledFor=\u00a7cdisabled\u00a76 for\u00a7c {0}
godEnabledFor=\u00a7aenabled\u00a76 for\u00a7c {0}
godMode=\u00a76God mode\u00a7c {0}\u00a76.
@@ -164,7 +162,7 @@ haveBeenReleased=\u00a76You have been released.
heal=\u00a76You have been healed.
healDead=\u00a74You cannot heal someone who is dead\!
healOther=\u00a76Healed\u00a7c {0}\u00a76.
helpConsole=To view help from the console, type ?.
helpConsole=To view help from the console, type ''?''.
helpFrom=\u00a76Commands from {0}\:
helpLine=\u00a76/{0}\u00a7r\: {1}
helpMatching=\u00a76Commands matching "\u00a7c{0}\u00a76"\:
@@ -201,12 +199,11 @@ invalidSignLine=\u00a74Line\u00a7c {0} \u00a74on sign is invalid.
invalidSkull=\u00a74Please hold a player skull.
invalidWarpName=\u00a74Invalid warp name\!
invalidWorld=\u00a74Invalid world.
inventoryClearFail=\u00a74Player {0} \u00a74does not have\u00a7c {1} \u00a74of\u00a7c {2}\u00a74.
inventoryClearFail=\u00a74Player\u00a7c {0} \u00a74does not have\u00a7c {1} \u00a74of\u00a7c {2}\u00a74.
inventoryClearingAllArmor=\u00a76Cleared all inventory items and armor from {0}\u00a76.
inventoryClearingAllItems=\u00a76Cleared all inventory items from {0}\u00a76.
inventoryClearingAllStack=\u00a76Cleared all\u00a7c {0} \u00a76from {1}\u00a76.
inventoryClearingAllItems=\u00a76Cleared all inventory items from\u00a7c {0}\u00a76.
inventoryClearingFromAll=\u00a76Clearing the inventory of all users...
inventoryClearingStack=\u00a76Removed\u00a7c {0} \u00a76of\u00a7c {1} \u00a76from {2}\u00a76.
inventoryClearingStack=\u00a76Removed\u00a7c {0} \u00a76of\u00a7c {1} \u00a76from\u00a7c {2}\u00a76.
is=is
isIpBanned=\u00a76IP \u00a7c{0} \u00a76is banned.
internalError=\u00a7cAn internal error occurred while attempting to perform this command.
@@ -214,15 +211,18 @@ itemCannotBeSold=\u00a74That item cannot be sold to the server.
itemId=\u00a76ID\:\u00a7c {0}
itemMustBeStacked=\u00a74Item must be traded in stacks. A quantity of 2s would be two stacks, etc.
itemNames=\u00a76Item short names\:\u00a7r {0}
itemnameClear=\u00a76You have cleared this item''s name.
itemnameInvalidItem=\u00a7cYou need to hold an item to rename it.
itemnameSuccess=\u00a76You have renamed your held item to "\u00a7c{0}\u00a76".
itemNotEnough1=\u00a74You do not have enough of that item to sell.
itemNotEnough2=\u00a76If you meant to sell all of your items of that type, use /sell itemname.
itemNotEnough3=\u00a76/sell itemname -1 will sell all but one item, etc.
itemNotEnough2=\u00a76If you meant to sell all of your items of that type, use\u00a7c /sell itemname\u00a76.
itemNotEnough3=\u00a7c/sell itemname -1\u00a76 will sell all but one item, etc.
itemsConverted=\u00a76Converted all items into blocks.
itemsCsvNotLoaded=Could not load items.csv\!
itemSellAir=You really tried to sell Air? Put an item in your hand.
itemsNotConverted=\u00a74You have no items that can be converted into blocks.
itemSold=\u00a7aSold for \u00a7c{0} \u00a7a({1} {2} at {3} each).
itemSoldConsole=\u00a7a{0} \u00a7asold {1} for \u00a7a{2} \u00a7a({3} items at {4} each).
itemSoldConsole=\u00a7e{0} \u00a7asold\u00a7e {1}\u00a7a for \u00a7e{2} \u00a7a({3} items at {4} each).
itemSpawn=\u00a76Giving\u00a7c {0} \u00a76of\u00a7c {1}
itemType=\u00a76Item\:\u00a7c {0}
jailAlreadyIncarcerated=\u00a74Person is already in jail\:\u00a7c {0}
@@ -252,13 +252,13 @@ kitOnce=\u00a74You can''t use that kit again.
kitReceive=\u00a76Received kit\u00a7c {0}\u00a76.
kits=\u00a76Kits\:\u00a7r {0}
kitTimed=\u00a74You can''t use that kit again for another\u00a7c {0}\u00a74.
leatherSyntax=\u00a76Leather color syntax\: color\:<red>,<green>,<blue> eg\: color\:255,0,0 OR color\:<rgb int> eg\: color\:16777011
leatherSyntax=\u00a76Leather color syntax\:\u00a7c color\:<red>,<green>,<blue> eg\: color\:255,0,0\u00a76 OR\u00a7c color\:<rgb int> eg\: color\:16777011
lightningSmited=\u00a76Thou hast been smitten\!
lightningUse=\u00a76Smiting\u00a7c {0}
listAfkTag=\u00a77[AFK]\u00a7r
listAmount=\u00a76There are \u00a7c{0}\u00a76 out of maximum \u00a7c{1}\u00a76 players online.
listAmountHidden=\u00a76There are \u00a7c{0}\u00a76/{1}\u00a76 out of maximum \u00a7c{2}\u00a76 players online.
listGroupTag=\u00a76{0}\u00a7r\: \u00a7r
listAmountHidden=\u00a76There are \u00a7c{0}\u00a76/\u00a7c{1}\u00a76 out of maximum \u00a7c{2}\u00a76 players online.
listGroupTag=\u00a76{0}\u00a7r\:
listHiddenTag=\u00a77[HIDDEN]\u00a7r
loadWarpError=\u00a74Failed to load warp {0}.
localFormat=[L]<{0}> {1}
@@ -271,8 +271,6 @@ mailMessage={0}
mailSent=\u00a76Mail sent\!
mailSentTo=\u00a7c{0}\u00a76 has been sent the following mail\:
mailTooLong=\u00a74Mail message too long. Try to keep it below 1000 characters.
markedAsAway=\u00a76You are now marked as away.
markedAsNotAway=\u00a76You are no longer marked as away.
markMailAsRead=\u00a76To mark your mail as read, type\u00a7c /mail clear\u00a76.
matchingIPAddress=\u00a76The following players previously logged in from that IP address\:
maxHomes=\u00a74You cannot set more than\u00a7c {0} \u00a74homes.
@@ -289,12 +287,12 @@ mobsAvailable=\u00a76Mobs\:\u00a7r {0}
mobSpawnError=\u00a74Error while changing mob spawner.
mobSpawnLimit=Mob quantity limited to server limit.
mobSpawnTarget=\u00a74Target block must be a mob spawner.
moneyRecievedFrom=\u00a7a{0} has been received from {1}.
moneyRecievedFrom=\u00a7a{0}\u00a76 has been received from\u00a7a {1}\u00a76.
moneySentTo=\u00a7a{0} has been sent to {1}.
month=month
months=months
moreThanZero=\u00a74Quantities must be greater than 0.
moveSpeed=\u00a76Set {0} speed to\u00a7c {1} \u00a76for \u00a7c{2}\u00a76.
moveSpeed=\u00a76Set\u00a7c {0}\u00a76 speed to\u00a7c {1} \u00a76for \u00a7c{2}\u00a76.
msgDisabled=\u00a76Receiving messages \u00a7cdisabled\u00a76.
msgDisabledFor=\u00a76Receiving messages \u00a7cdisabled \u00a76for \u00a7c{0}\u00a76.
msgEnabled=\u00a76Receiving messages \u00a7cenabled\u00a76.
@@ -305,11 +303,15 @@ multipleCharges=\u00a74You cannot apply more than one charge to this firework.
multiplePotionEffects=\u00a74You cannot apply more than one effect to this potion.
mutedPlayer=\u00a76Player\u00a7c {0} \u00a76muted.
mutedPlayerFor=\u00a76Player\u00a7c {0} \u00a76muted for\u00a7c {1}\u00a76.
mutedPlayerForReason=\u00a76Player\u00a7c {0} \u00a76muted for\u00a7c {1}\u00a76. Reason: \u00a7c{2}
mutedPlayerReason=\u00a76Player\u00a7c {0} \u00a76muted. Reason: \u00a7c{1}
mutedUserSpeaks={0} tried to speak, but is muted: {1}
muteExempt=\u00a74You may not mute that player.
muteExemptOffline=\u00a74You may not mute offline players.
muteNotify=\u00a7c{0} \u00a76has muted player \u00a7c{1}\u00a76.
muteNotifyFor=\u00a7c{0} \u00a76has muted player \u00a7c{1}\u00a76 for\u00a7c {2}\u00a76.
muteNotifyForReason=\u00a7c{0} \u00a76has muted player \u00a7c{1}\u00a76 for\u00a7c {2}\u00a76. Reason: \u00a7c{3}
muteNotifyReason=\u00a7c{0} \u00a76has muted player \u00a7c{1}\u00a76. Reason: \u00a7c{2}
nearbyPlayers=\u00a76Players nearby\:\u00a7r {0}
negativeBalanceError=\u00a74User is not allowed to have a negative balance.
nickChanged=\u00a76Nickname changed.
@@ -324,12 +326,10 @@ noAccessCommand=\u00a74You do not have access to that command.
noAccessPermission=\u00a74You do not have permission to access that \u00a7c{0}\u00a74.
noBreakBedrock=\u00a74You are not allowed to destroy bedrock.
noDestroyPermission=\u00a74You do not have permission to destroy that \u00a7c{0}\u00a74.
noDurability=\u00a74This item does not have a durability.
northEast=NE
north=N
northWest=NW
noGodWorldWarning=\u00a74Warning\! God mode in this world disabled.
noHelpFound=\u00a74No matching commands.
noHomeSetPlayer=\u00a76Player has not set a home.
noIgnored=\u00a76You are not ignoring anyone.
noJailsDefined=\u00a76No jails defined.
@@ -359,8 +359,6 @@ notEnoughExperience=\u00a74You do not have enough experience.
notEnoughMoney=\u00a74You do not have sufficient funds.
notFlying=not flying
nothingInHand=\u00a74You have nothing in your hand.
notRecommendedBukkit=\u00a74* \! * Bukkit version is not the recommended build for Essentials.
notSupportedYet=Not supported yet.
now=now
noWarpsDefined=\u00a76No warps defined.
nuke=\u00a75May death rain upon them.
@@ -380,17 +378,18 @@ payToggleOn=\u00a76You are now accepting payments.
pendingTeleportCancelled=\u00a74Pending teleportation request cancelled.
playerBanIpAddress=\u00a76Player\u00a7c {0} \u00a76banned IP address\u00a7c {1} \u00a76for\: \u00a7c{2}\u00a76.
playerBanned=\u00a76Player\u00a7c {0} \u00a76banned\u00a7c {1} \u00a76for\: \u00a7c{2}\u00a76.
playerInJail=\u00a74Player is already in jail\u00a7c {0}\u00a74.
playerJailed=\u00a76Player\u00a7c {0} \u00a76jailed.
playerJailedFor=\u00a76Player\u00a7c {0} \u00a76jailed for {1}.
playerKicked=\u00a76Player\u00a7c {0} \u00a76kicked {1} for {2}.
playerJailedFor=\u00a76Player\u00a7c {0} \u00a76jailed for\u00a7c {1}\u00a76.
playerKicked=\u00a76Player\u00a7c {0} \u00a76kicked\u00a7c {1}\u00a76 for\u00a7c {2}\u00a76.
playerMuted=\u00a76You have been muted\!
playerMutedFor=\u00a76You have been muted for\u00a7c {0}.
playerMutedFor=\u00a76You have been muted for\u00a7c {0}\u00a76.
playerMutedForReason=\u00a76You have been muted for\u00a7c {0}\u00a76. Reason\: \u00a7c{1}
playerMutedReason=\u00a76You have been muted\! Reason\: \u00a7c{0}
playerNeverOnServer=\u00a74Player\u00a7c {0} \u00a74was never on this server.
playerNotFound=\u00a74Player not found.
playerTempBanned=\u00a76Player \u00a7c{0}\u00a76 temporarily banned \u00a7c{1}\u00a76 for \u00a7c{2}\u00a76: \u00a7c{3}\u00a76.
playerUnbanIpAddress=\u00a76Player\u00a7c {0} \u00a76unbanned IP\: {1}.
playerUnbanned=\u00a76Player\u00a7c {0} \u00a76unbanned\u00a7c {1}.
playerTempBanned=\u00a76Player \u00a7c{0}\u00a76 temporarily banned \u00a7c{1}\u00a76 for \u00a7c{2}\u00a76\: \u00a7c{3}\u00a76.
playerUnbanIpAddress=\u00a76Player\u00a7c {0} \u00a76unbanned IP\:\u00a7c {1}
playerUnbanned=\u00a76Player\u00a7c {0} \u00a76unbanned\u00a7c {1}
playerUnmuted=\u00a76You have been unmuted.
pong=Pong\!
posPitch=\u00a76Pitch\: {0} (Head angle)
@@ -402,7 +401,7 @@ posZ=\u00a76Z\: {0} (+South <-> -North)
potions=\u00a76Potions\:\u00a7r {0}\u00a76.
powerToolAir=\u00a74Command can''t be attached to air.
powerToolAlreadySet=\u00a74Command \u00a7c{0}\u00a74 is already assigned to \u00a7c{1}\u00a74.
powerToolAttach=\u00a7c{0}\u00a76 command assigned to {1}.
powerToolAttach=\u00a7c{0}\u00a76 command assigned to\u00a7c {1}\u00a76.
powerToolClearAll=\u00a76All powertool commands have been cleared.
powerToolList=\u00a76Item \u00a7c{1} \u00a76has the following commands\: \u00a7c{0}\u00a76.
powerToolListEmpty=\u00a74Item \u00a7c{0} \u00a74has no commands assigned.
@@ -427,7 +426,7 @@ pWeatherPlayers=\u00a76These players have their own weather\:\u00a7r
pWeatherReset=\u00a76Player weather has been reset for\: \u00a7c{0}
pWeatherSet=\u00a76Player weather is set to \u00a7c{0}\u00a76 for\: \u00a7c{1}.
questionFormat=\u00a72[Question]\u00a7r {0}
radiusTooBig=\u00a74Radius is too big\! Maximum radius is {0}.
radiusTooBig=\u00a74Radius is too big\! Maximum radius is\u00a7c {0}\u00a74.
readNextPage=\u00a76Type\u00a7c /{0} {1} \u00a76to read the next page.
realName=\u00a7f{0}\u00a7r\u00a76 is \u00a7f{1}
recentlyForeverAlone=\u00a74{0} recently went offline.
@@ -436,7 +435,7 @@ recipeBadIndex=There is no recipe by that number.
recipeFurnace=\u00a76Smelt\: \u00a7c{0}\u00a76.
recipeGrid=\u00a7c{0}X \u00a76| \u00a7{1}X \u00a76| \u00a7{2}X
recipeGridItem=\u00a7c{0}X \u00a76is \u00a7c{1}
recipeMore=\u00a76Type /{0} \u00a7c{1}\u00a76 <number> to see other recipes for \u00a7c{2}\u00a76.
recipeMore=\u00a76Type\u00a7c /{0} {1} <number>\u00a76 to see other recipes for \u00a7c{2}\u00a76.
recipeNone=No recipes exist for {0}.
recipeNothing=nothing
recipeShapeless=\u00a76Combine \u00a7c{0}
@@ -447,6 +446,10 @@ repairAlreadyFixed=\u00a74This item does not need repairing.
repairEnchanted=\u00a74You are not allowed to repair enchanted items.
repairInvalidType=\u00a74This item cannot be repaired.
repairNone=\u00a74There were no items that needed repairing.
replyLastRecipientDisabled=\u00a76Replying to last message recipient \u00a7cdisabled\u00a76.
replyLastRecipientDisabledFor=\u00a76Replying to last message recipient \u00a7cdisabled \u00a76for \u00a7c{0}\u00a76.
replyLastRecipientEnabled=\u00a76Replying to last message recipient \u00a7cenabled\u00a76.
replyLastRecipientEnabledFor=\u00a76Replying to last message recipient \u00a7cenabled \u00a76for \u00a7c{0}\u00a76.
requestAccepted=\u00a76Teleport request accepted.
requestAcceptedFrom=\u00a7c{0} \u00a76accepted your teleport request.
requestDenied=\u00a76Teleport request denied.
@@ -454,7 +457,6 @@ requestDeniedFrom=\u00a7c{0} \u00a76denied your teleport request.
requestSent=\u00a76Request sent to\u00a7c {0}\u00a76.
requestSentAlready=\u00a74You have already sent {0}\u00a74 a teleport request.
requestTimedOut=\u00a74Teleport request has timed out.
requiredBukkit=\u00a76* \! * You need at least build {0} of CraftBukkit, download it from http\://dl.bukkit.org/downloads/craftbukkit/
resetBal=\u00a76Balance has been reset to \u00a7c{0} \u00a76for all online players.
resetBalAll=\u00a76Balance has been reset to \u00a7c{0} \u00a76for all players.
returnPlayerToJailError=\u00a74Error occurred when trying to return player\u00a7c {0} \u00a74to jail\: \u00a7c{1}\u00a74\!
@@ -485,7 +487,7 @@ southWest=SW
skullChanged=\u00a76Skull changed to \u00a7c{0}\u00a76.
slimeMalformedSize=\u00a74Malformed size.
socialSpy=\u00a76SocialSpy for \u00a7c{0}\u00a76\: \u00a7c{1}
socialSpyMsgFormat=\u00a76[\u00a7c{0}\u00a76 -> \u00a7c{1}\u00a76] \u00a77{2}
socialSpyMsgFormat=\u00a76[\u00a7c{0}\u00a77 -> \u00a7c{1}\u00a76] \u00a77{2}
socialSpyMutedPrefix=\u00a7f[\u00a76SS\u00a7f] \u00a77(muted) \u00a7r
socialSpyPrefix=\u00a7f[\u00a76SS\u00a7f] \u00a7r
soloMob=\u00a74That mob likes to be alone.
@@ -497,8 +499,8 @@ sudoRun=\u00a76Forcing\u00a7c {0} \u00a76to run\:\u00a7r /{1}
suicideMessage=\u00a76Goodbye cruel world...
suicideSuccess=\u00a76Player \u00a7c{0} \u00a76took their own life.
survival=survival
takenFromAccount=\u00a7a{0} has been taken from your account.
takenFromOthersAccount=\u00a7a{0} taken from {1}\u00a7a account. New balance\: {2}.
takenFromAccount=\u00a7e{0}\u00a7a has been taken from your account.
takenFromOthersAccount=\u00a7e{0}\u00a7a taken from\u00a7e {1}\u00a7a account. New balance\:\u00a7e {2}
teleportAAll=\u00a76Teleport request sent to all players...
teleportAll=\u00a76Teleporting all players...
teleportationCommencing=\u00a76Teleportation commencing...
@@ -509,19 +511,21 @@ teleportationEnabledFor=\u00a76Teleportation \u00a7cenabled \u00a76for \u00a7c{0
teleportAtoB=\u00a7c{0}\u00a76 teleported you to \u00a7c{1}\u00a76.
teleportDisabled=\u00a7c{0} \u00a74has teleportation disabled.
teleportHereRequest=\u00a7c{0}\u00a76 has requested that you teleport to them.
teleportHome=\u00a76Teleporting to \u00a7c{0}\u00a76.
teleporting=\u00a76Teleporting...
teleportInvalidLocation=Value of coordinates cannot be over 30000000
teleportNewPlayerError=\u00a74Failed to teleport new player\!
teleportRequest=\u00a7c{0}\u00a76 has requested to teleport to you.
teleportRequestAllCancelled=\u00a76All outstanding teleport requests cancelled.
teleportRequestSpecificCancelled=\u00a76Outstanding teleport request with {0} cancelled.
teleportRequestCancelled=\u00a76Your teleport request to \u00a7c{0}\u00a76 was cancelled.
teleportRequestSpecificCancelled=\u00a76Outstanding teleport request with\u00a7c {0}\u00a76 cancelled.
teleportRequestTimeoutInfo=\u00a76This request will timeout after\u00a7c {0} seconds\u00a76.
teleportTop=\u00a76Teleporting to top.
teleportToPlayer=\u00a76Teleporting to \u00a7c{0}\u00a76.
tempbanExempt=\u00a74You may not tempban that player.
tempbanExemptOffline=\u00a74You may not tempban offline players.
tempbanJoin=You are banned from this server for {0}. Reason: {1}
tempBanned=\u00a7cYou have been temporarily banned for {0}\:\n\u00a7r{2}
tempBanned=\u00a7cYou have been temporarily banned for\u00a7r {0}\:\n\u00a7r{2}
thunder=\u00a76You\u00a7c {0} \u00a76thunder in your world.
thunderDuration=\u00a76You\u00a7c {0} \u00a76thunder in your world for\u00a7c {1} \u00a76seconds.
timeBeforeHeal=\u00a74Time before next heal\:\u00a7c {0}\u00a76.
@@ -545,7 +549,7 @@ typeTpacancel=\u00a76To cancel this request, type \u00a7c/tpacancel\u00a76.
typeTpaccept=\u00a76To teleport, type \u00a7c/tpaccept\u00a76.
typeTpdeny=\u00a76To deny this request, type \u00a7c/tpdeny\u00a76.
typeWorldName=\u00a76You can also type the name of a specific world.
unableToSpawnItem=\u00a74Cannot spawn \u00a7c{0}\u00a74, this is not a spawnable item.
unableToSpawnItem=\u00a74Cannot spawn \u00a7c{0}\u00a74; this is not a spawnable item.
unableToSpawnMob=\u00a74Unable to spawn mob.
unignorePlayer=\u00a76You are not ignoring player\u00a7c {0} \u00a76anymore.
unknownItemId=\u00a74Unknown item id\:\u00a7r {0}\u00a74.
@@ -579,6 +583,7 @@ versionOutputUnsupportedPlugins=\u00a76You are running \u00a7dunsupported plugin
versionMismatch=\u00a74Version mismatch\! Please update {0} to the same version.
versionMismatchAll=\u00a74Version mismatch\! Please update all Essentials jars to the same version.
voiceSilenced=\u00a76Your voice has been silenced\!
voiceSilencedReason=\u00a76Your voice has been silenced\! Reason: \u00a7c{0}
walking=walking
warpDeleteError=\u00a74Problem deleting the warp file.
warpingTo=\u00a76Warping to\u00a7c {0}\u00a76.
@@ -592,9 +597,9 @@ warpSet=\u00a76Warp\u00a7c {0} \u00a76set.
warpUsePermission=\u00a74You do not have permission to use that warp.
weatherInvalidWorld=World named {0} not found\!
weatherStorm=\u00a76You set the weather to \u00a7cstorm\u00a76 in\u00a7c {0}\u00a76.
weatherStormFor=\u00a76You set the weather to \u00a7cstorm\u00a76 in\u00a7c {0} \u00a76for {1} seconds.
weatherStormFor=\u00a76You set the weather to \u00a7cstorm\u00a76 in\u00a7c {0} \u00a76for\u00a7c {1} seconds\u00a76.
weatherSun=\u00a76You set the weather to \u00a7csun\u00a76 in\u00a7c {0}\u00a76.
weatherSunFor=\u00a76You set the weather to \u00a7csun\u00a76 in\u00a7c {0} \u00a76for {1} seconds.
weatherSunFor=\u00a76You set the weather to \u00a7csun\u00a76 in\u00a7c {0} \u00a76for \u00a7c{1} seconds\u00a76.
west=W
whoisAFK=\u00a76 - AFK\:\u00a7r {0}
whoisAFKSince=\u00a76 - AFK\:\u00a7r {0} (Since {1})
@@ -611,10 +616,11 @@ whoisJail=\u00a76 - Jail\:\u00a7r {0}
whoisLocation=\u00a76 - Location\:\u00a7r ({0}, {1}, {2}, {3})
whoisMoney=\u00a76 - Money\:\u00a7r {0}
whoisMuted=\u00a76 - Muted\:\u00a7r {0}
whoisMutedReason=\u00a76 - Muted\:\u00a7r {0} \u00a76Reason\: \u00a7c{1}
whoisNick=\u00a76 - Nick\:\u00a7r {0}
whoisOp=\u00a76 - OP\:\u00a7r {0}
whoisPlaytime=\u00a76 - Playtime\:\u00a7r {0}
whoisTempBanned=\u00a76 - Ban expires:\u00a7r {0}
whoisTempBanned=\u00a76 - Ban expires\:\u00a7r {0}
whoisTop=\u00a76 \=\=\=\=\=\= WhoIs\:\u00a7c {0} \u00a76\=\=\=\=\=\=
whoisUuid=\u00a76 - UUID\:\u00a7r {0}
worth=\u00a7aStack of {0} worth \u00a7c{1}\u00a7a ({2} item(s) at {3} each)
+598
View File
@@ -0,0 +1,598 @@
#X-Generator: crowdin.net
#version: ${full.version}
# Single quotes have to be doubled: ''
# by:
action=§5* {0} §5{1}
addedToAccount=§a{0} бяха добавени към вашият акаунт.
addedToOthersAccount=§a{0} бяха добавени към акаунта на {1}. Нов баланс\: {2}
adventure=приключенски
alertBroke=счупени\:
alertFormat=§3[{0}] §r {1} §6 {2} at\: {3}
alertPlaced=поставени\:
alertUsed=използвани\:
alphaNames=§4Имената на играчите могат да съдържат само букви, цифри и долни черти.
antiBuildBreak=§4Нямате право да чупите блокчета§c {0} §4тук.
antiBuildCraft=§4Нямате право да създавате§c {0}§4.
antiBuildDrop=§4Нямате право да изхвърляте§c {0}§4.
antiBuildInteract=§4Нямате право да взаимодействате с§c {0}§4.
antiBuildPlace=§4Нямате право да поставяте§c {0} §4тук.
antiBuildUse=§4Нямате право да използвате§c {0}§4.
autoAfkKickReason=Вие бяхте изгонени поради повече от {0} минути бездействие.
backAfterDeath=§6Използвайте командата /back, за да се върнете на мястото където сте умрели.
backOther=§6Върнахте§c {0}§6 до предишното им местоположение.
backupDisabled=§4Няма конфигуриран външен архивиращ скрипт.
backupFinished=§6Архивирането е завършено.
backupStarted=§6Създаване на архив.
backUsageMsg=§6Връщане до предишната локация.
balance=§aБаланс\:§c {0}
balanceOther=§aБалансът на {0}§a\:§c {1}
balanceTop=§6Топ богаташи ({0})
banExempt=§4Не можете да ограничите този играч.
banExemptOffline=§4Не можете да ограничавате офлайн играчи.
banFormat=§cВие бяхте ограничени\:\n§r{0}
banIpJoin=Вашият IP адрес е ограничен от този сървър. Причина\: {0}
banJoin=Вие сте ограничени от този сървър. Причина\: {0}
bed=§oлегло§r
bedMissing=§4Вашето легло е незададено, липсващо или блокирано.
bedNull=§mлегло§r
bedSet=§6Локация на легло е зададена\!
bigTreeFailure=§4Провал при създаване на голямо дърво. Опитайте върху пръст или трева.
bigTreeSuccess=§6Създадено е голямо дърво.
blockList=§6Essentials предаде следните команди на друг плъгин\:
bookAuthorSet=§6Авторът на книгата е зададен на {0}.
bookLocked=§6Книгата е заключена.
bookTitleSet=§6Заглавието на книгата е зададено на {0}.
broadcast=§r§6[§4Съобщение§6]§a {0}
burnMsg=§6Подпалихте§c {0} §6за§c {1} секунди§6.
cannotStackMob=§4Нямате право да групирате множество животни.
canTalkAgain=§6Вече можете да говорите.
cantFindGeoIpDB=Няма намерена GeoIP база данни\!
cantGamemode=§4Нямате право да променяте режима си на {0}
cantReadGeoIpDB=Грешка при прочитането на GeoIP базата данни\!
cantSpawnItem=§4Нямате право да създадете предмета§c {0}§4.
chatTypeLocal=[L]
chatTypeSpy=[Шпионин]
cleaned=Потребителските файлове са изчистени.
cleaning=Изчистване на потребителските файлове.
clearInventoryConfirmToggleOff=§6Вече няма да бъдете питани да потвърждение за триенето на инвентари.
clearInventoryConfirmToggleOn=§6Вече ще да бъдете питани да потвърждение за триенето на инвентари.
commandCooldown=§cНе можете да пишете тази команда за {0}.
commandFailed=Неуспех при изпълнение на командата {0}\:
commandHelpFailedForPlugin=Грешка при получаването на помощ за плъгина\: {0}
commandNotLoaded=§4Командата {0} е грешно заредена.
compassBearing=§6Посока\: {0} ({1} градуса).
configFileMoveError=Грешка при прехвърлянето на config.yml в архива.
configFileRenameError=Грешка при преименуването на временния файл на config.yml.
confirmClear=§7За да §lпотвърдите§7 изчистването на инвентара, препишете командата\: §6{0}
confirmPayment=§7За да §lПОТВЪРДИТЕ§7 плащането на §6{0}§7, моля повторете командата\: §6{1}
connectedPlayers=§6Свързани играчи§r
connectionFailed=Неуспешно отваряне на връзка.
cooldownWithMessage=§4Изчакване\: {0}
coordsKeyword={0}, {1}, {2}
couldNotFindTemplate=§4Не може да се намери шаблон {0}
createdKit=§6Създадохте кит §c{0} §6с §c{1} §6употреби и интервал от §c{2}
createKitFailed=§4Грешка при създаването на кит {0}.
createKitSeparator=§m-----------------------
createKitSuccess=§6Създаден кит\: §f{0}\n§6Интервал\: §f{1}\n§6Връзка\: §f{2}\n§6Копирайте съдържанието от връзката отгоре във вашият kits.yml.
creatingConfigFromTemplate=Създаване на конфигурация от шаблон\: {0}
creatingEmptyConfig=Създаване на празна конфигурация\: {0}
creative=творчески
currency={0}{1}
currentWorld=§6Текущ свят\:§c {0}
day=ден
days=дни
defaultBanReason=Вие бяхте ограничени от този сървър\!
deleteFileError=Не може да бъде изтрит файлът\: {0}
deleteHome=§6Домът§c {0} §6беше премахнат.
deleteJail=§6Затворът§c {0} §6беше премахнат.
deleteWarp=§6Точката за телепортация§c {0} §6беше премахната.
deniedAccessCommand=§c{0} §4беше отказан достъп до командата.
denyBookEdit=§4Не можете да отключите тази книга.
denyChangeAuthor=§4Не можете да промените авторът на тази книга.
denyChangeTitle=§4Не можете да промените заглавието на книгата.
depth=§6Вие сте на морско ниво.
depthAboveSea=§6Вие сте на§c {0} §6блокче(та) над морското ниво.
depthBelowSea=§6Вие сте на§c {0} §6блокче(та) под морското ниво.
destinationNotSet=Дестинацията не е зададена\!
disabled=изключен
disabledToSpawnMob=§4Размножаването на това същество е изключено в конфигурационния файл.
disableUnlimited=§6Изключихте безбройното слагане на §c {0} §6за {1}.
distance=§6Разстояние\: {0}
dontMoveMessage=§6Телепортацията ще се осъществи след§c {0}§6. Не се движете.
downloadingGeoIp=Изтегля се GeoIP база данни... това може да отнеме време (държава\: 1.7 MB, град\: 30MB)
duplicatedUserdata=Дублирани данни на играчи\: {0} и {1}.
durability=§6На инструмента му остават §c{0}§6 използвания.
east=И
editBookContents=§eСега можете да редактирате съдържанието на тази книга.
enabled=включен
enableUnlimited=§6Даване на безброй количество от§c {0} §6на §c{1}§6.
enchantmentApplied=§6Енчантът§c {0} §6беше приложен на предметът в ръката ви.
enchantmentNotFound=§4Енчантът не намерен\!
enchantmentPerm=§4Нямате правото за§c {0}§4.
enchantmentRemoved=§6Енчантът§c {0} §6беше премахнат от предмета в ръката ви.
enchantments=§6Енчанти\:§r {0}
errorCallingCommand=Грешка при изпълняването на командата /{0}
errorWithMessage=§cГрешка\:§4 {0}
essentialsHelp1=Файлът е повреден и Essentials не може да го отвори. Essentials се изключва. Ако не можете да поправите сами, отидете на http\://tiny.cc/EssentialsChat
essentialsHelp2=Файлът е повреден и Essentials не може да го отвори. Essentials се изключва. Ако не можете да поправите сами или напишете /essentialshelp в играта, или отидете на http\://tiny.cc/EssentialsChat
essentialsReload=§6Essentials е презареден§c {0}.
exp=§c{0} §6има§c {1} §6опит (ниво§c {2}§6) и им трябва§c {3} §6опит за да вдигнат ниво.
expSet=§c{0} §6сега има§c {1} §6опит.
extinguish=§6Вие се изгасихте.
extinguishOthers=§6Изгасихте {0}§6.
failedToCloseConfig=Грешка при затварянето на конфигурация {0}.
failedToCreateConfig=Грешка при създаването на конфигурация {0}.
failedToWriteConfig=Грешка при записа на конфигурация {0}.
false=§4не§r
feed=§6Вашият апетит беше заситен.
feedOther=§6Заситихте апетита на §c{0}§6.
fileRenameError=Грешка при реименуването на файла {0}\!
fireworkColor=§4Бяха въведени невалидни параметри на заряд, първо трябва да се въведе цвят.
fireworkEffectsCleared=§6Бяха премахнати всички ефекти от това което държите.
fireworkSyntax=§6Параметри за фойерверк\:§c color\:<color> [fade\:<цвят>] [shape\:<форма>] [effect\:<ефект>]\n§6За да използвате няколко цвята/ефекта, разделете стойностите със запетая\: §cred,blue,pink\n§6Форми\:§c star, ball, large, creeper, burst §6Ефекти\:§c trail, twinkle.
flying=лети
flyMode=§6Зададохте режим на летене на§c {0} §6за {1}§6.
foreverAlone=§4Няма на кого да отговорите.
fullStack=§4Вече имате цял стак.
gameMode=§6Зададохте режим на игра на§c {0} §6за §c{1}§6.
gameModeInvalid=§4Трябва да посочите валиден играч/режим на игра.
gcfree=§6Свободна памет\:§c {0} MB.
gcmax=§6Максимум памет\:§c {0} MB.
gctotal=§6Зададена памет\:§c {0} MB.
gcWorld=§6{0} "§c{1}§6"\: §c{2}§6 разреза, §c{3}§6 създания, §c{4}§6 плочки.
geoipJoinFormat=§6Играчът §c{0} §6идва от §c{1}§6.
geoipCantFind=§6Играчът §c{0} §6идва от §aнеизвестна държава§6.
geoIpUrlEmpty=Линкът за изтегляне на GeoIP е празен.
geoIpUrlInvalid=Линкът за изтегляне на GeoIP е невалиден.
givenSkull=§6Беше ви дадена главата на §c{0}§6.
giveSpawn=§6Даване на§c {0} §6от§c {1} на§c {2}§6.
giveSpawnFailure=§4Недостатъчно свободно място, §c{0} §c{1} §4беше загубено.
godDisabledFor=§cизключен§6 за§c {0}
godEnabledFor=§aвключен§6 за§c {0}
godMode=§6Режим на неуязвимост§c {0}§6.
groupDoesNotExist=§4Няма активни играчи от тази група\!
groupNumber=§c{0}§f активни, за пълния списък\:§c /{1} {2}
hatArmor=§4Не можете да използвате този предмет за шапка\!
hatEmpty=§4Вие не носите шапка.
hatFail=§4Трябва да имате нещо за обличане в ръката си.
hatPlaced=§6Насладете се на новата си шапка\!
hatRemoved=§6Вашата шапка беше премахната.
haveBeenReleased=§6Вие бяхте освободени.
heal=§6Вие бяхте изцелени.
healDead=§4Не можете да излекувате мъртвец\!
healOther=§6Изцелихте§c {0}§6.
helpConsole=За да видите помощ в конзолата, напишете ''?''.
helpFrom=§6Команди от {0}\:
helpLine=§6/{0}§r\: {1}
helpMatching=§6Команди съвпадащи с "§c{0}§6"\:
helpOp=§4[Помощ]§r §6{0}\:§r {1}
helpPlugin=§4{0}§r\: Помощ за плъгин\: /help {1}
holdBook=§4Не държите книга в която може да се пише.
holdFirework=§4Трябва да държите фойерверк, за да му добавите ефект.
holdPotion=§4Трябва да държите отвара, за да и приложите ефект.
holeInFloor=§4Има дупка в пода\!
homes=§6Домове\:§r {0}
homeSet=§6Вече имате дом на тази локация.
hour=час
hours=часа
ignoredList=§6Игнорирани\:§r {0}
ignoreExempt=§4Не можете да игнорирате този играч.
ignorePlayer=§6От сега игнорирате играч§c {0}§6.
illegalDate=Невалиден формат на дата.
infoChapter=§6Изберете глава\:
infoChapterPages=§e ---- §6{0} §e--§6 Страница §c{1}§6 of §c{2} §e----
infoPages=§e ---- §6{2} §e--§6 Страница §c{0}§6/§c{1} §e----
infoUnknownChapter=§4Непозната глава.
insufficientFunds=§4Нямате достатъчно средства.
invalidBanner=§4Невалиден синтаксис на банер.
invalidCharge=§4Неправилен заряд.
invalidFireworkFormat=§4Опцията §c{0} §4е не е валидна стойност за §c{1}§4.
invalidHome=§4Дом с име§c {0} §4не съществува\!
invalidHomeName=§4Няма дом с такова име\!
invalidItemFlagMeta=§4Невалидна мета на опция за предмет\: §c{0}§4.
invalidMob=§4Няма такъв вид същество.
invalidNumber=Неправилно число.
invalidPotion=§4Няма такава отвара.
invalidPotionMeta=§4Невалидна мета на отвара\: §c{0}§4.
invalidSignLine=§4Ред§c {0} §4на табелата е неправилен.
invalidSkull=§4Трябва да държите глава на играч.
invalidWarpName=§4Няма уарп с такова име\!
invalidWorld=§4Няма такъв свят.
inventoryClearFail=§4Играчът {0} §4няма§c {1} §4от§c {2}§4.
inventoryClearingAllArmor=§6Премахнати са всички предмети и броня от инвентара на {0}§6.
inventoryClearingAllItems=§6Премахнати са всички предмети от инвентара на {0}§6.
inventoryClearingFromAll=§6Почистване на инвентарите на всички играчи...
inventoryClearingStack=e§6Премахнати са§c {0} §6броя§c {1} §6fот {2}§6.
is=e
isIpBanned=§6IP адресът §c{0} §6е ограничен.
internalError=Възникна грешка докато се опитвахте да изпълните тази команда.
itemCannotBeSold=§4Този предмет не може да бъде продаден на сървъра.
itemId=§6Номер\:§c {0}
itemMustBeStacked=§4Предметите трябва да бъдат търгувани в стакове. Количество от 2s може да е два стака, т.н.
itemNames=§6Кратки имена на предметите\:§r {0}
itemNotEnough1=§4Нямате достатъчно от този предмет, за да продавате.
itemsConverted=§6Превърнахте всички предмети в блокчета.
itemsCsvNotLoaded=Не може да се зареди items.csv\!
itemSellAir=Наистина ли опита да продадеш въздух? Сложете предмет в ръката си.
itemsNotConverted=§4Нямате предмети, които могат да се превърнат в блокчета.
itemSold=§aПродадено за §c{0} §a({1} {2} по {3} всеки).
itemSpawn=§6Даване на§c {0} §6от§c {1}
itemType=§6Предмет\:§c {0}
jailAlreadyIncarcerated=§4Играчът е вече в затвор\:§c {0}
jailList=§6Затвори\:§r {0}
jailMessage=§4Бяхте хвърлени в затвора. Приятна почивка\!
jailNotExist=§4Този затвор не съществува.
jailReleased=§6Играчът §c{0}§6 е освободен.
jailReleasedPlayerNotify=§6Вие бяхте освободен\!
jailSentenceExtended=§6Времето в затвора бе удължено на §c{0}§6.
jailSet=§6Затвор§c {0} §6беше зададен.
jumpError=§4Ох, това ще навреди на компютъра ти.
kickDefault=Бяхте изгонени от сървъра.
kickedAll=§4Изгонихте всички играчи от сървъра.
kickExempt=§4Не може да изгоните този играч.
kill=§6Убихте§c {0}§6.
killExempt=§4Не можете да убиете §c{0}§4.
kitContains=§6Кит §c{0} §6съдържа\:
kitCost=\ §7§o({0})§r
kitDelay=§m{0}§r
kitError=§4Няма китове.
kitError2=§4Този кит е неправилно дефиниран. Свържете се с администратор.
kitGiveTo=§6Даване на кит§c {0}§6 за §c{1}§6.
kitInvFull=§4Вашият инвентар е пълен, поставяне на предметите на земята.
kitItem=§6- §f{0}
kitNotFound=§4Такъв кит не съществува.
kitOnce=§4Не можете да използвате този кит отново.
kitReceive=§6Получихте кит§c {0}§6.
kits=§6Китове\:§r {0}
kitTimed=§4Не можете да използвате използвате този кит за още§c {0}§4.
lightningSmited=§6Бяхте покосени от мълния\!
lightningUse=§6Ударихте§c {0}§6 с мълния.
listAfkTag=§7[Неактивен]§r
listAmount=§6Има §c{0}§6 от максимум §c{1}§6 играчи онлайн.
listHiddenTag=§7[СКРИТ]§r
loadWarpError=§4Грешка при зареждането на уарп {0}.
localFormat=[L]<{0}> {1}
mailClear=§6За да изчистите пощата си, напишете§c /mail clear§6.
mailCleared=§6Пощата ви е почистена\!
mailDelay=Твърде много писма бяха пратени в една минута. Максимум\: {0}
mailFormat=§6[§r{0}§6] §r{1}
mailMessage={0}
mailSent=§6Писмото е изпратено\!
mailSentTo=§6Следната поща беше пратена на §c{0}§6\:
mailTooLong=§4Писмото е твърде дълго. Максимумът е 1000 знака.
markMailAsRead=§6За да маркирате всички писма като прочетени, напишете§c /mail clear§6.
matchingIPAddress=§6Следните играчи са влизали от този IP адрес\:
maxHomes=§4Не можете да имате повече от§c {0} §4домове.
maxMoney=§4Тази транзакция ще надвиши лимитът на сметката за този акаунт.
mayNotJail=§4Не можете да затворите този играч\!
mayNotJailOffline=§4Не може да затворите играчи извън линия.
me=аз
minimumPayAmount=§cМинималната сума която може да платите е {0}.
minute=минута
minutes=минути
missingItems=§4Нямате §c{0}x {1}§4.
mobDataList=§6Валидна дата на съществото\:§r {0}
mobsAvailable=§6Същества\:§r {0}
mobSpawnError=§4Грешка при сменянето на вида на размножителя.
mobSpawnLimit=Броят на съществата беше намален до лимита на сървъра.
mobSpawnTarget=§4Целта трябва да е размножител.
moneySentTo=§a{0} бяха пратени на {1}.
month=месец
months=месеца
moreThanZero=§4Сумата трябва да е повече от 0.
msgDisabled=§cИзключихте§6 получаването на съобщения.
msgDisabledFor=§cИзключихте§6 получаването на съобщения за §c{0}§6.
msgEnabled=§cВключихте§6 получаването на съобщения.
msgEnabledFor=§cВключихте§6 получаването на съобщения за §c{0}§6.
msgFormat=§6[§c{0}§6 -> §c{1}§6] §r{2}
msgIgnore=§cСъобщенията за {0} §4са изключени.
multipleCharges=§4Не можете да зареждате фойерверка с повече от един заряд.
multiplePotionEffects=§4Не можете да приложете повече от един ефект на тази отвара.
mutedPlayer=§6Играчът§c {0} §6бе перманентно заглушен.
mutedPlayerFor=§6Играчът§c {0} §6бе временно заглушен за§c {1}§6.
mutedUserSpeaks={0} се опита да говори, но е заглушен\: {1}
muteExempt=§4Не можете да заглушите този играч.
muteExemptOffline=§4Не можете да заглушавате играчи извън линия.
muteNotify=§c{0} §6заглуши §c{1}§6.
muteNotifyFor=§c{0} §6заглуши §c{1}§6 за§c {2}§6.
nearbyPlayers=§6Играчи наблизо\:§r {0}
negativeBalanceError=§4Играчът няма право да има негативен баланс.
nickChanged=§6Прякорът ви беше променен.
nickDisplayName=§4Трябва да активирате change-displayname в Essentials конфигурацията.
nickInUse=§4Това име вече се използва.
nickNamesAlpha=§4Имената трябва да съдържат само букви и числа.
nickNamesOnlyColorChanges=§4Само цветовете на имената могат да бъдат променяни.
nickNoMore=§6Вече нямате прякор.
nickSet=§6От сега вашият прякор е §c{0}§6.
nickTooLong=§4Този прякор е твърде дълъг.
noAccessCommand=§4Нямате достъп до тази команда.
noAccessPermission=§4Нямате право да достъпите §c{0}§4.
noBreakBedrock=§4Нямате право да чупите основен камък.
noDestroyPermission=§4Нямате право да чупите §c{0}§4.
northEast=СИ
north=С
northWest=СЗ
noGodWorldWarning=§4Внимание\! Режимът на неуязвимост в този свят е изключен.
noHomeSetPlayer=§6Играчът няма зададен дом.
noIgnored=§6Не игнорирате никого.
noJailsDefined=§6Няма съществуващ затвор.
noKitGroup=§4Нямате достъп до този кит.
noKitPermission=§4Нямате правото §c{0}§4, за да използвате този кит.
noKits=§6Няма налични китове.
noLocationFound=§4Няма открито местоположение.
noMail=§6Нямате писма.
noMatchingPlayers=§6Не са открити съответстващи играчи.
noMetaFirework=§4Нямата право да прилагате мета на фойерверка.
noMetaJson=JSON мета данните не са поддържани в тази версия на Bukkit.
noMetaPerm=§4Нямате права да прилагате метата §c{0}§4 на този предмет.
none=нищо
noNewMail=§6Нямате нова поща.
noPendingRequest=§4Нямате заявки за телепортация.
noPerm=§4Нямате правото §c{0}§4.
noPermissionSkull=§4Нямате правото да променяте главата.
noPermToAFKMessage=§4Нямате право да задавате съобщение при неактивност.
noPermToSpawnMob=§4Нямате право да разпространите това същество.
noPlacePermission=§4Нямате права да поставяте блокчета около тази табела.
noPotionEffectPerm=§4Нямате право да прилагате ефект §c{0} §4на тази отвара.
noPowerTools=§6Нямате предмети със зададени команди.
notAcceptingPay=§4{0} §4не приема плащания.
notAllowedToQuestion=§4Нямате право да използвате въпросителен знак.
notAllowedToShout=§4Нямате право да крещите.
notEnoughExperience=§4Нямате достатъчно опит.
notEnoughMoney=§4Нямате достатъчно средства.
notFlying=не лети
nothingInHand=§4Нямате нищо в ръката си.
now=сега
noWarpsDefined=§6Няма намерени уарпове.
nuke=§5Нека смъртта да се разпростре над тях.
numberRequired=Там трябва има число, глупчо.
onlyDayNight=/time приема единствено day/night.
onlyPlayers=§4Командата §c{0} §4може да се изпълни единствено в сървъра.
onlyPlayerSkulls=§4Можете да задавате единствено собственика на главите (§c397\:3§4).
onlySunStorm=§4/weather приема единствено sun/storm.
openingDisposal=§6Отваряне на кошчето за боклук...
orderBalances=§6Подреждане на баланските на§c {0} §6играчи, моля изчакайте...
oversizedTempban=§4Не може да ограничите играч за този период от време.
payConfirmToggleOff=§6Вече няма да бъдете питани за потвърждение на плащания.
payConfirmToggleOn=§6Вече ще бъдете питани за потвърждение на плащания.
payMustBePositive=§4Сумата трябва да е положителна.
payToggleOff=§6Вече ще отхвърляте всички плащания.
payToggleOn=§6Вече няма да отхвърляте всички плащания.
pendingTeleportCancelled=§4Заявката за телепортация беше отказана.
playerBanIpAddress=§6Играчът§c {0} §6ограничи IP адреса§c {1} §6за\: §c{2}§6.
playerBanned=§6Играчът§c {0} §6ограничи§c {1} §6за\: §c{2}§6.
playerJailed=§6Играчът§c {0} §6е освободен.
playerMuted=§6Вие бяхте заглушени\!
playerMutedFor=§6Вие бяхте заглушени за§c {0}.
playerMutedForReason=§6Вие бяхте заглушени за§c {0}§6. Причина\: §c{1}
playerNeverOnServer=§4Няма намерен играч с името§c {0}§4.
playerNotFound=§4Играчът не е намерен.
playerTempBanned=§6Играчът §c{0}§6 беше временно баннат §c{1}§6 за §c{2}§6\: §c{3}§6.
playerUnmuted=§6Вие бяхте отглушени.
pong=Понг\!
posPitch=§6Височина\: {0} (Посока на главата)
possibleWorlds=§6Възможни светове са номерата §c0§6 през §c{0}§6.
posX=§6X\: {0} (+Изток <-> -Запад)
posY=§6Y\: {0} (+Нагоре <-> -Надолу)
posYaw=§6Yaw\: {0} (Въртене)
posZ=§6Z\: {0} (+Юг <-> -Север)
potions=§6Отвари\:§r {0}§6.
powerToolAir=§4Командата не може да бъде назначена на въздух.
powerToolAlreadySet=§4Командата §c{0}§4 е вече заложена на §c{1}§4.
powerToolClearAll=§6Всички powertool команди бяха премахнати.
powerToolList=§6Предметът §c{1} §6има назначени командите\: §c{0}§6.
powerToolListEmpty=§4Предметът §c{0} §4няма назначени команди.
powerToolNoSuchCommandAssigned=§4Командата §c{0}§4 не беше назначена на §c{1}§4.
powerToolRemove=§6Командата §c{0}§6 беше премахната от §c{1}§6.
powerToolRemoveAll=§6Всички команди бяха премахнати от §c{0}§6.
powerToolsDisabled=§6Всичките ви предмети с команди бяха изключени.
powerToolsEnabled=§6Всичките ви предмети с команди бяха включени.
pTimeCurrent=§6Времето за §c{0}§6 е§c {1}§6.
pTimeCurrentFixed=§6Времето за §c{0}§6 е зададено на§c {1}§6.
pTimeNormal=§6Часовото време на §c{0}§6 е нормално и съвпада с това на сървъра.
pTimeOthersPermission=§4Нямате право да задавате часът на другите играчи.
pTimePlayers=§6Тези играчи имат собствено часово време\:§r
pTimeReset=§6Часовото време беше рестартирано за\: §c{0}
pTimeSet=§6Часовото време е зададено на §c{0}§6 за\: §c{1}.
pTimeSetFixed=§6Часовото време за играча е зададено на §c{0}§6 за\: §c{1}.
pWeatherCurrent=§6Времето на §c{0}§6 е§c {1}§6.
pWeatherInvalidAlias=§4Неправилен тип на време
pWeatherNormal=§6Времето на §c{0}§6 е нормално и съвпада с това на сървъра.
pWeatherOthersPermission=§4Нямате право да задавате времето на другите играчи.
pWeatherPlayers=§6Тези играчи имат собствено време\:§r
pWeatherReset=§6Времето беше рестартирано за\: §c{0}
pWeatherSet=§6Времето е зададено на §c{0}§6 за\: §c{1}.
questionFormat=§2[Въпрос]§r {0}
readNextPage=§6Напишете§c /{0} {1}§6, за да прочетете следващата страница.
realName=§f{0}§r§6 е §f{1}
recentlyForeverAlone=§4{0} наскоро излезе от игра.
recipe=§6Рецептата за §c{0}§6 (§c{1}§6 от §c{2}§6)
recipeBadIndex=Няма рецепта на този номер.
recipeFurnace=§6Изпекохте\: §c{0}§6.
recipeGrid=§c{0}X §6| §{1}X §6| §{2}X
recipeGridItem=§c{0}X §6е §c{1}
recipeNone=Няма съществуващи рецепти за {0}.
recipeNothing=нищо
recipeShapeless=§6Комбиниране на §c{0}
recipeWhere=§6Къде\: {0}
removed=§6Премахнати§c {0} §6същества.
repair=§6Вие успешно поправихте вашите\: §c{0}§6.
repairAlreadyFixed=§4Не е нужна поправка за този предмет.
repairEnchanted=§4Не можете да поправяте енчантати предмети.
repairInvalidType=§4Този предмет не може да бъде поправен.
repairNone=§4Няма предмети които се нуждаят от поправка.
replyLastRecipientDisabled=§6Отговарянето на последното съобщение е §cизключено§6.
replyLastRecipientDisabledFor=§6Отговарянето на последното съобщение е §cизключено §6за §c{0}§6.
replyLastRecipientEnabled=§6Отговарянето на последното съобщение е §aвключено§6.
replyLastRecipientEnabledFor=§6Отговарянето на последното съобщение е §aвключено §6за §c{0}§6.
requestAccepted=§6Заявката за телепорт е приета.
requestAcceptedFrom=§c{0} §6прие вашата заявка за телепорт.
requestDenied=§6Заявката за телепорт е отказана.
requestDeniedFrom=§c{0} §6отказва вашата заявка за телепорт.
requestSent=§6Изпратихте заявка на§c {0}§6.
requestSentAlready=§4Вече сте пратили заявка за телепортация на {0}§4.
requestTimedOut=§4Заявката за телепортация изтече.
resetBal=§6Балансът бе рестартиран на §c{0} §6за всички активни играчи.
resetBalAll=§6Балансът бе рестартиран на §c{0} §6за всички играчи.
returnPlayerToJailError=§4Възникна грешка при опит да върнете играча§c {0} §4в затвора\: §c{1}§4\!
runningPlayerMatch=§6Извършване на търсене за играчи подхождащи с ''§c{0}§6'' (може да отнеме малко време).
second=секунда
seconds=секунди
seenAccounts=§6Играчът е също познат като\:§c {0}
seenOffline=§6Играчът§c {0} §6е §4неактивен/на§6 от §c{1}§6.
seenOnline=§6Играчът§c {0} §6е §4активен/на§6 от §c{1}§6.
sellBulkPermission=§6Нямате право да продавате на куп.
sellHandPermission=§6Нямате право да продавате предмета в ръката си.
serverFull=Сървърът е пълен\!
serverTotal=§6Общо играчи\:§c {0}
serverUnsupported=Имате неподдържана версия на сървъра\!
setBal=§aВашият баланс беше зададен на {0}.
setBalOthers=§aЗададохте баланса на {0}§a на {1}.
setSpawner=§6Променихте вида на размножителя на§c {0}§6.
sheepMalformedColor=§4Неправилен цвят.
shoutFormat=§6[Викане]§r {0}
signFormatFail=§4[{0}]
signFormatSuccess=§1[{0}]
signFormatTemplate=[{0}]
signProtectInvalidLocation=§4Нямате право да създавате табела тук.
similarWarpExist=§4Вече съществува уарп със същото име.
southEast=ЮИ
south=Ю
southWest=ЮЗ
skullChanged=§6Черепът е променен на §c{0}§6.
slimeMalformedSize=§4Неправилна големина.
socialSpy=§6Режим на шпионин за §c{0}§6\: §c{1}
socialSpyMutedPrefix=§f[§6СШ§f] §7(заглушен) §r
socialSpyPrefix=§f[§6СШ§f] §r
soloMob=§4Това създание обича да е само.
spawned=размножено
spawnSet=§6Спаун локацията е зададена за група§c {0}§6.
spectator=наблюдател
sudoExempt=§4Не можете да контролирате §c{0}.
sudoRun=§6Принуждаване на§c {0} §6да напише\:§r /{1}
suicideMessage=§6Сбогом, жесток свят...
suicideSuccess=§6Играчът §c{0} §6се самоуби.
survival=оцеляване
teleportAAll=§6Беше изпратена покана за телепорт до всички играчи...
teleportAll=§6Телепортиране на всички играчи...
teleportationCommencing=§6Телепортацията започва...
teleportationDisabled=§6Телепортацията е §cизключена§6.
teleportationDisabledFor=§6Телепортацията е §cизключена §6за §c{0}§6.
teleportationEnabled=§6Телепортацията е §aвключена§6.
teleportationEnabledFor=§6Телепортацията е §aвключена §6за §c{0}§6.
teleportAtoB=§c{0}§6 ви телепортира до §c{1}§6.
teleportDisabled=§c{0} §4са с изключена телепортация.
teleportHereRequest=§c{0}§6 заявиха да се телепортирате §cдо тях§6.
teleporting=§6Телепортиране...
teleportInvalidLocation=Стойността на координатите не може да превишава 30000000.
teleportNewPlayerError=§4Не успяхте да телепортирате нов играч\!
teleportRequest=§c{0}§6 заяви да се телепортира §cдо вас§6.
teleportRequestAllCancelled=§6Всички други заявки за телепортация бяха отказани.
teleportRequestTimeoutInfo=§6Тази заявка ще изтече след§c {0} секунди§6.
teleportTop=§6Телепортиране до най-горната повърхност.
teleportToPlayer=§6Телепортирате се до §c{0}§6.
tempbanExempt=§4Не можете да баннете временно този играч.
tempbanExemptOffline=§4Не можете баннете временно играчи.
tempbanJoin=Вие бяхте временно баннати от този сървър {0}. Причина\: {1}
thunder=§6Вие§c {0} §6буря във вашия свят.
thunderDuration=§6Вие§c {0} §6буря във вашия свят за§c {1} §6секунди.
timeBeforeHeal=§4Време преди следващото изцеление\:§c {0}§6.
timeBeforeTeleport=§4Време преди следващата ви телепортация\:§c {0}§6.
timeFormat=§c{0}§6 или §c{1}§6 или §c{2}§6
timeSetPermission=§4Нямате право да задавате часа.
timeSetWorldPermission=§4Нямате правото да задавате часа в света ''{0}''.
timeWorldCurrent=§6Часовото време в§c {0} §6е §c{1}§6.
timeWorldSet=§6Часовото време беше зададено на§c {0} §6в\: §c{1}§6.
totalSellableAll=§aОбщата сума на всички предмети и блокове, които могат да се продадат, е §c{1}§a.
totalSellableBlocks=§aОбщата сума на всички блокчета, които могат да се продадат, е §c{1}§a.
totalWorthAll=§aПродадохте всички предмети и блокчета за общо §c{1}§a.
totalWorthBlocks=§aПродадохте всички блокчета за общо §c{1}§a.
tps=§6Текущ TPS \= {0}
tradeSignEmpty=§4Тази търговска табела няма нищо налично за вас.
tradeSignEmptyOwner=§4Няма нищо за събиране от тази търговска табела.
treeFailure=§4Провал при създаване на дърво. Опитайте върху пръст или трева.
treeSpawned=§6Създадено е дърво.
true=§aда§r
typeTpacancel=§6За да отмените, напишете §c/tpacancel§6.
typeTpaccept=§6За да се телепортирате, напишете §c/tpaccept§6.
typeTpdeny=§6За да откажете, напишете §c/tpdeny§6.
typeWorldName=§6Можете също да напишете името на определен свят.
unableToSpawnItem=§4Не можете да размножите §c{0}§4; това не е предмет, който може да се размножи.
unableToSpawnMob=§4Неуспех при създаването на същество.
unignorePlayer=§6Спряхте да игнорирате играч§c {0} §6.
unknownItemId=§4Неизвестен номер на предмет\:§r {0}§4.
unknownItemInList=§4Неизвестен предмет {0} в списък {1}.
unknownItemName=§4Неизвестно име на предмет\: {0}.
unlimitedItemPermission=§4Нямате право на безброй предмети§c {0}§4.
unlimitedItems=§6Безбройни предмети\:§r
unmutedPlayer=§6Играчът§c {0}§6 е отглушен.
unsafeTeleportDestination=§4Дестинацията е опасна и защитата след телепортиране е изключена.
unvanishedReload=§4Поради презареждане на сървъра сте отново видим.
upgradingFilesError=Грешка при подновяването на файловете.
uptime=§6Активно време\:§c {0}
userAFK=§7{0} §5е неактивен и може да не отговори.
userAFKWithMessage=§7{0} §5е неактивен и може да не отговори\: {1}
userdataMoveBackError=Грешка при преместването на userdata/{0}.tmp към userdata/{1}\!
userdataMoveError=Грешка при преместването на userdata/{0} към userdata/{1}.tmp\!
userDoesNotExist=§4Играчът§c {0} §4не съществува.
userIsAway=§7* {0} §7е неактивен.
userIsAwayWithMessage=§7* {0} §7е неактивен.
userIsNotAway=§7* {0} §7вече не е неактивен.
userJailed=§6Вие бяхте затворени\!
userUnknown=§4Внимание\: Играчът ''§c{0}§4'' никога не е влизал в сървъра.
usingTempFolderForTesting=Използване на временна папка за тестване\:
vanish=§6Невидимост за {0}§6\: {1}
vanished=§6Сега сте напълно невидим за нормалните играчи и скрит от командите в сървъра.
versionOutputVaultMissing=§4Vault не е инсталиран. Чатът и правата може да не работят.
versionOutputFine=§6{0} версия\: §a{1}
versionOutputWarn=§6{0} версия\: §a{1}
versionOutputUnsupported=§d{0} §6версия\: §d{1}
versionOutputUnsupportedPlugins=§6Имате §dнеподдържани плъгини§6\!
versionMismatch=§4Несъвпадение на версията\! Моля обновете {0} на същата версия.
versionMismatchAll=§4Несъвпадение на версията\! Моля обновете всички Essentials.jar файлове {0} на същата версия.
voiceSilenced=§6Вие бяхте заглушени\!
walking=вървене
warpDeleteError=§4Проблем при изтриването на файла на уарпа.
warpingTo=§6Телепортиране до§c {0}§6.
warpList={0}
warpListPermission=§4Нямате достъп до списъкът с уарпове.
warpNotExist=§4Този уарп не съществува.
warpOverwrite=§4Не можете да презапишете този уарп.
warps=§6Уарпове\:§r {0}
warpsCount=§6Има§c {0} §6уарпа. Показване на страница §c{1} §6от §c{2}§6.
warpSet=§6Уарп§c {0} §6е създаден.
warpUsePermission=§4Нямате право да използвате този уарп.
weatherInvalidWorld=Свят наречен {0} не е открит\!
weatherStorm=§6Зададохте времето на §cбурно§6 в§c {0}§6.
weatherSun=§6Зададохте времето на §cслънчево§6 в§c {0}§6.
weatherSunFor=§6Зададохте времето на §cслънчево§6 в§c {0}§6за {1} секунди.
west=З
whoisAFK=§6 - Неактивен/на\:§r {0}
whoisAFKSince=§6 - Неактивен/на\:§r {0} (От {1})
whoisBanned=§6 - Ограничен/а\:§r {0}
whoisExp=§6 - Опит\:§r {0} (Ниво {1})
whoisFly=§6 - Летателен режим\:§r {0} ({1})
whoisGamemode=§6 - Режим на неуязвимост\:§r {0}
whoisGeoLocation=§6 - Локация\:§r {0}
whoisGod=§6 - Неуязвим\:§r {0}
whoisHealth=§6 - Живот\:§r {0}/20
whoisHunger=§6 - Глад\:§r {0}/20 (+{1} наситеност)
whoisIPAddress=§6 - IP Адрес\:§r {0}
whoisJail=§6 - Затворен/а\:§r {0}
whoisLocation=§6 - Локация\:§r ({0}, {1}, {2}, {3})
whoisMoney=§6 - Пари\:§r {0}
whoisMuted=§6 - Заглушен/а\:§r {0}
whoisMutedReason=§6 - Заглушен/а\:§r {0} §6Причина\: §c{1}
whoisNick=§6 - Прякор\:§r {0}
whoisOp=§6 - Оператор\:§r {0}
whoisPlaytime=§6 - Играно време\:§r {0}
whoisTempBanned=§6 - Забраната изтича след\:§r {0}
whoisTop=§6 \=\=\=\=\=\= Кой е\:§c {0} §6\=\=\=\=\=\=
whoisUuid=§6 - UUID\:§r {0}
worth=§aСтак от {0} струва §c{1}§a ({2} предмет(а) по {3} всеки)
worthMeta=§aСтак от {0} с метаданни на {1} струва §c{2}§a ({3} предмет(а) по {4} всеки)
worthSet=§6Цената е зададена
year=година
years=години
youAreHealed=§6Вие бяхте излекувани.
youHaveNewMail=§6Имате§c {0} §6съобщения\! Напишете §c/mail read§6, за да прегледате пощата си.
+221
View File
@@ -0,0 +1,221 @@
#X-Generator: crowdin.net
#version: ${full.version}
# Single quotes have to be doubled: ''
# by:
addedToAccount=§a{0} je dodano na vas racun.
addedToOthersAccount=dodan §a {0} {1} §a račun. Novo ravnotežu\: {2}
adventure=pustolovina
alertBroke=slomio\:
alertFormat=§3[{0}] §r {1} §6 {2} u\: {3}
alertPlaced=postavljen\:
alertUsed=upotrebljen\:
antiBuildBreak=§7Nemas dozvolu da unistavas§3 {0} §7blokove ovdje.
antiBuildCraft=§7Nemas dozvolu da stvoris§3 {0}§7.
antiBuildDrop=§4Nemate pravo da padne§c {0}§4.
antiBuildInteract=§4Nemate pravo da za interakciju sa §c {0}§4.
antiBuildPlace=§4Nemate pravo da postavi§c {0} §4ovde.
antiBuildUse=§4Nemate pravo da koriste§c {0}§4.
autoAfkKickReason=Izbaceni ste za prazan hod vise od {0} minuta.
backupDisabled=§7Jedna vanjska sigurnosna kopija nije konfigurirana.
backupFinished=§7Backup je zavrsen.
backupStarted=§7Backup je zapoceo.
backUsageMsg=§7Vracanje na prethodnu lokaciju.
balance=§aStanje na racunu\:§c {0}
balanceOther=§aStanje na racunu od {0}§a\:§c {1}
balanceTop=§6Top stanje na racunu ({0})
banExempt=§4Nemozes banati tog igraca.
banFormat=§cBanovani ste sa servera\!\!\nNe poksuavajte praviti nove acconte, inace nikada necete dobiti unban\nRazlog\:\n§r{0}
bed=§oKrevet§r
bedMissing=§4Tvoj krevet nije postavljen, nedostaje ili je blokiran.
bedSet=§6Krevet je postavljen\!
bigTreeFailure=§4Generacija velikog stabla neuspjela. Pokušaj ponovo na travi ili zemlji.
bigTreeSuccess=§6Veliko stablo stvoreno.
bookAuthorSet=§6Author knjige postavljen na {0}.
bookLocked=§6Ova knjiga je sada zakljucana.
bookTitleSet=§6Naslov knjige postavljen na {0}.
burnMsg=§6Zapaslio si §c {0} §6na§c {1} sekundi§6.
cannotStackMob=Nemas dozvolu.
canTalkAgain=§6Sada opet mozes razgovarati.
cantFindGeoIpDB=Nije moguce pronaci GeoIP\!
cantReadGeoIpDB=Nije uspjeo citanje GeoIP\!
cantSpawnItem=Nemas dozvolu za stvaranje §c {0}.
cleaned=Baza igraca ociescena.
cleaning=Ciscenje baze igraca.
commandFailed=Naredba {0} nije uspjela\:
commandHelpFailedForPlugin=Pogreska pri dobivanju pomoći za plugin\: {0}
commandNotLoaded=Komanda {0} je uspjesno ucitana.
configFileMoveError=Premjestiti config.yml na mjesto sigurnosne kopije nije uspjelo.
configFileRenameError=Nije prava mjesavina varalica preminenovati u confiog.ym.
connectionFailed=Neuspjesno povezivanje.
defaultBanReason=Banan si sa servera\!
deleteFileError=Nije moguce obrisati dokument\: {0}
deleteHome=Kuca {0} je obrisana.
deleteJail=Jail {0} je uklonjen.
deleteWarp=Warp {0} je obrisan.
deniedAccessCommand=§c{0} §4je bio zabranjen pristup naredbi.
denyBookEdit=§4Ti ne mozes otkljucati ovu knjigu.
denyChangeAuthor=§4Ti ne mozes promijeniti autora ove knjige.
denyChangeTitle=§4Ti ne mozes promijeniti naslov ove knjige.
depthAboveSea=§Vi ste§c {0} §6blokova iznad nadmorske visine.
depthBelowSea=§6Vi ste§c {0} §6blok(ova) ispod razine mora.
fireworkColor=&7Nepoznat vartromet morate prvo staviti boju.
fireworkEffectsCleared=§6Uklonjeni su svi efekti iz itema u ruci.
flyMode=&7Letenje je &3{0} &7za &3{1}&7.
foreverAlone=§4Nemate nikoga kome možete odgovoriti.
fullStack=§4Vec imas puni stack.
gameMode=&6Postavjen gamemode &c {0} &6za &c{1}&6.
gcfree=§6Slobodno memorije\: §c {0} MB.
gcmax=§6Max memorije\: §c {0} MB.
gctotal=&7Memorija\: &3{0} &7MB.
geoipJoinFormat=&7Igrac &3{0} &7dolazi iz &3{1}&7.
geoIpUrlEmpty=GeoIP preuzimanje datoteka Url adresa je prazna.
geoIpUrlInvalid=GeoIP preuzimanje url nije valjan.
godDisabledFor=§ciskljucen§6 za§c {0}
godEnabledFor=§aukljuceno§6 za§c {0}
godMode=&7GodMode &3{0}&7.
groupDoesNotExist=§4Nitko nije online u ovoj grupi\!
groupNumber=§c{0}§f online, za cijeli popis\: §c /{1} {2}
hatArmor=§4Ne mozete koristiti ovaj item kao sesir\!
hatEmpty=§4Trenutno ne nosis kapu.
hatFail=§4Moras nesto nositi u ruci.
hatPlaced=§6Uzivaj sa novom kapom\!
hatRemoved=§6Vasa kapa je uklonjena.
haveBeenReleased=&7Pusten si&7.
heal=&7Izljecen si.
healDead=&7Nemozes izljeciti nekoga tko je mrtav\!
healOther=&7Izljecio si &3{0}&7.
helpFrom=&7Komande od &3{0}&7\:
helpMatching=&7Komande odgovarajuci "&3{0}&3"&7\:
helpOp=&8[&3PomocOP&8] &3{0}&7\: &7{1}&7
helpPlugin=§4{0}§r\: Plugin pomoc\: /help {1}
holdBook=§4Nedrzis knjigu u kojoj se moze pisati.
holdFirework=§4Moras drzati vatromet za dodavanje efekata.
holdPotion=§4Moras drzati napitak da bi primjenio efekte.
holeInFloor=§4Rupa u podu\!
homes=&6Kuce\:&r {0}
homeSet=§6Home postavljen na trenutnu lokaciju.
hour=sat sati\nhour hours
ignoredList=§6Ignoriran\:§r {0}
ignorePlayer=§6Ignoriras igraca§c {0} §6od sad.
illegalDate=Ilegalan oblik datuma.
infoChapter=§6Odaberi poglavlje\:
infoChapterPages=§e ---- §6{0} §e--§6 Stranica §c{1}§6 od §c{2} §e----
infoPages=§e ---- §6{2} §e--§6 Stranica §c{0}§6/§c{1} §e----
infoUnknownChapter=§4Nepoznato poglavlje.
inventoryClearingAllArmor=&7Ocistcene sve inventori stvari i oklop od &3{0}&7.
inventoryClearingFromAll=§6Ciscenje inventorija svih igraca...
isIpBanned=&7IP &3{0} &7je banovan.
kitOnce=Ne mozes ponovo koristiti taj kit.
kitReceive=§6Dobio si kit§c {0}§6.
kits=§6Kitovi\:§r {0}
kitTimed=§4Ti ne mozes koristiti taj kit ponovno za jos§c {0}§4.
listAmount=§6Online su §c{0}§6 od maksimalno §c{1}§6 igraca online.
loadWarpError=&3Greska&7, nemozemo ucitati warp {0}.
mailCleared=&7Email je obrisan\!
mailSent=&7Email je poslan\!
markMailAsRead=&7Ako zelis staviti da si procito email, napisi &3 /mail clear &7.
matchingIPAddress=&7Sljedeci igraci ranije prijavljeni s te IP adrese\:
maxHomes=§4Ti ne mozes postaviti vise od§c {0} §4kuca.
missingItems=§4Ti nemas §c{0}x {1}§4.
mobSpawnError=&7Greska u promjenjivanju spawnera.
mobSpawnLimit=&7Mob kolicina je ogranicena na ovom serveru.
mobSpawnTarget=&7Moras gledati u spawner da ga pretvoris u drugi spawner.
moneySentTo=§a{0} je poslano do {1}.
moreThanZero=&7Quantities mora biti veci od 0.
multiplePotionEffects=&7Nije moguce primjeniti vise efekta ovaj napitak.
mutedPlayer=&7Igrac &3{0} &7muted.
mutedPlayerFor=&7Igrac&3 {0} &7je mutovan za &3{1}&7.
muteExempt=&7Nemozes mute ovog igraca.
muteNotify=&3{0} &7je mutovao igraca &3{1}&7.
nearbyPlayers=&7Igraci u blizini\: &3{0}
negativeBalanceError=&7Igrac nesmije imati negativne novce.
nickChanged=&7Ime je promjenjeno.
nickDisplayName=&7Moras promjeniti displayname u Essentials config.
nickInUse=&7Ovo ime vec postoji.
nickNamesAlpha=&7Ime mora imati slova iz abecede.
nickNoMore=&7Nemas vise ime.
noKitGroup=§4Nemas pristup ovome kitu.
nuke=&7Bombe ce poceti padat.
onlyDayNight=/Time samo podržava dan/noć.
onlyPlayers=§4Samo igrači u igri mogu koristiti §c{0}§4.
onlyPlayerSkulls=Možeš postaviti samo igračevu lubanju (§c397\:3§4).
orderBalances=&7Ucitavamo stanja novaca &3{0} &figraca, molimo pricekajte...
oversizedTempban=&7Nemozes banovati igraca na to vrijeme.
pendingTeleportCancelled=&7Ponistio si teleport zahtijev.
playerBanIpAddress=&7Igrac &3{0} &7je banovao IP Adresu &3{1} &7za\: &3{2}&7.
playerBanned=&7Igrac &3{0} &7je banovao &3{1} &7, razlog\: &3{2}&7.
playerJailed=§6Igrac§c {0} §6zatvoren.
playerMuted=§6Mutan si\!
playerNeverOnServer=&7Igrac &3{0} &7nikad nije bio na ovom serveru.
playerNotFound=§4Igrac nije pronađen.
playerUnmuted=§6Unmutan si.
possibleWorlds=§6Moguci svjetovi su brojevi §c0§6 kroz §c{0}§6.
powerToolAir=§4Command ne može biti prilozen zraku.
powerToolAlreadySet=§4Command §c{0}§4 vec je dodijeljena §c{1}§4.
powerToolClearAll=&7Sve moci sa te stvari su izbrisane.
powerToolList=§6Item §c{1} §6ima sljedece naredbe\: §c{0}§6.
pTimeCurrent=&3{0}&7 vrijeme je &3{1}&7.
pTimeCurrentFixed=&3{0}&7vrijeme je popravljeno u &3{1}&7.
pTimeNormal=&3{0}&7 vrijeme je normalno i odgovara na server.
pTimePlayers=&7Ovi igraci imaju svoje vrijeme\: &r
pTimeReset=&7Igracevo vrijeme je vraceno na\: &3{0}
pTimeSet=&7Igracevo vrijeme je stavljeno na &3{0}&7 za\: &3{1}&7.
pTimeSetFixed=&7Igracevo vrijeme je popravljeno na &3{0}&7 za\: &3{1}&7.
pWeatherCurrent=&3{0}&7 vrijeme je &3{1}&7.
pWeatherInvalidAlias=&7Greska, nemozemo naci ovakav nacin vremena
pWeatherNormal=&3{0}&7 vrijeme je normalno i odgovara na server.
pWeatherPlayers=&7Ovi igraci imaju svoje vrijeme\: &r
pWeatherReset=&7Igracevo vrijeme je vraceno na\: &3{0}
pWeatherSet=&7Igracevo vrijeme je stavljeno na &3{0}&7 za\: &3{1}&7.
serverTotal=&7Server ukupno\: &3{0}
setBal=&7Tvoj novac je postavljen na &3{0}.
setBalOthers=&7Stavio si &3{0} &7novce za &3{1}&7.
setSpawner=§6Promijenjen spawner tip to§c {0}§6.
signProtectInvalidLocation=§4Nemas dozvolu da postavis sign ovdje.
similarWarpExist=§4Warp sa slicnim imenom vec postoji.
spawnSet=&7Spawn je postavljen na grupu &3 {0}&7.
suicideSuccess=&7Igrac &3{0} &7je ubio sam sebe.
teleportAAll=&7Teleport zahtjev je poslan svim igracima...
teleportAll=&7Teleportiram sve igrace...
teleportationCommencing=&7Teleporitanje dolazi...
teleportationDisabled=&7Teleportacija &3iskljucena&7.
teleportationDisabledFor=&7Teleportacija &3iskljucena&7 za &3{0}&7.
teleportationEnabled=&7Teleportacija je &3ukljucena&7.
teleportationEnabledFor=&7Teleportacija je &3ukljucena&7 za &3{0}&7.
teleportAtoB=&3{0}&7 teleporan si do &3{1}&7.
teleportDisabled=&3{0} &7ima teleportaciju iskljucenu.
teleportHereRequest=&3{0}&7 ti je poslao zahtjev da se teleportiras do njega.
teleporting=§6Teleportiranje...
teleportNewPlayerError=&7Greska u teleportiranju novog igraca\!
teleportRequest=&3{0}&7 vam je poslao zahtjev da se teleportira do tebe.
teleportRequestTimeoutInfo=&7Ovaj zahtjev ce zavrsiti nakon &3{0} &7sekundi.
teleportTop=&7Teleporitanje na vrh.
teleportToPlayer=§6Teleportiranje do §c{0}§6.
tempbanExempt=&7Nemozes privremeno banovati ovu osobu.
timeBeforeHeal=&7Vrijeme prije novog ljecenja\:&3{0}&7.
timeBeforeTeleport=&7Vrijeme nakon nove teleportacije\: &3{0}&7.
timeFormat=&3{0}&7 ili &3{1} &7 ili &3{2}&7
timeWorldCurrent=&7Trenutno vrijeme u &3{0} &7je &3{1}&7.
timeWorldSet=&7Vrijeme je postavljeno sa &3{0}&7u\: &3{1}&7.
warpingTo=&7Warpas se do &3{0}&7.
warpListPermission=&7Nemas dozvolu da vidis listu warpova.
warpNotExist=&7Ovaj warp ne postoji.
warpOverwrite=&7Nemozes prepisati taj warp.
warps=&7Warpovi\:&3 {0}
warpsCount=&7Ovdje su &3{0} &7warpovi. Rezultati stranica &3{1} &7od &3{2}&7.
warpSet=&7Warp &3{0} &7je postavljen.
warpUsePermission=&7Nemas dozvolu za koristenje ovog warpa.
weatherStorm=&7Stavio si vrijeme od &3oluje &7u &3{0}&7.
weatherSun=&7Stavio si vrijeme od &3sunca &7u &3{0}&7.
whoisBanned=§6 - Banovan\: §r {0}
whoisFly=&7 - Nacin letenja\:&3 {0} ({1})
whoisGeoLocation=&7Lokacija\: &3 {0}
whoisHealth=&7 - Zdravlje\: &3 {0}/20
whoisHunger=&7 - glad\: &3 {0}/20 (+{1} Zasicenje)
whoisIPAddress=&7 - IP Adresa\: &3 {0}
whoisMoney=&7 - Novac\: &3 {0}
whoisMuted=&7 - Mutovan\:&3 {0}
worth=§aStack {0} vrijednosti §c{1}§a ({2} stavke u {3} svaki)
worthSet=§6Vrijednost je stavljena
youAreHealed=§6Izlječen si.
youHaveNewMail=§6Imaš§c {0} §6poruka\! Kucaj §c/mail read§6 da vidiš poštu.
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+177
View File
@@ -0,0 +1,177 @@
#X-Generator: crowdin.net
#version: ${full.version}
# Single quotes have to be doubled: ''
# by:
addedToAccount=§a {0} έχει προστεθεί στο λογαριασμό σας.
addedToOthersAccount=§a {0} προστέθηκαν στον {1}§a λογαριασμό. Νέα ισορροπία\: {2}
adventure=περιπέτεια
alertBroke=έσπασε\:
alertFormat=§3 [{0}] §r {1} §6 {2} στο\: {3}
alertPlaced=τοποθετούνται\:
alertUsed=χρησιμοποιούνται\:
antiBuildBreak=§4Δεν επιτρέπεται να σπάσεις§c {0} §4blocks εδώ.
antiBuildCraft=§4Δεν επιτρέπεται να δημιουργήσετε§c {0}§4.
antiBuildDrop=§4Δεν σου επιτρέπεται να ρίξεις§c {0}§4.
antiBuildInteract=§4Δεν σου επιτρέπεται να αλληλεπιδράσεις με§c {0}§4.
antiBuildPlace=§4Δεν σου επιτρέπεται να τοποθετήσεις§c {0} §4εδώ.
antiBuildUse=§4Δεν σου επιτρέπεται να χρησιμοποιήσεις§c {0}§4.
autoAfkKickReason=Σας έδιωξαν επειδή μείνατε ανενεργοί για περισσότερο από {0} λεπτά.
backupDisabled=§4Δεν έχει ρυθμιστεί κάποιο εξωτερικό script δημιουργίας αντιγράφων ασφαλείας.
backupFinished=§6Η δημιουργία αντίγραφου ασφαλείας ολοκληρώθηκε.
backupStarted=§6Η δημιουργία αντίγραφου ασφαλείας ξεκίνησε.
backUsageMsg=§6Επιστροφή στην προηγούμενη τοποθεσία.
balance=§aΥπόλοιπο\:§c {0}
balanceOther=§aΙσοζύγιο {0}§a\:§c {1}
balanceTop=§6Top υπόλοιπα ({0})
banExempt=§4Μπορείτε δεν μπορεί να απαγορεύσει αυτού του παίκτη.
banFormat=§4Έχεις Αποκλειστεί\:\n§r{0}
bed=§oκρεβάτι§r
bedMissing=§4Το κρεβάτι σας είναι είτε απενεργοποιημένο, που λείπουν ή μπλοκαριστεί.
bedNull=§mκρεβάτι§r
bedSet=§6Κρεβάτι που αναπαράγονται\!
bigTreeFailure=§4Μεγάλη αποτυχία γενιά δέντρο. Προσπαθήστε ξανά με χόρτο ή χώμα.
bigTreeSuccess=§6Μεγάλο δέντρο εμφανίστηκε.
blockList=§6Essentials αναμεταδίδονται τις ακόλουθες εντολές σε ένα άλλο plugin\:
bookAuthorSet=§6Συγγραφέας του βιβλίου που να {0}.
bookLocked=§6Αυτό το βιβλίο είναι τώρα κλειδωμένη.
bookTitleSet=§6Τίτλος του βιβλίου που να {0}.
burnMsg=Κάψατε τον {0} για {1} δευτερόλεπτα
cannotStackMob=§4Δεν έχεις άδεια να στοιβάξεις πολλά ζώα.
canTalkAgain=§6Μπορείς να μιλήσεις πάλι.
cantFindGeoIpDB=Δεν βρέθηκε η βάση δεδομένων GeoIP\!
cantReadGeoIpDB=Απέτυχε η ανάγνωση της βάσης δεδομένων GeoIP\!
cantSpawnItem=§4Δεν επιτρέπεται να εμφανίσετε τα αντικείμενα§c {0}§4.
chatTypeSpy=[Κρυφό]
cleaned=Τα Userfiles διαγράφτηκαν.
cleaning=Διαγραφή των userfiles.
commandFailed=Απέτυχε η εντολή {0}\:
commandHelpFailedForPlugin=Σφάλμα κατά τη λήψη βοήθειας για την προέκταση\: {0}
commandNotLoaded=Η εντολή {0} δεν φόρτωσε σωστά
configFileMoveError=Απέτυχε να μετακινήσετε το config.yml στη θέση του αντιγράφου ασφαλείας.
connectedPlayers=§6σύνδεμένοι παίκτες§r
connectionFailed=Απέτυχε το άνοιγμα της σύνδεσης.
cooldownWithMessage=§4Χρονοκαθυστέρηση\: {0}
couldNotFindTemplate=§4δεν βρέθηκε πρότυπο {0}
creatingConfigFromTemplate=δημιουργείτε config από το πρότυπο\: {0}
creatingEmptyConfig=Δημιουργείτε κενό config\: {0}
creative=δημιουργικό
currentWorld=§6Τρέχον Κόσμος\:§c {0}
day=ημέρα
days=ημέρες
defaultBanReason=Το σφυρί της απαγόρευσης μίλησε\!
deleteFileError=Δεν είναι δυνατή η διαγραφή αρχείου\: {0}
deleteHome=§6Το σπίτι§c {0} §6έχει αφαιρεθεί.
deleteJail=§6η φυλακή§c {0} §6έχει αφαιρεθεί.
deleteWarp=§6η περιοχή§c {0} §6έχει αφαιρεθεί.
deniedAccessCommand=§c{0} §4Δεν έχεις πρόσβαση στην εντολή.
denyBookEdit=§4δεν μπορείς να ξεκλειδώσεις αυτό το βιβλίο.
denyChangeAuthor=§4δεν μπορείς να αλλάξεις τον συγγραφέα αυτού του βιβλίου.
denyChangeTitle=§4Δεν μπορείς να αλλάξεις τον τίτλο αυτού του βιβλίου.
depth=§6είσαι στο επίπεδο της θάλασσας.
depthAboveSea=§6Είσαι§c {0} §6κύβο/κύβους επάνω από τη στάθμη της θάλασσας.
depthBelowSea=§6Βρίσκεσαι §c{0} §6block(s) κάτω από την επιφάνεια της θάλασσας.
destinationNotSet=Προορισμός δεν ορίστηκε\!
disabled=απενεργοποιημένο
distance=§6Απόσταση\: {0}
dontMoveMessage=§6Η Μεταφορά θα αρχίσει σε§c {0}§6. Μην κουνηθείς.
durability=§6Αυτό το εργαλείο έχει §ψ{0} §6χρήσεις ακόμα.
enabled=ενεργοποιημένο
enchantmentNotFound=§4Δεν υπάρχει αυτή η μαγεία\!
enchantmentPerm=§4Δεν έχεις δικαιώματα για§c {0}§4.
enchantmentRemoved=§6Η μαγεία§c {0} §6έχει αφαιρεθεί από το αντικείμενο που κρατάς στο χέρι σου.
enchantments=§6Μαγείες\:§r {0}
errorCallingCommand=Σφάλμα στην εντολή /{0}
errorWithMessage=§cΣφάλμα\:§4 {0}
essentialsHelp1=Το αρχείο είναι χαλασμένο και το Essentials δεν μπορεί να το ανοίξει. Το Essentials είναι ποια κλειστό. Εαν δεν μπορείς να το φτιάξεις μόνος σου, πήγαινε στο http\://tiny.cc/EssentialsChat
essentialsHelp2=Το αρχείο είναι σπασμένο και το Essentials δεν μπορεί να το ανοίξει. Το Essentials είναι τώρα απενεργοποιημένο. Εάν δεν μπορείτε να διορθώσετε το αρχείο σας, πληκτρολογήστε /essentialshelp στο παιχνίδι ή πηγαίνετε στο http\://tiny.cc/EssentialsChat
essentialsReload=§6Το Essentials ανανεωθηκε§c {0}.
failedToCloseConfig=Απέτυχε να κλείσει το config {0}.
failedToCreateConfig=Απέτυχε η δημιουργία του config {0}.
failedToWriteConfig=Απέτυχε να γράψει το config {0}.
flying=πετάει
gcfree=§6Ελεύθερη μνήμη\:§c {0} MB.
godDisabledFor=§cαπενεργοποιημένο§6 for§c {0}
godEnabledFor=§aενεργοποιημένο§6 for§c {0}
hatPlaced=§6Απόλαυσε το καινούργιο σου καπέλο\!
hatRemoved=§6Το καπέλο σου αφαιρέθηκε.
heal=§6Έχεις θεραπευθεί.
healOther=§6θεραπεύτηκε§c {0}§6.
helpFrom=Εντολή απο {0}\:
helpMatching=§6Εντολές που ταιριάζουν "§c{0}§6"\:
helpPlugin={0} Βοήθεια Επέκτασης\: /help {1}
holdBook=Δεν κρατάς ενα βιβλίο μονο για ανάγνωση.
holdFirework=Εσυ πρέπει να κρατάς ένα πυροτέχνημα για να προσθέσετε εφέ.
holdPotion=Εσύ πρέπει να κρατάς ένα φίλτρο για να εφαρμόσετε εφέ σε αυτό.
holeInFloor=Τρύπα στο πάτωμα\!
homes=§6Σπίτια\:§r {0}
homeSet=Το σπίτι ορίστεικε στην τρέχουσα θέση.
hour=ώρα
hours=ώρες
ignoredList=Αγνοείται\: {0}
ignorePlayer=Εσυ αγνοείς player§c {0} §6απο τώρα στο.
illegalDate=Μορφή παράνομης ημερομηνίας.
infoChapter=Επιλέξτε κεφάλαιο\:
infoChapterPages=§e---§6{0} §e--§6 Σελίδα §c{1}§6 του §c{2} §e---
infoPages=§e---§6{2} §e--Σελίδα §6 §c{0}§6/§c{1} §e---
infoUnknownChapter=§4Άγνωστο κεφάλαιο.
insufficientFunds=§4Aνεπαρκής διαθέσιμων κεφαλαίων.
invalidCharge=§4Άκυρη χρέωση.
invalidFireworkFormat=§4Η §c{0} επιλογή δεν είναι μια έγκυρη τιμή για το §c{1}§4.
invalidHome=§4Το σπίτι§c {0} §4δεν υπάρχει\!
invalidHomeName=§4Μη έγκυρο όνομα στο σπίτι\!
invalidMob=Άκυρος τύπος mob.
invalidNumber=Μη έγκυρος αριθμός.
invalidPotion=§4Άκυρο φίλτρο.
invalidSignLine=§4Η σειρά§c {0} §4στην πινακίδα δεν είναι έγκυρη.
invalidWarpName=Μη έγκυρο όνομα περιοχής\!
invalidWorld=§4Μη έγκυρος κόσμος\!
is=είναι
itemCannotBeSold=Το στοιχείο §4αυτο δεν μπορεί να πωληθεί στον server.
itemMustBeStacked=§4Το αντικειμενο πρέπει να είναι σε στοίβες για να μπορεί να γίνει ανταλλαγή. Ποσότητα 2s θα ήταν δύο στοίβες, κλπ.
itemNames=Σύντομη ονόματα\: §r {0} §6Αντικειμενο
itemNotEnough1=§4Δεν έχεις αρκετά από αυτό το στοιχείο για να το πουλήσεις.
itemSellAir=Καλά προσπάθησες πραγματικά να πωλήσεις αέρα; Βάλτε ένα στοιχείο στο χέρι σας.
itemSold=§aΠουλήθηκε για §c{0} §α ({1} {2} στο {3} κάθε).
jailNotExist=§4Αυτή η φυλακή δεν υπάρχει.
jailReleased=§6Παίχτης §c{0}§6 αποφυλακίστηκε.
jailReleasedPlayerNotify=§6Έχεις απελευθερωθεί\!
jailSentenceExtended=§6Οχρόνος φυλάκισης επεκτάθηκε σε §c{0}§6.
jailSet=§6Η φυλακή§c {0} §6 έχει καθοριστεί.
kickDefault=Διώχθηκε από το διακομιστή.
kickedAll=§4Διώχθηκαν όλοι οι παίκτες απ τον διακοσμητή.
kickExempt=§4Δεν μπορείς να kick αυτό το άτομο.
kill=§6Σκοτώθηκε§c {0}§6.
kitInvFull=§4Το inventory σου είναι γεμάτο, το kit έπεσε στο πάτωμα.
kitNotFound=§4Δεν υπάρχει αυτό το kit.
kitOnce=§4Δεν μπορείς να ξανά πάρεις αυτό το kit ξανά.
kitReceive=§6Πήρες το kit§c {0}§6.
kitTimed=§4Δεν μπορείς να ξανά χρησιμοποιήσεις αυτό το kit μέχρι§c {0}§4.
me=εγώ
minute=λεπτό
minutes=λεπτά
month=μήνας
months=μήνες
nickChanged=§6Το Ψευδώνυμο άλλαξε.
nickInUse=§4Αυτό όνομα είναι ήδη σε χρήση.
noKitPermission=§4Χρειάζεσαι την §c{0}§4 άδεια για να χρησιμοποιήσεις αυτό το kit.
noKits=§6Δεν υπάρχουν διαθέσιμα kits.
noNewMail=§6Δεν έχεις νέα αλληλογραφία.
now=τώρα
recipeNothing=τίποτα
second=δευτερόλεπτο
seconds=δευτερόλεπτα
serverFull=Ο διακομιστής είναι πλήρης\!
survival=επιβίωση
teleportationCommencing=§6Η τηλεμεταφορά αρχίζει...
teleporting=§6Τηλεμεταφορά...
teleportTop=Τηλεμεταφορά στην κορυφή.
walking=περπάτημα
warps=§6Περιοχές\:§r {0}
warpSet=§6Περιοχή§c {0} §6Καθορίστηκε.
whoisBanned=§6 - Αποκλεισμένος\:§r {0}
whoisJail=§6 - Φυλακή\: §r {0}
whoisLocation=§6 - Τοποθεσία\: §r ({0}, {1}, {2}, {3})
whoisMoney=§6 - {0} χρήματα\: §r
year=έτος
years=έτη
youAreHealed=§6Έχεις θεραπευθεί.
Loaded 100 of 214 files, more files were not shown because too many files have changed in this diff. Show more