Compare commits

..
2001 Commits
Author SHA1 Message Date
JRoy a6edf04a60 Release 2.18.2 2020-11-16 11:32:40 +00:00
Josh Roy 3ba675a899 Allow users to modify existing homes when over homes limit (#3776)
Fixes #3761
2020-11-15 17:40:34 +00:00
pop4959 1fed7a9a3a Fix tab completion for delhome (#3775)
There was a minor issue with one line of code in delhome which was causing the user's homes not to be listed since the condition was effectively reversed. This was also causing an NPE for console senders attempting to tab complete.

Fixes #3774
2020-11-14 22:50:48 +00:00
80fb91b6d7 Fix /clear <player> <item> not clearing offhand (#3715)
Co-authored-by: Kenichycmd <kenichycmd@gmail.com>
Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com>
2020-11-09 16:43:55 +00:00
Josh Roy 5b0c2a4131 Use ray-tracing based target block for 1.13.2+ (#3763)
Uses new method of ray-tracing to target block instead of using BlockIterator which doesn't respect the player looking at a different y-level. Falls back to old BlockIterator method on server versions older than 1.13.2

Fixes #3756.
2020-11-09 16:38:02 +00:00
Josh Roy bb43e8f7b6 Add option to prevent replying from vanished players (#3703)
Closes #2066
2020-11-09 12:25:16 +00:00
Josh Roy 4d9a10147a Split backup command by space (#3762)
Splits command sent to ProcessBuilder by spaces. Fixes backup commands with arguments

Fixes #3759
2020-11-09 08:52:35 +00:00
Josh Roy ea4f5cf919 Update to 1.16.4 (#3753) 2020-11-02 13:36:48 -08:00
dependabot[bot] 295bc9f76d Bump junit from 4.12 to 4.13.1 (#3726)
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-10-23 00:19:54 +01:00
MD 327806d9a1 Add new PR templates and revamp issue templates (#3711)
Adds new PR templates and revamps the existing issue templates to (hopefully) make the PR/issue submission easier to understand.
2020-10-23 00:19:04 +01:00
Josh Roy 80e7558fc0 Move some tab complete messages to debug mode only (#3739) 2020-10-22 12:15:02 -07:00
md678685 9cda59511e Consolidate permissions default setup into single class 2020-10-19 21:27:05 +01:00
md678685 c12a031918 Add more specific platform support messages 2020-10-19 21:26:38 +01:00
Alexander SöderbergandMD a4f580e319 Make HelpInput use the known command map (#3675)
Co-authored-by: MD <1917406+md678685@users.noreply.github.com>

This PR makes HelpInput use knownCommands in the command map, rather than relying on plugin descriptions. This means that commands that have been registered programmatically (or impromptu) will be recognized and displayed in the help menu.

The ugly reflection is due to Spigot not exposing the command map getter. This has been tested on Spigot 1.8, 1.16.3 and Paper 1.16.3 with plugins that register commands directly to the command map.
2020-10-19 15:27:40 +01:00
md678685 583bf88207 Implement ConsoleCommandSender methods 2020-10-19 15:06:50 +01:00
montlikadani a5f8e83e03 Remove redundant checks in the tree command (#3716) 2020-10-13 00:47:12 -07:00
Alexander Söderberg e2f17f11d3 Tab-complete plugin names in /help (#3713)
Plugin names are accepted as input to `/essentials:help`, but they are not completed. This makes it easier to lookup plugin commands.
2020-10-07 11:54:30 -07:00
md678685 4f8c040d06 Add link to Register license notice 2020-10-05 17:34:55 +01:00
Josh Roy af1d068022 Add more inventory commands (#3704)
Add more commands to access virtual crafting inventories (on platforms with the required APIs).

Closes #3195 and #108.
2020-10-05 14:45:33 +01:00
Andre_601andMD 1bd8d1c85c Update old EssentialsX URLs in issue templates (#3678)
Co-authored-by: MD <1917406+md678685@users.noreply.github.com>

This updates the old essentialsx.github.io domains to the new essentialsx.net one.
2020-10-05 14:20:17 +01:00
pop4959 d7fc859d14 Use username instead of nickname in console /sell messages (#3693)
Closes #3662

This PR changes the default placeholder `{0}` to username. Display name can still be used with `{5}`.

Before change:
messages.properties
`itemSoldConsole=\u00a7e{0} \u00a7asold\u00a7e {1}\u00a7a for \u00a7e{2} \u00a7a({3} items at {4} each).`
console
`[Essentials] ~test sold dirt for $64 (64 items at $1 each).`

After change:
messages.properties
`itemSoldConsole=\u00a7e{0} \u00a7asold\u00a7e {1}\u00a7a for \u00a7e{2} \u00a7a({3} items at {4} each).`
console
`[Essentials] pop4959 sold dirt for $64 (64 items at $1 each).`

messages.properties
`itemSoldConsole=\u00a7e{5} \u00a7asold\u00a7e {1}\u00a7a for \u00a7e{2} \u00a7a({3} items at {4} each).`
console
`[Essentials] ~test sold dirt for $64 (64 items at $1 each).`
2020-10-05 09:50:56 +01:00
Ryan ac953cd114 Remove sign color codes from trade.log (#3699)
Started looking into #3116 but noticed this issue and wanted to fix it first.

Also added a comment as to why the username is truncated as this took me a long time to figure out and seemed arbitrary. Probably could truncate the username later for trade signs only as other signs don't require any username to be present on the sign. However, for now I simply opted to document.
2020-10-05 09:47:12 +01:00
md678685 6e6dd041d5 Add Javadocs to most API classes 2020-10-04 19:59:42 +01:00
md678685 9b3c8a9df2 Reformat and fix Checkstyle violations 2020-10-04 19:59:42 +01:00
md678685 234a481b0d Add Checkstyle rules and suppressions
This commit adds Checkstyle rules for EssentialsX, based on those from the adventure library (https://github.com/KyoriPowered/adventure/tree/master/.checkstyle).

It also makes Checkstyle passes mandatory for a GH build to pass.
2020-10-04 19:59:42 +01:00
pop4959 89b3c9233e Bump Paperlib version (#3695) 2020-10-03 12:29:43 -07:00
Josh Roy 5d61a43fe1 Add balanceTopLine i18n translation string (#3626) 2020-09-25 19:16:12 -07:00
Olivia 29d5ccf751 Fix /lightning ignoring essentials.lightning.others (#3671) 2020-09-13 17:23:50 -07:00
l1ttleO fde0665593 Update Readme to list 1.16.3 as a supported version (#3666) 2020-09-12 10:58:54 -07:00
l1ttleO 29541b0995 Bump supported server version to 1.16.3 (#3664) 2020-09-12 10:37:18 -07:00
Josh Roy 05f31c5ddf Fix time command throwing exceptions when used in console (#3622)
Fixes #3621
2020-09-09 16:00:13 +01:00
JRoy f89840545d Revert clearinventory command to pre-command-refactor
This command is too big to rewrite without a behavior change
2020-09-09 15:52:59 +01:00
JRoy 18534f8576 Fix inverted messages in Commandpaytoggle 2020-09-09 15:52:38 +01:00
JRoy 1382a05dc8 Fix IEssentials#getOnlineUsers ABI breakage 2020-09-09 15:52:37 +01:00
JRoy 1671d4839c Clean up some tab completes that I missed 2020-09-09 15:52:29 +01:00
Josh Roy 4d2fbd04c5 Fix /sell and /worth messages displaying {1} instead of the item(s) value (#3656) 2020-09-08 12:36:05 -07:00
md678685 dc6b9b89cd Handle funky bStats classloading correctly
Fixes bStats for plugins that do funky classloading things, like AntiVPN.
2020-08-29 20:37:20 +01:00
Josh Roy 76f36aa895 [CI-SKIP] Some issue template updates (#3623)
Co-authored-by: MD <1917406+md678685@users.noreply.github.com>

* Forces use of issue templates
* Auto-labels issue templates
* Links to discord in the issue-create matrix as a better form of troubleshooting
2020-08-29 17:21:22 +01:00
Josh Roy fa835e9c64 Fix tablist name getting reset after AFK status change (#3624)
Fixes #3606.
2020-08-29 16:03:49 +01:00
md678685 c8dc874a56 Release 2.18.1 2020-08-23 17:18:31 +01:00
Josh Roy b3a6307052 Fix miscellaneous command permission bugs (#3616)
Fixes #3612, in which `/list`'s tab complete previously revealed the presence of vanished players in certain groups, and fixes #3613 in which `/time set` did not properly check whether the player had permission to change the time.
2020-08-22 20:07:21 +01:00
pop4959 3ca0181b79 Update block damaging checks in teleportation safety (#3537)
This PR updates and improves LocationUtil#isBlockDamaging. Notably, the lava check is fixed (it was not working on older versions of Minecraft), many newer materials that were missing damage checks have been added, and the code is a bit cleaner. I've tested this code on MC 1.8 and 1.16 and everything should work correctly.
2020-08-22 18:37:15 +01:00
pop4959 98557dcecf Add world border checking to teleportation safety (#3536)
Fixes #3499. Please see that issue for discussion about the bug.

Fix demonstration with `/tppos`: https://imgur.com/a/Mo4okQa
2020-08-22 17:51:23 +01:00
MD 3351092c79 Add "amplifier" potion meta attribute (#3614)
Adds an `amplifier:<value>` potion meta attribute to MetaItemStack that applies a raw amplifier value, instead of translating inputs between 1 and 3 to match their vanilla names like `power:<value>` does. This matches the Mojang `/effect` command, which doesn't translate any potion effect amplifiers, and allows for creation of level IV potions (using `amplifier:3` instead of a `power` value) through EssentialsX without breaking existing usages of `power:<value>`.

More context for this commit can be found at https://github.com/EssentialsX/Essentials/pull/3592#issuecomment-678656107.

Closes #3592 and fixes #3589.
2020-08-22 17:40:40 +01:00
pop4959 68cd509d41 Fix /bigtree command on versions 1.12 and prior (#3569)
Fixes #3549.

Replaces the `Block#isPassable` check with `Material#isSolid`, which is compatible with all versions through 1.8 to 1.16.
2020-08-22 17:01:50 +01:00
xtomyserrax 5fa65b42ae Fix creeper player damage being cancelled incorrectly (#3604)
Previously, disabling creeper explosion block damage with the `protect.prevent.creeper-explosion` setting would also prevent players getting hurt. This fixes this, meaning servers can disable creeper block damage while still allowing players to take damage from creeper explosions.
2020-08-22 16:55:32 +01:00
Andre_601 bdae259a1d Update links in readme (#3596)
This PR updates several links:

- https://essentialsx.cf -> https://essentialsx.net
- Wiki links (Either github.io links or GitHub Wiki links) now point to their corresponding pages on the actual wiki (https://essentialsx.net/wiki/Home.html)
2020-08-22 16:49:50 +01:00
Jason fea86ea70e Add config note regarding displayname (#3535) 2020-08-22 14:15:24 +01:00
Josh Roy 1133770aeb Fix changing players' gamemodes from the console (#3590)
Fixes #3587 which was introduced by #3337.
2020-08-21 16:37:54 +01:00
MD 2c462106bc Fix blacklisted blocks being pulled by pistons (#3610)
Closes #3609.
2020-08-21 16:31:34 +01:00
triagonal bd1e624c91 clarify piston blacklist config comment 2020-08-21 23:00:56 +10:00
triagonal 6875fa4c7e fix blacklisted blocks being pulled by sticky piston 2020-08-21 23:00:18 +10:00
pop4959 def5f2155d Fix compilation issues on latest Spigot/Paper (#3607) 2020-08-20 19:24:42 +01:00
triagonal 73d2457fea Fix regression with teleportation commands where command cost gets charged twice (#3601) 2020-08-16 14:40:58 -07:00
MD bc52ca856e Update to 1.16.2 (#3586) 2020-08-11 23:12:41 +01:00
Flask Bot 18ccea320a Update items.json from generator
Note: this action was performed by a human (@md678685) under the
Flask-Bot account.
2020-08-11 23:06:07 +01:00
Josh Roy f6cb9ff470 Improve command codestyle (#3337)
Co-authored-by: MD <1917406+md678685@users.noreply.github.com>

Fixes #3579 (async `/skull` command)
Fixes #3336 (improve codestyle of commands)
Partially addresses #3339 (`/spawn` and `/setspawn` are now hidden from tabcomplete)
Closes #3087 (`/paytoggle` is now a loop command)
2020-08-11 19:09:22 +01:00
pop4959 14c6c2a055 Fix spawner delay feature (#3239)
Closes #1332

The spawner delay feature has been broken in Essentials for as long as anyone can remember. The reasons for this are mentioned in the issue above.

This PR fixes this by changing the command to utilize new API for setting the minimum and maximum spawn delay on spawners. This API was added in 1.12.2, so all supported versions before that (1.8.8 thru 1.12.1) require NMS to function properly. I'm aware that Essentials avoids NMS for maintainability reasons, however that should not be of much concern here since all versions 1.12.2 and later are going to be using the Bukkit API. Hence, no NMS updates will be necessary.

Also let me know if you want the NMS code refactored somewhere else. I saw the net.ess3.nms packages, but I wasn't sure where this would fit into the organisation of that.

Tested on:
1.8.8, 1.9.4, 1.10.2, 1.11.2 (NMS)
1.12.2, 1.15.2 (Bukkit API)
2020-08-05 20:47:42 +01:00
pop4959 68d0aa9688 Improve GeoIP errors/warnings (#3568)
Aims to provide a better and less confusing error for users of GeoIP who have not configured properly (which is more common now after the license key requirement). Seems like a lot of people miss the initial error on startup, and so this may help a bit.

Closes #3561.
2020-08-04 16:22:14 +01:00
MD 1ef4e15a4d Fix regression in /tpaccept (#3567)
d9bf099c3d introduced a regression where `/tpaccept` no longer unconditionally cancels the teleportation request when it is accepted. This restores the previous request cancellation behaviour.

Fixes #3563.
2020-08-04 16:20:24 +01:00
latiku d35b4b9128 Don't send chat messages if they only contain formatting codes (#3505)
Closes #3442.

When a player with the appropriate permission node to use color formatting codes sends a message with nothing but valid formatting code, a message with an empty line is sent. This PR solves this issue by checking if the final formatted message is just a color code, and if so, cancels the event.

Below are some attached screenshots with debug messages containing the event's raw message, the event message after it is formatted, and in the case of the "before" screenshot, the message sent in-game. 

Before: https://user-images.githubusercontent.com/47498808/87505823-7a8c5080-c62f-11ea-99b4-29fc6eaff042.png

After: https://user-images.githubusercontent.com/47498808/87505857-8c6df380-c62f-11ea-95f8-dd59dadaf27c.png
2020-08-04 15:38:53 +01:00
Zefferis 6995be7dbd Updated website in plugin.yml files (#3528)
Replaced "http://tiny.cc/EssentialsCommands" with "https://essentialsx.net"
2020-08-04 15:35:34 +01:00
uf0h f9de6763d3 Use playerNeverOnServer message where appropriate (#3489)
### Use `playerNeverOnServer` message where it should be used:

### https://github.com/EssentialsX/Essentials/pull/3489/commits/309e1c470d4bcfe2a2186f9720ce33f26441b802 
`playerNeverOnServer=\u00a74Player\u00a7c {0} \u00a74was never on this server.` is currently used in the **Commandmail** class at [Line 61](https://github.com/EssentialsX/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/commands/Commandmail.java#L61), [Line 116](https://github.com/EssentialsX/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/commands/Commandmail.java#L116) and [Line 129](https://github.com/EssentialsX/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/commands/Commandmail.java#L129) however is **not called** as PlayerNotFoundException is thrown by `#getPlayer` breaking current execution (below).
```
Commandmail#run() throws Exception {
...
    User u = getPlayer(server, args[1], true, true); // throws PlayerNotFoundException
        if (u == null) {
            throw new Exception(tl("playerNeverOnServer", args[1]));
    } 
...
}
```

Before changes:
![bm](https://user-images.githubusercontent.com/24858857/87236993-6b679180-c3e8-11ea-83a7-002194f5c467.png)
After changes:
![mailafter](https://user-images.githubusercontent.com/24858857/87237060-3576dd00-c3e9-11ea-8020-d5a80a958ca0.png)

--------------------------

**Commandseen** currently throws the default PlayerNotFoundException `playerNotFound` message for players that have not logged on to the server where it would be more appropriate to use the `playerNeverOnServer` message.

```
Commandseen#run throws Exception {
...
    AsyncRunnable#run() {
        User userFromBukkit = ess.getUserMap().getUserFromBukkit(args[0]);  <-- ***
        try {
            if (userFromBukkit != null) {                             <--- ***
                showUserSeen(userFromBukkit);
            } else {
                showUserSeen(getPlayer(server, sender, args, 0)); <--- ***
            }
        } catch (Exception e) {
            ess.showError(sender, e, commandLabel);
        }
    }
    private void showUserSeen(User user) throws Exception {
        if (user == null) {                                    <--- ***
            throw new PlayerNotFoundException();
        }
        showSeenMessage(server, sender, user, showBan, showIp, showLocation);
    }
...
}
```

**`<-- ***`:**
`usersFromBukkit` null check is performed before `#showUserSeen` so there is no need for another null check.
`EssentialsCommand#getPlayer` throws **NotEnoughArguementsException** or **PlayerNotFoundException** after [arg checks](https://github.com/EssentialsX/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java#L88) and [player checks](https://github.com/EssentialsX/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/commands/EssentialsCommand.java#L103). https://github.com/EssentialsX/Essentials/pull/3489#issuecomment-657138524

Before changes:
![sb](https://user-images.githubusercontent.com/24858857/87237038-e9c43380-c3e8-11ea-8294-8f91e8b6f25d.png)
After changes:
![seenafter](https://user-images.githubusercontent.com/24858857/87237067-53444200-c3e9-11ea-92c5-1784b4dcd739.png)

----------------

### 725128e
Catch more specfic exception `PlayerNotFoundException`.

Before changes:
![banbefore](https://user-images.githubusercontent.com/24858857/87237021-c1d4d000-c3e8-11ea-99e4-eb97b5a5ba6d.png)
After changes:
![afterunban](https://user-images.githubusercontent.com/24858857/87237081-8d154880-c3e9-11ea-9d35-a25b8c105969.png)
2020-08-04 15:30:05 +01:00
pop4959 dfce971565 Fix stale tpaccept 2020-08-04 02:37:37 -07:00
Olivia 97e3f32d7f Fix some minor errors in config/docs (#3566) 2020-08-04 01:13:09 -07:00
Cameron Seid c86e1a5973 Update backup comments in config.yml to be less ambiguous (#3553) 2020-07-30 21:58:19 -07:00
md678685 ab545dc44c Fix rare ConcurrentModificationException in quit handler
Copies the list of viewers before iterating over it to fix a rare CME that is *sometimes* thrown. It's not clear *why* this broke - Spigot seems to have changed behaviour in late 1.15 or 1.16?
2020-07-30 14:23:22 +01:00
Josh Roy 11cd57e8fb Add sign text tab completion in editsign command (#3497) 2020-07-28 13:12:07 -07:00
pop4959 b7c18d0785 Add missing getRecipe(NamespacedKey) method to FakeServer (#3530) 2020-07-22 12:02:00 -07:00
Josh Roy 9aec89f381 Properly handle jail respawn in togglejail (#3522) 2020-07-21 16:22:20 -07:00
Josh Roy e34984513d Add config option to respawn at respawn anchors (#3498) 2020-07-17 14:13:30 -07:00
Tim S cedd42f411 Fix how random teleport picks a location (#3480) 2020-07-17 13:56:48 -07:00
untuned c9b75aabb2 include new sign types in definitions (#3487) 2020-07-11 15:21:33 -07:00
pop4959 41ae12ed3d Disable random tp pre-cache by default (#3496) 2020-07-11 12:35:19 -07:00
JakeTS dba35f043d Typo, should be "match" not "maths". (#3488) 2020-07-10 21:10:12 -07:00
md678685 8046b8594a Release 2.18.0
🎉
2020-07-09 20:15:30 +01:00
pop4959 6c64aaefec Fix issue with /remove skeletonhorse (#3477)
Fixes a problem where skeleton trapped horses cannot be killed in commands such as `/remove skeletonhorse` (or even `/remove all`) because they are tamed by non-player entities. There is a separate command for killing tamed entities, however this kills other player-owned entities which is undesirable.

This can be replicated easily by spawning some skeleton traps like so:
`/summon skeleton_horse ~ ~ ~ {SkeletonTrap:1}`
and then attempting to run `/killall skeletonhorse`.

After this small change, any tamed skeleton horses will be retained, but non-player-owned skeleton horses will be removed as appropriate.

Closes #3475.
2020-07-09 19:36:08 +01:00
MD 07fa87dc6a Deny tpahere requests to players without permission to accept (#3478) 2020-07-09 10:45:14 -07:00
pop4959 b58c98bea0 Add jail contexts (#3476)
Someone probably wants these. Also, who in the world decided that `IJails::getList` should throw an exception?

https://user-images.githubusercontent.com/17698576/87005099-57ffc080-c173-11ea-956f-0b64a52c7f40.png

https://user-images.githubusercontent.com/17698576/87005107-5afab100-c173-11ea-8d25-6efde7ee9026.png

https://user-images.githubusercontent.com/17698576/87005382-c5135600-c173-11ea-9335-e80e322afd89.png

https://user-images.githubusercontent.com/17698576/87005299-a44b0080-c173-11ea-8789-f2f0d8b9cc4b.png
2020-07-09 08:41:25 +01:00
zml 08e553bd1a Hide EssX commands from non-core modules in autocomplete (#3473)
quick little thing so people stop complaining
2020-07-09 08:37:41 +01:00
Josh Roy e35fb82bc2 Add UserTeleportHomeEvent (#3403)
Adds an event which allows developers to see & cancel when users attempt to teleport home. This event is needed over `PreTeleportEvent` due to the fact that it would be extremely difficult to accurately filter it by the /home command.

Closes #3401
2020-07-08 19:53:32 +01:00
MD a92ca63ca9 Replace UserTeleportEvent with more sane events (#3192)
This PR replaces UserTeleportEvent with two new teleport events called at different stages:
- TeleportWarmupEvent; called before a user's teleport warmup begins and allows plugins to skip it or prevent a teleportation
- PreTeleportEvent; called after the warmup completes but before any safety checks are carried out

This is a **breaking change** as it removes UserTeleportEvent, but the previous event isn't useful or descriptive in its current form and was only recently introduced, so it's unlikely that many plugins already depend on this.

Closes #2506.
2020-07-08 19:51:00 +01:00
pop4959 cbfad7b320 Choose better elevation for random nether teleport (#3466) 2020-07-07 18:19:53 -07:00
MD c16987fb87 Add config option to hide join/quit messages above X players (#3464) 2020-07-07 15:16:20 -07:00
Flask Bot 477f5a7841 New Crowdin updates (#3462) 2020-07-07 20:41:06 +01:00
md678685 6f149224d1 Fix reporting of economy backend to bStats 2020-07-06 21:15:03 +01:00
Josh Roy 1a6ad2fdb0 Allow for specifying amount to increase itemstack in /more (#3302)
Fixes #2342.
2020-07-06 19:55:07 +01:00
pop4959 76e511a774 Implement random teleport command (#3418)
Adds `/tpr` and `/settpr` commands, which respectively allow you to teleport randomly or set teleportation parameters.

Server owners are expected to set the center with `/settpr` before players can use `/tpr`. They can also set the minimum and maximum range to be teleported from the center (default 0-1000).

Also includes an event where plugins can adjust or cancel the teleport.

Closes #3154.
2020-07-06 19:53:43 +01:00
Josh RoyandMD 9681933ec2 Add mute expiry time in mute messages (#3329)
Co-authored-by: MD <1917406+md678685@users.noreply.github.com>

Closes #1211.
2020-07-06 19:52:51 +01:00
711bfed557 Add itemlore command (#3331)
Co-authored-by: pop4959 <pop4959@gmail.com>
Co-authored-by: MD <1917406+md678685@users.noreply.github.com>

Adds a command to add to or clear an item's lore.

Closes #1911.
2020-07-06 19:46:57 +01:00
zml 016a1b3421 Handle explicitly denied permissions with no perms plugin (#3419)
to finally end the `/hat` saga, hopefully for good
2020-07-06 19:40:47 +01:00
MD 01b9ec4a42 Allow preventing bed and respawn anchor explosions in Protect (#3453)
Adds `bed-explosion` and `respawn-anchor-explosion` options to the Protect config.
2020-07-06 19:38:07 +01:00
pop4959 9b729dd091 unchange 1.13 naming 2020-07-06 11:34:43 -07:00
triagonal 0a73be2082 Add PrivateMessageSentEvent and fix PrivateMessagePreSendEvent (#3432)
This PR introduces a new private messaging related event `PrivateMessageSentEvent` and fixes a mistake made on my part during the implementation of `PrivateMessagePreSendEvent`.

Recently when attempting to use the pre-send event in order to play a sound to the recipient of a message, I found that the event was not completely adequate for my use case. Between the firing of the pre-send event and the end of the delivery attempt, the message delivery could fail for a number of reasons (e.g. messages toggled off, sender ignored, unreachable recipient) with no straightforward way of determining this using the existing event.

I believe that a second event fired after the message sending attempt has been fully processed will provide a simple method of determining whether or not a message was successfully delivered by including the [`MessageResponse`](https://github.com/EssentialsX/Essentials/blob/60f54ee37d9472848e28d2e64adc2735e10975c1/Essentials/src/com/earth2me/essentials/messaging/IMessageRecipient.java#L84) in the event.

Additionally, I found that when implementing the pre-send event, I mistakenly passed an incorrect reference for the `sender` meaning that currently there's no clean or reliable way to determine if `sender` is the `Console` or a `User` (`instanceof` doesn't work, which leaves checking by name or using reflection).
2020-07-06 19:34:13 +01:00
md678685 c668879070 Add slightly more sanity to Vault code
This subtly changes how backend permissions plugins are reported on
bStats. (Previously, somehow the LP service provider was detected as
originating from Vault...?)
2020-07-06 19:09:20 +01:00
md678685 c4d318b7d0 Deprecate TimedTeleport 2020-07-06 18:49:25 +01:00
pop4959 e7d9dbfbcf Allow preventing bed and respawn anchor explosions in EssentialsProtect 2020-07-05 18:46:23 -07:00
MD 1be3daf0b5 Update bStats Metrics and add wrapper class for new graphs (#3451)
This PR updates the version of the bStats Metrics class to the latest version, supporting plugin IDs in place of just plugin names. It also adds the following graphs:
- Active permissions backend
- Active economy backend
- Whether or not a command has been used as a bar chart (pending bStats backend implementation)
- Version history graph as a multiline graph (also pending bStats impl)

It also removes the weird `getMetrics` and `setMetrics` APIs which should never have been API in the first place.
2020-07-05 19:30:01 +01:00
Josh Roy 8f86849aec Fix 65f8883 breaking offline home listing (#3446) 2020-07-02 18:59:40 -07:00
Josh Roy 0b4ee9e73e Add hidden config to stop throwing errors for passengers (#3445) 2020-07-02 15:30:22 -07:00
Josh Roy 65f88834ba Fix further AME(s) in /home (#3444) 2020-07-02 22:58:40 +01:00
pop4959 024c56efdd Fix recipe command on Paper (#3404) 2020-07-01 15:19:42 -07:00
pop4959 9c487b0aac Match kit name in delkit (#3396)
This allows deleting kits ignoring case; fixes #3370.

I don't know if this is the ideal fix, but everything else for kits seems to nuke the letter casing. Not really sure why in `Kits.java`, the keys needs to get lowercased in a new mock `ConfigurationSection`. It just seems like this would purely make it harder to access the same section again in the real config. Instead, I just added a different method that matches the real config name of the kit (as set in `/createkit`, which currently allows uppercase).
2020-07-01 22:12:43 +01:00
pop4959 d743f928ad Ignore NPCs in EntityCombustByEntityEvent (#3389) 2020-07-01 22:06:49 +01:00
pop4959 07e2fe3af1 Improve suicide and kill commands (#3388)
Fixes #3189 

This PR makes improvements to the suicide and kill commands, namely:
1) Call `EntityDamageEvent` with damage equal to `Float.MAX_VALUE`, which is the amount that is inflicted by `/minecraft:kill`.
2) Removes the calls to `Damageable::damage` which ends up damaging the player with `DamageSource.GENERIC`, and later causing another `EntityDamageEvent` where as a result the last damage cause gets set to `EntityDamageEvent.DamageCause.CUSTOM`. Thus, the `EntityDamageEvent` that Essentials calls gets rendered useless when someone tries to get the damage cause of the player in `PlayerDeathEvent`. Setting health to zero forcibly kills the player without causing damage.
3) Add `getTabCompleteOptions` to the suicide command, as it currently incorrectly suggests players.
2020-07-01 22:04:46 +01:00
pop4959 9f384c71f3 Confirm home replacement when overwriting existing homes (#3338)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
Co-authored-by: MD <1917406+md678685@users.noreply.github.com>

Warns the player that they are trying to replace a home, if they try to set one with the same name, when `confirm-home-overwrite` is set to `true` in the config.

https://user-images.githubusercontent.com/17698576/83004206-3633eb00-9fc4-11ea-9317-fe245fed9cbb.png

Fixes #2038
Closes #2847
2020-07-01 22:03:22 +01:00
Josh Roy 7a5aea0bcf EditSign Command (#3415)
bro so epic bro
2020-07-01 21:58:11 +01:00
Josh Roy b6c9bc1439 Add command + money queues to process after items in kits (#3434)
Fixes #3431
2020-07-01 21:51:10 +01:00
Josh Roy b7f38517ef Fix some reported bugs regarding teleportation. (#3433)
Fixes #3420
Fixes #3430
2020-06-30 17:00:20 +01:00
Josh Roy 60f54ee37d Fix relocation pattern for EssentialsXSpawn (#3427) 2020-06-28 19:14:06 -07:00
Josh Roy adf1273bf9 Fix RGB support in prefixes/suffixes (#3422) 2020-06-28 16:36:17 +01:00
MD 3c79e9e59d Update items.json from generator (#3394)
This PR replaces the current `items.json` file with one generated *solely* by ItemDbGenerator.

In 1.13.x, the `items.json` shipped with EssentialsX was generated using the [genItemsFlat script and data](https://github.com/md678685/essx-scripts). For 1.14 and 1.15, this was merged with the output of [ItemDbGenerator](https://github.com/EssentialsX/ItemDbGenerator), but this is an awkward and unreliable process involving three separate tools. This has now been consolidated into a single tool, which is now on par with the old process.
2020-06-27 22:38:32 +01:00
1ab1b5713e Update to 1.16.1 (#3408)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
Co-authored-by: md678685 <1917406+md678685@users.noreply.github.com>
Co-authored-by: pop4959 <pop4959@gmail.com>
2020-06-27 12:17:35 -07:00
Flask-Bot edf2f295d1 Update Crowdin configuration file 2020-06-27 16:41:40 +01:00
pop4959 c043416b11 Fix spawner provider on 1.16 (#3412) 2020-06-24 23:25:14 -07:00
Josh Roy 4a471f0a93 Provider Rework (#3407)
Moved providers around, made them make sense, profit
2020-06-24 22:00:59 +01:00
md678685 04a1d8197f Update PaperLib to 1.0.4 2020-06-24 18:08:39 +01:00
Josh Roy d9bf099c3d Reduce sync loads for teleporting (#3102)
This PR reduces the number of sync loads occurring on any teleport caused by essentials.

Fixes #2861
Fixes #2287
Fixes #3274
Fixes #3201
Fixes #2120

Before this PR, essentials would get a block multiple times causing sync loads to check if it was safe to teleport to. Now, the target block's chunk if fetched async with PaperLib and passed along to `LocationUtil#isBlockUnsafeForUser` (which internally calls other LocationUtil methods what that chunk object) resulting in the chunk only loading once, off the main thread. The only operations remaining on the main thread is `LocationUtil#getSafeDestination`. This is due to the method's recursion which would be a pain to move async. **However:** since the chunk was already loaded async, `LocationUtil#getSafeDestination` most of the time won't cause sync chunk loads. The only time it would cause sync chunk loads is with an unsafe location near a chunk border.

-----------------------------------------

* Reduce sync teleporting loads

* Avoid argument re-assigning

* Remove async teleports when unnecessary

* Make exceptions cleaner

* Async all the things

Made an async version of every method with fallbacks for deprecated methods.

* Remove old now fallback method

* Migrate everything to the new async teleport API

* Update ITeleport javadocs

* Fix invoking via async context

* Fix /jail using deprecated method

* Fix jail join handler using deprecated method

* Rename all teleport classes to indicate async

* Remove deprecated methods

* Add (and deprecate) old teleport api

* Revert TimedTeleport.java

* Reduce Diff

* Add legacy sendToJail method

* Reduce Diff Further

* Use getNewExceptionFuture in Commandtpo

* Use getNewExceptionFuture everywhere

* Fix even more usages

* Revert LocationUtil.java

* Fix issue causing unsafe locations to not work properly

* Add deprecated notice in IUser implementation

* Use CompletableFuture#completeExceptionally for exceptions

* Use Essentials' logger in EssentialsCommand#showError

* Return implementation rather than interface

* Avoid possible deadlocks with entity ejections

* Nuke some sync loads with homes

Took 7 hours and 2 PRs to paper but it's here!

* Fix ABI and make the codestyle worse

* Make the codestyle worse because muh diff

* Further ruin the codestyle

* Fix error messages not showing in TimedTeleports

* Improve messages around beds for /home

* Fix #3274

Allow unsafe locations for different worlds + spectator mode

* Fix fly safety operators
2020-06-24 09:52:25 +01:00
Jason d2f2140be9 Fix a messages.properties message (#3391)
It's a small change but I figured more consistency could be nice
2020-06-19 17:15:52 +01:00
pop4959 04f88e460b Add missing tl keys for tempbanip (#3387) 2020-06-16 18:39:22 -07:00
pop4959 d64f73e719 Add support for translating command description and usage (#3284) 2020-06-16 13:39:48 -07:00
Josh Roy 2ab4dcbc11 Add option to remove vanishing items from keepinv users (#3328) 2020-06-15 16:22:00 -07:00
846043e9a0 Add settings to protect items from explosions (#2504)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>
Co-authored-by: pop4959 <pop4959@gmail.com>

Adds protection settings to Protect to block item damage when entities such as wither skulls, fireballs, TNT and creepers explode.

Closes #2284.
2020-06-15 13:54:16 +01:00
MD ea57e4ae01 Add serialize method to ItemResolvers for custom serialization (#3307)
Add an optional `serialize` method to `ItemResolver`s which plugins can implement in order to add custom items to `/createkit`. Also improves ItemResolver docs.

Closes #3305, closes #3216.
2020-06-15 13:46:44 +01:00
Josh Roy 6aa5e5cc4a Add config option to control selling names items with /sell (#3314)
Adds an `allow-selling-named-items` config option, which allows server admins to enable/disable the ability to sell named items with `/sell`.

Closes #1988.
Closes #908.
Closes #2196.
2020-06-15 13:44:46 +01:00
oxygencraft 3e5bd4cf09 Deny teleport requests to players lacking permission to accept (#3361)
This PR will deny any teleport requests to players lacking permission to accept the request (`essentials.tpaccept`).

Closes #1259.
2020-06-15 13:36:13 +01:00
TehBrian 3d096c1f31 Fix inconsistent coloring in messages (#3366)
Fix two inconsistencies that look like this:

https://user-images.githubusercontent.com/32250137/84316124-971d0080-ab38-11ea-8297-73f978e79a57.png

The period's color at the end is out of place. This pull-request fixes that by setting the period's color to `§4` instead of `§6`.
2020-06-15 13:35:13 +01:00
Glare b5b6bce758 Ensure RemoveEffectsOnHeal config setting is actually registered (#3377) 2020-06-13 09:40:42 -07:00
Jasonandtriagonal 46ed8e954f Add config.yml note (#3359)
Co-authored-by: triagonal <10545540+triagonal@users.noreply.github.com>

"The player's bed respawn point is still set by Minecraft even if `update-bed-at-daytime` is set to `false` in config, meaning that the entire feature is indeed ineffective on Minecraft 1.15 and above."
2020-06-10 13:40:05 +01:00
pop4959 cfca2f7550 Mention setworth command in worth.yml (#3364) 2020-06-10 13:37:55 +01:00
MDandJosh Roy a09df9bf3a Add UTF8 support for .properties files (#3358)
Co-authored-by: Josh Roy <10731363+JRoy@users.noreply.github.com>

Based on edaa4f6, this allows messages files to be read in UTF8 without the need for native2ascii conversion. This also removes the native2ascii-maven-plugin, previously used to convert Crowdin translations to a compatible format. I've tested this briefly and it appears to work correctly with both internal translations and custom messages.
2020-06-07 12:06:33 +01:00
Josh Roy dc2462c277 Add option to change disposal title via sign (#3269)
Closes #2628.
2020-06-05 16:16:47 +01:00
md678685 25c7ebcf39 Remove BuildTools script and update README 2020-06-05 15:22:40 +01:00
pop4959 baab65d776 Add support for permission contexts (#3320)
As discussed in #2960. Allows Essentials to register contexts with permission plugins that support them. A working implementation for LuckPerms is included in this PR. PermissionsEx 2 also has support for registering contexts, however it should probably be added at a later date, since as per zml2008 on Discord, the API is not yet stable.

https://user-images.githubusercontent.com/17698576/82718550-f5507500-9c57-11ea-970d-9d5f8bce8037.png
2020-06-03 21:36:27 +01:00
pop4959 9e2b906048 Display date diff correctly (#3292)
There is an age old issue in Essentials which causes date diffs (such as those displayed in teleportation delays, mutes, and temp bans) to display incorrectly to the user when the command is run. After looking into this a bit, it looks like the reason for this is that if there is even a 1 ms time difference between parsing the date diff and displaying it, the time displayed will be truncated by an entire second. This PR fixes this problem by adding 50 ms of buffer time to the date object *only* when it is calculating the date diff string. This is not significant enough to be noticed by users, and allows Essentials code to correctly generate the date diff string as long as it does so within 50 ms of parsing it.

As a theoretical example... lets say a user is muted for 1 year. If 1 ms passed (in code prior to this PR) between parsing and displaying the date diff, then the displayed time will be 11 months, 29 days, 23 hours. This is because 1 year - 1 ms is being truncated down and then Essentials lops off time accuracy beyond the 3 most significant terms. After this PR, the date diff will be parsed normally, but when the display string is being calculated, it will use 1 year + 50 ms (and if 1 ms passed, then that would be 1 year + 49 ms), which gets truncated to 1 year.

As a practical example:
https://user-images.githubusercontent.com/17698576/82106444-d55c0700-96d5-11ea-8290-377442e4f9fe.png

Quite often (I'd say about half of the time) before this PR, the date diff will display like this, when the example command `/mute <player> 1y` is run.

https://user-images.githubusercontent.com/17698576/82106467-063c3c00-96d6-11ea-9da2-3dc1556add14.png

After this PR, the date diff displays correctly every time.

Fixes #3349.
2020-05-30 15:18:16 +01:00
pop4959 9f3c2683ae Clean up providers a bit (#3279) 2020-05-28 12:06:03 -07:00
pop4959 9e01a1a427 Player should not be able to send empty shout/question messages (#3341) 2020-05-28 11:45:05 -07:00
pop4959 db729241c9 Fix issue with eco reset requiring 3 args (#3340) 2020-05-28 11:44:46 -07:00
d5d8c80d74 Protect Armor Stands + Item Frames (#3270)
Co-authored-by: JRoy <joshroy126@gmail.com>
Co-authored-by: AlexTheCoder <alexjmeech@gmail.com>
2020-05-27 12:36:53 -07:00
Josh Roy 4c48ccb422 Block removing hats with curse of binding (#3299) 2020-05-27 12:36:22 -07:00
Josh Roy 53e7c83254 Add tempbanip command (#3291) 2020-05-27 12:35:20 -07:00
Josh Roy fdef1062f0 Add config option to block /pay from ignored users (#3273) 2020-05-27 12:34:11 -07:00
kakd b9f8fc2e11 Option to send coordinate after death (#3207) 2020-05-27 01:58:54 -07:00
Xeyame db410fb3e7 Add missing methods to Commandexp (#3335) 2020-05-26 17:26:58 -07:00
Jason 500dadc760 Update config.yml custom join/quit message comments (#3334) 2020-05-26 16:22:38 -07:00
md678685 7d61953753 Fix spawner provider detection only working on 1.13+
This caused a seemingly-unrelated error where the 1.7/1.8 provider was being used on all versions up until 1.12. Upon further investigation, this line caused a NoSuchFieldError, and since this isn't an Exception it was caught by the outer `catch (Throwable t)` which was intended to catch throwables from the providers rather than the setup of tryProvider.
2020-05-20 19:49:45 +01:00
pop4959 5b9b76d5e7 Fix clearing specific items in clearinventory (#3263)
Fixes #2986
Closes #3050
Closes #3191

Refactors the clearinventory command code in such a way that fixes the problem of not being able to clear all of a specific item on newer server versions. Also re-adds data value support for older server versions that support it, which seemed to have been inadvertently removed in 79bc340.

Checked against 1.8.8, 1.12.2, 1.13.2, 1.15.2.
2020-05-17 21:10:12 +01:00
Josh Roy b9804d8980 Ignore CloudNet v3 SLPE (#3288)
Yet another CloudNet fix.

Fixes #3282
2020-05-17 15:35:31 +01:00
Josh Roy b960ee365a Fix improper target block handing in /tree & /bigtree (#3271) 2020-05-13 15:55:17 -07:00
Josh Roy 302f0acbaa Add permission for storing user's last location on teleportation (#3272) 2020-05-13 15:53:36 -07:00
Glare 8f5b97b9d2 Merge pull request #3277 from pop4959/remove-1.8-spawner-providers-2 2020-05-13 14:29:54 -05:00
pop4959 6371cf7517 Remove 1.8 nms spawner providers from pom 2020-05-13 12:17:37 -07:00
pop4959 e53520aef6 Remove 1.8 NMS spawner providers (#3276)
This PR removes the 1.8 R1 and R2 spawner providers. I was looking into refactoring these to use reflection instead of importing NMS code (in order to avoid requiring buildtools to compile), but after some research it looks like these are actually not even used anymore, in favor of the LegacySpawnerProvider (which Essentials appears to use for 1.8.0-1.12.2). Thus, keeping these is fairly pointless and causes more harm than good. There is no reason to continue including them, nor maintaining them. Essentials currently doesn't even officially support these versions anyway.
2020-05-13 10:56:50 +01:00
triagonal d59fd71ba5 implement PrivateMessagePreSendEvent (#3260)
This PR introduces an event to be called just before a private message is sent to a user. This event provides the message sender, the message recipient, and the contents of the message.

This event provides the possibility for greater customization of private messages, such as playing a sound or displaying a boss bar when a private message is received, or filtering private message content.

Closes #726, closes #2097.
2020-05-13 08:03:28 +01:00
Crash Cringle 4b967a749b Added a command to /eco that allows users to take percentages from pl… (#3080)
* Removed unnecessary formatting

* Fixed spacing around isPercent, removed unnecessary parenthesis, optimized conversion
2020-05-12 21:38:36 -07:00
pop4959 8f88a8dcb3 Allow 1 char name (#3264) 2020-05-12 21:27:33 -07:00
pop4959 a58ba406eb Add offhand slot to invsee equip (#3265) 2020-05-12 21:26:24 -07:00
pop4959 a93ca9b7bc Use world's sea level for depth command (#3268) 2020-05-12 21:05:57 -07:00
Josh Roy 02e6b5f1b3 Fix isStopping MethodHandle invocation on Spigot (#3267)
Fixes #3266.
2020-05-12 20:14:01 +01:00
Josh Roy 63dd5f3f64 Fix age old bug with active status in Backup manager (#3262)
I cannot even reproduce this error but I guess one other person can. Fuck this stupid feature
2020-05-11 18:09:29 -07:00
Alexander Meech a3a50e9cd5 Implement permission node to extinguish other players (#2826)
Implements a specific permission node to restrict access to extinguishing other players, so Extinguish command will match other commands with similar functionality (i.e. /feed)

Fixes #2796
2020-05-11 17:40:24 +01:00
pop4959 8e3c1aaa96 Implement rest command (#3205)
Implements a rest command based on @mart-r's suggestion in #2299. Resetting the time since rest statistic prevents phantoms from coming after you for an hour (real time). The statistic is also set to zero when using a bed. This command cannot be used pre-1.13 because the statistic does not exist (nor would it matter since there are no phantoms).

Closes #2299
2020-05-11 17:11:06 +01:00
Josh Roy 8b71437264 Improve backup functionality (#3258)
Waits for an ongoing backup task to complete in onDisable (and yells at users for `/reload`ing), and adds a `backup.always-run` option to enable always running backups even when no users have logged in since the last backup.

Fixes #3257 and closes #2646.
2020-05-11 16:55:31 +01:00
Josh Roy 61d0ed3f01 Fix invalid charge error when using suffix currency on signs (#3253)
i swear i test my code

Fixes #3252.
2020-05-11 15:20:00 +01:00
Josh Roy fc2b7b63a2 Save player logout times on shutdown (#3157)
Properly save userdata and mark the player's last logout time when the server is shutting down.

Fixes #2764.
2020-05-11 14:53:05 +01:00
kmecpp 96590a3389 Add KitClaimEvent (#3197)
Adds an event fired when a kit is expanded for a user. Fixes #3196.
2020-05-09 21:19:51 +01:00
zml a043de3e44 Add a more helpful error message for xmpp module (#3247)
Rather than spitting out a stacktrace, this gives users some instructions on what to do.

It's a bit spammy so the error messages get noticed, that could be toned down a bit if we just want to be silent on login. Unfortunately a lot of plugins haven't discovered the debug and trace log levels, so a lot of startup warnings (like this one) will get lost in the spam if there aren't other issues.
2020-05-09 13:21:02 +01:00
Josh Roy 81d3900ef6 Cleanup after UUID Ignore List PR (#3227)
Most of these are edge case fixes, but still fixes nonetheless!
2020-05-04 14:32:49 +01:00
Josh Roy fd136384a1 Add null check in ignore command (#3226)
This would only become a problem if a server owner decided to delete a bunch of their userdata. Nonetheless, it doesn't hurt to have the check.

I promise this is the last pull request regarding this 😄
2020-05-04 14:17:08 +01:00
Josh Roy dd5fe117b5 Fix null check in Username->UUID ignore list converter (#3225)
Didn't test with a username that didn't exist and didn't notice this. Null check(s) are now in their proper place.

Fixes #3223.
2020-05-04 13:48:50 +01:00
Josh Roy e9d29f789f Add default enchantment level for enchant sign (#3070)
Defaults the enchantment level on signs to `1` if one is not provided on the sign.

Closes #1497.
2020-05-04 11:10:16 +01:00
Josh Roy 1bc1f646fd Convert ignore list storage to UUID-based (#3209)
As the title describes, this PR converts the ignore list storage from username-based to UUID-based.

Fixes #239.
2020-05-04 11:06:09 +01:00
Josh Roy 8ad55cb634 Add UUID and User based economy methods (#3085)
Adds methods to the Economy API to use UUIDs and User objects. Additionally, deprecates all the username (String) based methods. Backwards compatibility has been maintained and I added User validation to UUID-based methods and null checks in User-based methods
2020-05-04 11:00:25 +01:00
mart-r b19dec120a Don't show hidden players in /balance unless exact name entered (#3218)
Fixes #2305

Not looking for hidden players within the command, yet looking for offline players.
Only matching a hidden player if the name match was exact (i.e not matching nicknames).
2020-05-04 10:36:01 +01:00
pop4959 283c088b21 Add protect option for disabling ender crystal explosions (#3210)
Closes #587.
2020-04-30 20:39:00 +01:00
pop4959 d5ffed09b4 Fix home tab completions (#3206)
Fixes #1337 😎 

This PR fixes tab completions for all of the home commands in Essentials. Prior to this PR, the behavior is approximately as follows:

- `/sethome` has no implementation for completions, and so it provides player names, which isn't very useful, and in my opinion can cause more harm than good by confusing users.
- `/home` and `/delhome` fail to provide valid completions when a user has the `essentials.home.others` permission. The argument syntax is `[player:]<name>` but it tries to complete it as `<player> <name>`. Not only does it not show you suggestions for your own homes, but it proceeds to show you invalid suggestions!

This PR provides completions that accurately reflect the syntax and real behavior of the command, including suggesting homes for player names that are partially matched. It will provide suggestions for all of your own homes, as well as providing suggestions based on how far along you are in the command (players if you haven't specified `:` yet, otherwise a specific player's homes).
2020-04-30 20:26:27 +01:00
Josh Roy b7eec09307 Add config option to make currency symbol as a suffix (#3066)
Adds `currency-symbol-suffix` config option to move the currency symbol as a suffix rather than a prefix.

Closes #2577.
2020-04-25 13:12:55 +01:00
Josh Royandmd678685 23f0f98af3 Cleanup code (#3067)
Co-Authored-By: md678685 <1917406+md678685@users.noreply.github.com>

Basically cleans up a bunch of warnings that are easily suppressed.
2020-04-25 13:08:57 +01:00
Josh Royandmd678685 6bbdbc89a6 Improve MuteStatusChangeEvent (#3068)
Co-Authored-By: md678685 <1917406+md678685@users.noreply.github.com>

Adds getTimestamp and getReason methods to MuteStatusChangeEvent with the apropriate JavaDocs explaining them.

Closes #2459.
2020-04-23 16:28:08 +01:00
zml 12c8623666 Add permissions defaults to plugin.yml for op-affecting commands (#3029)
This aims to reduce the unintended consequences of granting all Essentials permissions or giving a player op, by defaulting permissions some more permissions to false, including `essentials.hat.prevent-type.<type>`. There's also a new essentials.exempt metapermission to have one parent that controls exemption from kick/ban/mute/etc. This will change behaviour for ops to some extent.
2020-04-23 16:15:10 +01:00
mink 2bd6ebd2b1 Config option to toggle disabling flight / speed on world change (#2546)
Closes #2141.

This PR adds the option to toggle whether or not EssentialsX should handle disabling player flight / speed when they switch to a new world, in case server administrators are handling that via a third party plugin.
2020-04-23 16:13:19 +01:00
pop4959 40fb496052 OfflinePlayer getAttackCooldown (#3190)
Fix compile
2020-04-23 12:15:32 +01:00
triagonal b72d822f94 Re-add missing GeoIP license message key (#3186)
This PR re-adds the geoIpLicenseMissing key which was inadvertently removed during the recent mass locale update (#3165).
2020-04-21 19:44:54 +01:00
FourDown 6d92ac9af6 Fix book formatting (#3173) 2020-04-16 17:01:51 -07:00
Josh Roy 47f27a8016 Fix method signature breakage in versions lower than 1.14 (#3175) 2020-04-16 16:55:06 -07:00
Noahandmd678685 849d095e9a Add /ecreative alias to /gamemode (#3101)
* Proper command alias

* Update Essentials/src/plugin.yml

Co-authored-by: md678685 <1917406+md678685@users.noreply.github.com>
2020-04-14 17:30:25 +01:00
Trent Hensler 923f240aa1 New Crowdin translations (#3165)
* New translations messages.properties (Russian)

* New translations messages.properties (Portuguese)

* New translations messages.properties (Hebrew)

* New translations messages.properties (Japanese)

* 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, Brazilian)

* New translations messages.properties (German)

* New translations messages.properties (Romanian)

* 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 (Greek)

* New translations messages.properties (French)

* New translations messages.properties (Italian)

* New translations messages.properties (Chinese Simplified)

* New translations messages.properties (Turkish)

* New translations messages.properties (Hungarian)

* New translations messages.properties (Vietnamese)

* New translations messages.properties (Korean)

* New translations messages.properties (Basque)

* New translations messages.properties (Bulgarian)

* New translations messages.properties (Chinese Traditional)

* New translations messages.properties (Finnish)

* 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 (Dutch)

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

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

* New translations messages.properties (Estonian)

* New translations messages.properties (Ukrainian)
2020-04-14 17:15:19 +01:00
triagonal 8655ff2de3 Add displayname placeholders to self-AFK messages (#3164)
As a result of #2780 (oops) the self-AFK messages can no longer exactly match the regular AFK messages as the placeholder for the player's displayname was left out for the self messages.

This PR adds those placeholders so that those who would prefer that these messages are the same can simply copy their messages from the normal `userIs*Away*` keys to the new `userIs*AwaySelf*` keys.
2020-04-14 11:56:17 +01:00
triagonal 6f61010cf9 Allow toggling public broadcast of AFK messages (#2780)
(description from #2608)

So... I've implemented a system for toggling whether or not AFK messages are broadcasted to the entire server and also changed a few things along the way:

1. I added a config toggle broadcast-afk-message that will change whether AFK messages are broadcast globally or not.
2. In both cases the AFK target now recieves a "self-oriented" message instead of the global default. Basically just says "You are now/no longer AFK". This would be a change from the default behaviour.
3. I created a way to exclude certain IUsers from broadcastMessage messages using an IUser... varargs parameter. I wasn't too sure how to implement the exclusion, but this seemed like a fairly good option.

I'm not too sure if what I've come up with is an optimal solution, but it's been tested and confirmed to work as intended.

closes #2116, closes #959

---

* implement toggle for broadcasting afk message

* add "self-private" AFK messages, implement exclusion system for broadcastMessage

* remove rogue import, clarify config comment

* move excluded collection creation out of loop, use set instead

* use set instead of varargs

* ok but actually use the set this time

* address requested changes

* update missed message section

* move from Collection to Predicate for broadcast exclusion

* update Predicate variable name

* use identity comparison (cleanup)

* clean up unnecessary imports, remove extra spacing
2020-04-13 14:33:37 +01:00
md678685 5082badca4 Improve config.yml comments and structure (#3151)
This PR fixes some issues with the config.yml:
* Adds links to the EssentialsX docs where appropriate
* Moves a couple of settings into their correct locations
* Changes headers to remove the weird implications of modularity (EssentialsHelp isn't a module, it's *one* command)
* Updates support link at top
* Minor grammar nitpicks
2020-04-13 09:06:31 +01:00
Josh Roy 307bd2a35f Prevent tridents from being picked up (#3149) 2020-04-10 12:44:45 -07:00
md678685 a11552f497 Document and clean up API events 2020-04-10 12:00:01 +01:00
Jason 8556caaeb4 Update kits.yml example to be more consistent (#3148)
Follows the note using {USERNAME} instead of {player} to prevent confusion
2020-04-09 17:11:14 +01:00
md678685 7c09012b3d Update /fireball usage and description 2020-04-09 16:40:49 +01:00
Jason eb596caa00 Change {PLAYER} to {USERNAME} in kits.yml comment (#3057)
Avoids confusion between `{PLAYER}` (KeywordReplacer placeholder) and `{player}` (kit-specific placeholder).
2020-04-09 16:00:35 +01:00
HexedHero ab4501aa4c Add check for NPCs to /back listeners (#2833)
Add a check for NPCs to the PlayerTeleportEvent and PlayerDeathEvent to avoid unnecessarily tracking NPCs' `/back` locations.

Closes #2832.
2020-04-09 15:37:51 +01:00
md678685 4b766d373d Fix kit command example
Shhhhh, #2980 isn't real, it can't hurt you
2020-04-09 15:10:43 +01:00
ThatGamerBlue e3574edc5d scripts: fix buildtools script under windows git bash (#3145)
wget is nonfunctional in git bash for windows, so we should use curl instead
(no matter what you pass to wget it fails with the same error)

https://i.imgur.com/YDw68vM.png
2020-04-09 15:05:21 +01:00
Dieter Nuytemans dcb69ddc73 Set sleepingingored default to false (#3141) 2020-04-06 22:18:33 -07:00
pop4959 1d6ad297a4 Add new interface methods to FakeServer (#3140) 2020-04-05 23:13:13 -07:00
Josh Roy 85a5e517c9 Fix passenger check not working on versions below 1.11.2 (#3132) 2020-04-05 02:48:21 +11:00
Radoje17 b08d380643 Added real name boolean option for the /list command (#3117) 2020-04-02 00:06:32 -07:00
Glare ad98fc4121 Implemented uptime placeholder (#3120) 2020-04-01 11:37:55 -07:00
Josh Roy 810689c037 Add passenger dismounting for teleports (#3069)
Add passenger dismounting for teleports
2020-03-31 18:04:44 -07:00
Joe Hirschfeld c007700c59 Merge pull request #3106 from Markyroson/2.x
Make MockBukkit compatible #3105
2020-03-31 00:06:39 -07:00
Joe Hirschfeld 8cc3f6626b Merge pull request #3113 from darbyjack/200-IQ-Protect-Improvements
Fixed my PR pt2
2020-03-30 23:42:54 -07:00
darbyjack a3b8a4adc9 Version to 1.14 2020-03-31 01:40:37 -05:00
Joe Hirschfeld 8f817c089b Merge pull request #3111 from darbyjack/200-IQ-Protect-Improvements
200 IQ Essentials Protect Improvements
2020-03-30 23:32:58 -07:00
Joe Hirschfeld ed4e7794c3 Merge pull request #3063 from schlatt-co/feature/3034
Implement better AfkStatusChangeEvent
2020-03-30 23:15:34 -07:00
darbyjack 6f732d410e Fixed my stupid PR 2020-03-31 01:13:14 -05:00
Joe Hirschfeld 6c8da20883 Merge pull request #3052 from pop4959/fix-zh-CN-geoip-issue
Fix zh-CN GeoIP locale issue
2020-03-30 23:01:50 -07:00
Joe Hirschfeld c7d9ce7f7f Merge pull request #3051 from pop4959/xp-tab-complete-fix
Fix tab completion for Exp command
2020-03-30 22:58:21 -07:00
Joe Hirschfeld 4e7f639076 Merge pull request #3049 from pop4959/near-exempt
Near exclude permission
2020-03-30 22:47:36 -07:00
Joe Hirschfeld b2c3b3a99f Merge pull request #2914 from montlikadani/patch-5
Fix NPE when the user is null in the hidden players
2020-03-30 21:27:39 -07:00
Joe Hirschfeld 77338d66dc Make drop-items-if-full work on Essentials kits (#2820) 2020-03-30 21:11:56 -07:00
Xeyame e2130df596 Add different translation keys for the "me" message (#2805)
* Add different translation keys for the "me" message

* Add proper German "me" translation
2020-03-30 21:10:46 -07:00
montlikadani 2bbe6d6069 Implement message for #2640 (#2721)
* Update Essentials.java

* Update messages.properties

* Update messages.properties
2020-03-30 21:01:15 -07:00
montlikadani c8b8e505f3 Add teleport warmup event to API (#2590)
* Update Teleport.java

* Create UserTeleportEvent.java

* Update Teleport.java

* Add location to event
2020-03-30 20:38:13 -07:00
latiku 89743f9900 implement command teleporting to a player's last known logout location (#2505)
* implement /offlinetp command, teleports to a player's last known logout location

* send a message to /tp user when they try teleporting to an offline player

* getHidden is now false, you are no longer able to teleport to offline players using offline tp

* change /offlinetp to /tpoffline to match essentialsx conventions
2020-03-30 20:35:23 -07:00
latiku dbc0562fb0 permission-based jailed player interactions (#2503) 2020-03-30 20:32:12 -07:00
pop4959 76f4dff14c Fix bed message on some older versions of MC (#3048)
Fixes #3045. Some older versions of MC use "BED_BLOCK" to represent beds.
2020-03-30 08:32:44 +01:00
pop4959 baa2a2f24f Use isAuthorized for permission check 2020-03-29 13:44:33 -07:00
Pokechu22 2ca02911b3 Mention 1.15.2 in the README (#3107) 2020-03-29 12:11:44 -07:00
Markyroson cf48237049 Make MockBukkit compatible #3105 2020-03-29 10:34:16 -07:00
pop4959 adfe2c1975 Update FakeWorld (#3095) 2020-03-26 19:12:07 +11:00
triagonal a782043798 Revert "Add {PLAYER} placeholder with uppercase in kits (#2929)" (#3072)
This reverts commit 90c4a2f53c.
2020-03-14 22:49:48 -07:00
montlikadani 90c4a2f53c Add {PLAYER} placeholder with uppercase in kits (#2929) 2020-03-14 15:17:58 -07:00
pop4959 338b371e4c Implement max mute time feature (#2807) 2020-03-14 15:12:43 -07:00
Glare 347179373d Fixed double local logging (#2755) 2020-03-13 02:33:18 -07:00
montlikadani 3bb45b80b1 Add tab-completer for /spawnmob command (#2661) 2020-03-13 02:30:50 -07:00
Glare e3ec0f3b9b Added in option to remove effects on heal (#2754) 2020-03-13 02:24:29 -07:00
Joel Otero f20572b30c Add speed info to whois (#2952) 2020-03-13 01:10:44 -07:00
Josh Roy 2124cce603 Fix User::payUser(User, BigDecimal, Cause) not properly utilizing Cause (#3064) 2020-03-13 00:39:21 -07:00
JRoy ebf60c1e70 Implement better AfkStatusChangeEvent 2020-03-12 22:08:11 -04:00
pop4959 c31b6c3683 Update FakeWorld + FakeServer (#3061) 2020-03-11 17:20:46 +11:00
pop4959 ffc83343fe Fix zh-CN GeoIP locale issue 2020-03-05 01:08:55 -08:00
pop4959 2554acd304 Fix tab completion for Exp command 2020-03-05 00:31:40 -08:00
pop4959 98239114ad Near exclude permission 2020-03-04 23:23:23 -08:00
md678685 c10b39c1c7 Fix bee spawn egg aliases 2020-03-01 11:16:42 +00:00
montlikadaniandmd678685 20e11465e4 Properly fix error with fireball command (#3040)
Closes #3016.

* Update Commandfireball.java

* Update Commandfireball.java

Co-authored-by: md678685 <1917406+md678685@users.noreply.github.com>
2020-03-01 11:12:55 +00:00
pop4959 46e1b95b33 Add missing OfflinePlayer methods (#3033) 2020-02-23 18:11:57 -08:00
md678685 279d6f16e1 Bump version to 2.17.2
\o/
2020-02-22 10:05:14 +00:00
md678685 a747eccaa3 Fix /fireball on 1.8.8 (#3027)
Dragon fireballs were added in 1.9 and so this previously caused an
error. This PR fixes that (and adds tridents as throwables). Fixes #3016.
2020-02-22 10:03:43 +00:00
md678685 0bafbc3184 Reduce permission check calls in PlayerCommandSendEvent (#3026)
This reduces permissions checks by only checking each command once, not checking each command for each alias.

The impact of this is a near-tenfold reduction in permission checks during this listener, which should slightly improve performance when using LuckPerms (and provide significant improvements on older inefficient permissions plugins).
2020-02-22 10:02:53 +00:00
Edward Wang 8069370b8c Clarify easter egg config description (#3028) 2020-02-21 13:12:09 -08:00
Jason 46f4b92ff7 Update config.yml group-formats (#3025)
Since most (if not all) modern permission plugins only use lowercase group names, the examples should also be lowercase. A note has also been added explaining that group names are case-sensitive.
2020-02-21 12:24:49 +00:00
md678685 d92f5ce71c Add 1.14/1.15 item aliases and fallbacks
Short term replacement for #2897 until ItemDbGenerator is complete:

* Closes #2934 by adding 1.15 items
* Closes #2790 by adding minecraft:sign fallbacks and a "sign" alias
* Closes #2732 by adding aliases and fallbacks for cactus green/green dye, dandelion yellow/yellow dye and rose red/red dye.
2020-02-21 11:11:35 +00:00
Josh Roy 2314bf8bd4 Fix CustomItemResolver causing a StackOverflowError (#3022)
CustomItemResolver was fetching the custom item from the item database instead of the resolved custom item which caused a StackOverflowError.

Fixes #3018.
2020-02-18 20:20:53 +00:00
Jasonandmd678685 7808b21496 Explain how to add commands to kits (#2980)
* Explain how to add commands to kits

* Update Essentials/src/kits.yml

Co-Authored-By: md678685 <1917406+md678685@users.noreply.github.com>

Co-authored-by: md678685 <1917406+md678685@users.noreply.github.com>
2020-02-16 15:39:28 +00:00
triagonal 18ef412211 Add beezooka command (#3003)
This PR introduces the `/beezooka` command as suggested in #2975. The command acts similarly to `/kittycannon` with the exception of the Bee being tamed, instead flying around for a small amount of time before exploding.

Sample usage:
![beezooka](https://user-images.githubusercontent.com/10545540/74099459-11804880-4b78-11ea-9c3d-499b06d912fb.gif)

As Bees do not exist below version 1.15, an error will display when attempting to run the command on such a version:
![image](https://user-images.githubusercontent.com/10545540/74099477-4d1b1280-4b78-11ea-91c2-fa675994a85f.png)

Closes #2975.
2020-02-10 11:46:41 +00:00
md678685 0678328253 Update funding to include Ko-fi link 2020-02-10 11:34:59 +00:00
md678685 5503e1e14c Revert "Split plugin compatibility report into own class"
Revert 6fa5b80c0a, which broke `/ess version`, until this can be fixed.
2020-02-10 09:05:32 +00:00
triagonal 9e89cfa4ed Implement missing FakeWorld methods (#3002) 2020-02-08 21:10:49 -08:00
imDaniX 13f454a022 Properly escape pipe character on item lore (#2994)
Using negative lookbehind instead of negated characters set.

Fixes #2962, fixes #2984
2020-02-07 10:10:54 +00:00
pop4959 129650dade Update FakeServer (#2997) 2020-02-07 12:08:29 +11:00
md678685 6fa5b80c0a Split plugin compatibility report into own class 2020-02-01 21:46:53 +00:00
pop4959 04dfcd0965 Bump supported version to 1.15.2 2020-01-22 09:14:41 +00:00
pop4959 2e818ac709 Properly register entity transform event depending on version (#2942)
Fixes the problem mentioned in #2931 which was introduced in #2836. This is caused as a result of EntityTransformEvent being a relatively new event introduced in Spigot [856adc3e6af](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/856adc3e6afc3e9c0495ac27e38b96b144e54b1e), which was after the update to 1.13.2 in Spigot [f311182396b](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/f311182396bd74b106efebc926ea4d0b92cfba80).

Closes #2931.
2020-01-14 07:54:51 +00:00
pop4959 32ef61197f Fix bed spawn message on 1.15+ (#2943)
Closes #2893

**Tests**
![2020-01-13_14 08 12](https://user-images.githubusercontent.com/17698576/72297425-be66b480-3610-11ea-8421-1ac6881259b8.png)
![2020-01-13_14 10 02](https://user-images.githubusercontent.com/17698576/72297431-c32b6880-3610-11ea-89fc-bdda2d0cec89.png)
2020-01-14 07:50:48 +00:00
md678685 fa06cd8253 Fix Java 9 breakage causing issues on Java 8 2020-01-11 17:03:33 +00:00
pop4959 5020983af5 Update GeoIP (#2926)
This implements the fix suggested by @Bobcat00 in #2919

Users of GeoIP will now be required to register a MaxMind account and create a license to download the database required by the plugin. This license is entered into the new license-key field in the configuration.

---

* Update GeoIP

* Simplify branch

* Update old config detection

* Update geoIpLicenseMissing to point to the EssX wiki
2020-01-11 07:10:40 +00:00
pop4959 f4496b6977 Update FakeWorld again (#2925)
Spigot added some new methods.
2020-01-04 12:32:40 +00:00
montlikadani a1719d651e Update Commandlightning.java 2019-12-31 17:51:21 +01:00
montlikadani e7be2b68a3 Update PlayerList.java 2019-12-31 17:49:46 +01:00
pop4959 552dcb56a1 Improvements for delkit (#2908)
3 improvements for delkit within this PR:

1) Cleaned up unused imports
2) Show actual kit name when deleting instead of memory address (this is the reason originally for making this)
3) Implement tab completion

I've tested to make sure the changes are properly functioning. See below:

Before:
![2019-12-29_01 12 09](https://user-images.githubusercontent.com/17698576/71555204-4bd5c200-29de-11ea-9fe3-eb88db08ef48.png)

After:
![2019-12-29_01 48 50](https://user-images.githubusercontent.com/17698576/71555207-56905700-29de-11ea-9277-271bb0656d64.png)
![2019-12-29_01 48 25](https://user-images.githubusercontent.com/17698576/71555208-58f2b100-29de-11ea-8257-742fa7bb3150.png)
2019-12-31 16:10:38 +00:00
montlikadani e158a65603 Improve scheduler methods to use Java 1.8 lambdas (#2700)
* Update EssentialsPlayerListener.java

* Update Backup.java
2019-12-31 13:58:09 +00:00
CmdrKittens b694e8aaa2 Don't attempt to modify a Map value view (#2910)
md dun goofed
2019-12-29 19:41:17 +00:00
md678685 a2e09121ba Slightly nicer AntiBuild messages 2019-12-26 16:17:10 +00:00
md678685 4ce7dfa8f0 Minor refactor of permissions handlers
* Move `essentials.build` perm check from AntiBuild into default SuperPerms handler
* Don't emulate wildcards for LuckPerms or PEX
* Add `build: true` meta support for LuckPerms (+ other plugins as needed)
2019-12-26 15:08:07 +00:00
md678685 1c4ce7b4bd Don't assume primary group is always present
Fixes a potential issue with PEX 2.0 (and 1.x) where users may not have a primary group.
Closes #2901.
2019-12-26 13:08:38 +00:00
md678685 8a04c1e232 Fix custom_items.yml generation 2019-12-24 23:02:07 +00:00
md678685 6e5d378324 Add methods to set/remove custom aliases 2019-12-24 09:36:15 +00:00
md678685 8e1f3617fd Add custom_items.yml file 2019-12-24 09:36:15 +00:00
Mark Vadeikaandmd678685 2549ed830f Enable control of entity transformations in EssentialsProtect (#2836)
This allows users to prevent any of the following transformations:

- Creeper charging
- Villager infected by zombie villagers
- Villager being cured
- Villagers turning into witches
- Pigs turning into zombie pigmen
- Zombies turning into Drowned (and husks turning into Zombies)
- Mooshrooms switching colors

Configurations are in a new subsection, `protect.prevent.transformation`. All options are disabled by default.

---

* Allow for control of transformations

* Undid removal of villager checking

* Undid removal of villager checking

* Documentation for transformation configs

Co-Authored-By: md678685 <1917406+md678685@users.noreply.github.com>

* Removed duplicate configuration lines

* Updated info about husks drowning

* Changed config names

Co-authored-by: md678685 <1917406+md678685@users.noreply.github.com>
2019-12-23 13:55:05 +00:00
Josh Roy 0ebd64d314 Add a cause enum to UserBalanceUpdateEvent (#2824)
Basically, I just needed this for one of my plugins; otherwise, this could be useful for people using this event who want to see where the user's balance is being updated from.

---

* Add UserBalanceUpdateEvent.Cause
* Add special cause enum
* Add API Cause
2019-12-23 13:16:34 +00:00
Mark Vadeika 843ecb4a42 Escape pipe character on item lore (#2831)
I just adjusted the regex used to split the item lore into multiple lines in order to allow escaping of the pipe character using \|.

Fixes #2830.
2019-12-23 13:15:26 +00:00
md678685 a1a0d34940 Attempt to parse input as UUID in loop commands (#2606)
Related: #2424
2019-12-23 13:06:15 +00:00
md678685 15bb978dab Remove unused VersionUtil constants 2019-12-22 23:55:25 +00:00
md678685 6a7cf39548 Fix wrong filename in ManagedFile error message 2019-12-22 23:53:36 +00:00
pop4959 8ccb70d07d Add phantoms to protect.prevent.spawn (#2806)
Closes #2733.
2019-12-22 22:13:26 +00:00
dashaw92 45461a93b0 Correct unbanip's permission for broadcasts 2019-12-22 22:11:44 +00:00
Joe Hirschfeld b3a54a78bc Save materials in unlimited by name
There was a mistake where materials in unlimited would instead be saved
as a bukkit Material instead of its name. Instead, save it by the name.
2019-12-22 22:10:30 +00:00
AgentTroll a4182b5ff9 Correct check for command cooldowns list in userdata 2019-12-20 12:44:10 +00:00
pop4959 215dcde4b9 Update to 1.15.1 2019-12-19 12:38:18 +00:00
md678685 67b2a9a4f4 Build with GitHub Actions (#2800)
* Add GitHub Actions workflow

* Update workflow

* Run BuildTools in workflow

* Update build.yml

* Add distributionManagement to pom.xml

* Add GitHub registry Maven credentials

* Remove Travis CI config

* mkdir -p

* Remove GitHub package registry push

Didn't work anyway

* Remove distributionManagement

* Cache Maven repo

* Fix step order

* Use JitPack for VaultAPI
2019-12-16 14:23:00 +00:00
Johnny Cao 3b51b23ac2 Block gamemode changes for jailed players (#2875)
Blocks players from experiencing any gamemode changes while they are jailed.

Fixes #1996.
2019-12-12 07:37:13 +00:00
Johnny Cao e0f19f8121 Allow players to set single word AFK message - fixes #2712 (#2876)
Allows players with "essentials.afk.others" to toggle afk themselves with a single word message
2019-12-11 19:20:56 +00:00
Madis Otenurm e720fb528a Crowdin in readme (#2877)
* Crowdin for readme

* Update README.md
2019-12-11 19:04:12 +00:00
md678685 518a5454c6 Add missing FakeWorld methods 2019-12-11 08:48:45 +00:00
Josh Roy 2d9c846084 Update to 1.15 (#2873)
* Compile against 1.15

* Remove achievement related methods for OfflinePlayer

* Add 1.15 to VersionUtil

* Revert "Remove achievement related methods for OfflinePlayer"

This reverts commit d0ab84e0

* Add 1.15 Mobs

* Remove Achievement related methods from OfflinePlayer

This needs more work as this currently breaks > 1.15 support

* Actually this isn't a problem
2019-12-11 07:47:56 +00:00
md678685 59e30f05fc Merge pull request #2871 from AgentTroll/patch-mockito
Update Mockito to allow tests to pass in newer versions of Java
2019-12-10 07:48:07 +00:00
AgentTroll 0f1085a02d Update Mockito to allow tests to pass in newer versions of Java 2019-12-09 20:55:55 -05:00
Glare 882699919e Reimplement spawn-if-no-home config option (#2757)
This reimplements the `spawn-if-no-home` config option from the original Essentials plugin. If set to true, running `/home` without having set a home will send the player to spawn (previous behaviour). If set to false, running `/home` will instead show an error message and not teleport the player anywhere.

Closes #1452.
2019-10-20 09:12:53 +01:00
Ryan f6a70a542e Implements missing createExplosion methods in FakeWorld (#2818) 2019-10-13 14:35:38 -07:00
rye761 785b1fe937 Make drop-items-if-full work on Essentials kits 2019-10-13 17:00:11 -04:00
triagonal bae909ba10 implement missing OfflinePlayer methods 2019-09-24 15:51:43 +01:00
triagonal dbb9757a9f add {USERNAME} placeholder to chat format 2019-09-23 06:20:28 +01:00
md678685 deaeb46ce9 Implement missing FakeWorld methods 2019-08-28 21:14:06 +01:00
md678685 219012bc35 Set item meta in setSkullOwner before returning
*Should* address #2765.
2019-08-28 15:26:23 +01:00
md678685 5f9eb22d23 Fix player head meta on versions below 1.13 2019-08-24 10:05:26 +01:00
md678685 2c33fb6834 Correctly return null for invalid IDs when doing legacy conversion 2019-08-13 15:12:04 +01:00
md678685 8bcef6022b Add max-projectile-speed option
Projectils can load chunks pretty intensively if too fast.
2019-08-05 19:56:25 +01:00
md678685 93d36779f0 Implement regex-based nickname blacklist
Adds `nick-blacklist` list to config which takes phrases or regexes. Users with essentials.nick.blacklist.bypass can bypass the blacklist.
2019-08-05 19:01:48 +01:00
Glare 2502f5e6f2 Check if user has a permission to block putting X item on their head. (#2574)
Closes #2550. 

* Check if user has a permission to block putting X item on their head.
* Forced the material name to be lower case.
* Fixed a typo in the message.
* Updated permission node and added check to the EssentialsPlayerListener.
2019-08-05 16:19:03 +01:00
triagonal 95f2852cf3 Implement toggle for command block logging (#2599)
Just a simple config toggle for whether or not command block commands should be logged.

closes #1153, closes #162

---

* Add toggle for command block logs
* update setting name
2019-08-05 16:17:22 +01:00
md678685 ff9f712d65 Add per-projectile permissions and speed argument to /fireball 2019-08-05 16:12:32 +01:00
Mickey42302 60c4e75a1c Add Dragon Fireballs to "/fireball". 2019-08-05 16:12:32 +01:00
md678685 ccf7c48bf1 Add aliases to /delkit 2019-08-05 15:35:32 +01:00
md678685 65d81eb31e Clean up /essentials 2019-08-05 15:25:55 +01:00
md678685 b97eb12dfc Implement /delkit command
Closes #2709, closes #2719.
2019-08-05 14:06:37 +01:00
md678685 d2724d77df URGENT: critical bug fix 2019-08-02 16:05:41 +01:00
md678685 119b21ac67 Check plugin equals rather than name equals in autocomplete listener 2019-08-01 14:57:48 +01:00
md678685 1ff73b3837 Bump version to 2.17.1 2019-07-30 18:10:27 +01:00
Glare d98f8b3467 Fixed dupe on new builds. (#2696)
Fixes #2695.
2019-07-30 12:56:46 +01:00
md678685 ac8b8861cb Merge remote-tracking branch 'origin/2.x' into 2.x 2019-07-28 16:18:00 +01:00
md678685 22dc5dcebd Fix /r not showing in 1.13+ tab complete
Fixes #2659.
2019-07-28 15:00:49 +01:00
Josh Roy 3c09e72ce4 Bump supported 1.14.x version to 1.14.4 (#2681) 2019-07-20 00:48:13 -07:00
pop4959 fffc3fcac7 Implement missing methods in FakeWorld (#2679) 2019-07-18 11:56:00 -07:00
md678685 bcdbbe9546 Fix wall sign protection on 1.12.2 and below
Fixes #2635.
2019-06-27 15:50:04 +01:00
md678685 19f03cd70e Add missing /tpauto messages
Add messages from #2310 to the `messages.properties` file. Fixes #2634.
2019-06-27 12:00:47 +01:00
md678685 9b7858b830 Update README.md 2019-06-26 22:13:10 +01:00
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
md678685 4431d452f1 Bump to 2.16-pre4
Pretty much there now.
2018-12-31 13:02:08 +00:00
md678685 6a529d6671 Update EssentialsX Protect with cross-version enum lookups 2018-12-31 12:54:43 +00:00
md678685 78fca9a67a Updates signs with cross-version enum lookups 2018-12-31 12:53:41 +00:00
md678685 0114b5e4f6 Update several commands with cross-version enum lookups 2018-12-31 12:53:23 +00:00
md678685 5a14a64b6c Add cross-version support to SpawnMob 2018-12-31 12:24:41 +00:00
md678685 b555ea6350 Add cross-version support to MobData 2018-12-31 12:20:05 +00:00
md678685 361ae1dd16 Use constant field for "harp"/"piano" sound 2018-12-31 12:19:22 +00:00
md678685 58117eba88 Remove redundant BuildTools instructions 2018-12-31 12:18:45 +00:00
md678685 6260b49b4f Restore item ID messages in /itemdb 2018-12-31 11:57:15 +00:00
md678685 988239267b Restore durability permissions checks in AntiBuild 2018-12-31 11:56:50 +00:00
md678685 19cffe3872 Restore ID-based charges in /repair 2018-12-31 11:39:08 +00:00
md678685 3b1cef918e Simplify item spawn permission checks; restore ID-based item spawn perms 2018-12-31 11:29:27 +00:00
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 3553328f7a Bump to 2.16-pre3 2018-12-29 21:22:08 +00:00
md678685 0202271f00 Add missing FakeWorld methods 2018-12-29 21:16:17 +00:00
md678685 d91d6a419c Update items.json
* Fix incorrect "cobblestone" and "stone" aliases
* Fix stripped log aliases not appearing
* Fix meat/fish aliases pointing to spawn eggs
2018-12-28 16:40:39 +00:00
md678685 5173090474 Update items.json
Adds more minecart, meat, fish and hay aliases.
2018-12-26 21:05:48 +00:00
md678685 c26df8318f Update items.json
* Add more shorter spawn egg aliases
* Add new trapdoor aliases
* Add new infested block aliases and stone brick variants
2018-12-26 19:24:50 +00:00
md678685 7b44f0088a Update items.json
* Add spawn eggs aliases
* Add new aliases for several items and blocks like beetroot, pumpkins and crafting tables
* Remove `WALL_` materials (these are unspawnable)
2018-12-26 18:05:55 +00:00
md678685 aa4d3cc9fd Bump to 2.16-pre2 2018-12-25 00:27:54 +00:00
md678685 246fd03265 Fix typo in README 2018-12-23 23:33:46 +00:00
md678685 55074872fe Add setting to enable item ID recognition on signs
Item IDs can now be enabled for existing signs by manually changing a config option, but there is no facility to create new signs with item IDs.
2018-12-23 23:02:36 +00:00
md678685 28559dda3a Lowercase the provided ID in FlatItemDb#get 2018-12-23 19:45:23 +00:00
md678685 cbcfad5b2e Merge branch '2.x' into 1.13 2018-12-23 19:33:20 +00:00
md678685 a9ad440860 Overhaul AbstractItemDb.serialize to use MaterialUtil methods 2018-12-23 19:32:10 +00:00
md678685 5104463593 Add MaterialUtil.getColorOf 2018-12-23 19:31:33 +00:00
md678685 4b1c51c21d Reword IItemDb#serialize docs 2018-12-23 18:02:38 +00:00
md678685 236ef52980 Improved README (#2293)
I've made several improvements to the README, including:
* Overall rewording to make phrasing feel less awkward
* Added links to Patreon
* More consistent images for links at top
* Consolidated "Why you should use it" and "Other info" into "Why use EssentialsX?"
* More specific about version support
* Moved "Support" section above "Building" and added explanation
* Removed redundant "Commit Guidelines" section
  - It has been totally ignored for years, and it doesn't make much sense to keep it
* Added a new "Contributing" section near the bottom
2018-12-23 17:21:31 +00:00
md678685 f220c5b406 Update Estonian sudoExempt message
Thanks to @Madis0 for [pointing this out and translating it](https://github.com/EssentialsX/Essentials/pull/2228#issuecomment-449586891).
2018-12-22 17:47:39 +00:00
Thomas 9415582fe1 Update messages_nl.properties (#2129) @DutchUser
* Update messages_nl.properties

* Update messages_nl.properties

* Update messages_nl.properties

* Update messages_nl.properties

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

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

Hope it will be used :)

Greets Sprungente/enterih

* mistake^^

^

* Part 2

Adding more Improvements
Hope it helps other serverowners^^

* Part 2 fixes

* Part 3 



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

* Part 4

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

* Last part 

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

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

* small polishing

* Update messages_de.properties

* Update messages_de.properties

* Adding new strings 

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

* Half done

* Almost done

* Translation done

* Encode umlauts

* Additional refinements

* Minor fix

* Some more tweaks

* Minor wording change

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

* Does not return display name if user is hidden

* Added hide-displayname-in-vanish field

* Added hideDisplayNameInVanish()

* Changed to only hide display name if specified in config

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

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

* Spacing

* Adding Trade parameter

* Refactoring

* Adding #setWarp() to the Event

* Spacing

* Documenting the purpose of the Event

* Javadoc?
2018-10-28 18:53:52 +00:00
md678685 22538ba7c9 Merge branch '1.13' into 2.x_feature_jail_no_teleport 2018-10-28 18:46:53 +00:00
montlikadani a2a95ed840 Added acacia and dark oak tree types (#2001) @montlikadani
* Update Commandbigtree.java

* Update Commandbigtree.java

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

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

* Remove duplicate bug template

* Remove duplicate feature template

* Update help-.md

* Update report-a-bug.md

* Update request-a-feature.md

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

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

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

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

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

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

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

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

* Update messages_da.properties

* Update messages_de.properties

* Update messages_es.properties

* Update messages_en.properties

* Update messages_et.properties

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess=

* Updated "createKitSuccess=

* Updated "createKitSuccess=

* Updated "createKitSuccess=

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Updated "createKitSuccess="

* Update messages_vi.properties

Going add the other later today, 

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

* Update messages_vi.properties

* Update messages_vi.properties @md678685

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

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

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

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

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

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

* Correct comment

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

* Fix comments, again

* Re add isIgnoreMsg() check

Accidently removed it, sorry

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

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

* Update Warps.java

* Update Commandsetwarp.java

* Update Warps.java

* Update Warps.java

* Update Commandsetwarp.java

* Update Warps.java

* Update Warps.java

* Update Commandsetwarp.java

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

Fixes #1970
2018-05-18 01:23:20 -07:00
Joseph Hirschfeld b29f98c525 [Feature] Add world specific /back dest. perms (#1948) @Ichbinjoe
Adds world specific perms for whether a player may use /back to teleport
back to a given world. Adds logic to default
essentials.back.into.<world> permissions for loaded worlds to true to
maintain backwards compatibility.
2018-04-29 15:49:49 +01:00
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
md678685 b2a5280971 Avoid build version being overridden by Jenkins (#1936) 2018-03-29 14:19:19 -07:00
md678685 613e852ffd Implement new versioning as per #1873 (#1882) 2018-03-28 20:00:19 -07:00
Rodrigo Aguilar 823f1c2ee3 cancel-afk-on-interact and cancel-afk-on-move are now separate settings (#1804) 2018-03-26 00:50:42 -07:00
Trent Hensler 7d7c58fa7c Merge branch 'SupaHam-default-confirm-command-prompt' into 2.x 2018-03-26 00:37:08 -07:00
Trent Hensler a468ec5e08 Default setting to be enabled confirm commands by default with commented out list of possible options 2018-03-26 00:24:10 -07:00
Trent Hensler ce1e584266 Merge branch 'default-confirm-command-prompt' of https://github.com/SupaHam/Essentials into SupaHam-default-confirm-command-prompt 2018-03-26 00:19:23 -07:00
Minecrell ecd6c5f81a Avoid using ServerListPingEvent workaround on fixed Paper builds (#1925)
Fixes #1924

PaperMC/Paper#884 has been fixed in recent Paper builds (1368+),
which means the workaround is no longer necessary. Disable it when
running a fixed build.
2018-03-26 00:15:55 -07:00
md678685 61c1485083 Replace vanishedPlayers list with set (#1796)
* Replace vanishedPlayers list with set

Not sure if there is any particular reason to keep it ordered, but for now I've used a LinkedHashSet.

* Change return of new method from Set to Collection

Also makes return of old method an unmodifiable list, but this is just as breaking as just changing the method return type as far as I can see
2018-03-25 22:12:36 +01:00
Thomas D 9f6d0fa2d6 Update messages_nl.properties (#1888) @DutchUser
* Update messages_nl.properties

Changed English lines to Dutch.

* Update messages_nl.properties

* Update messages_nl.properties

* Update messages_nl.properties

* Update messages_nl.properties

* Update messages_nl.properties
2018-03-25 22:02:28 +01:00
RikoDEV 1c398f819e Update messages_pl.properties (#1901) @RikoDEV
Smaller corrections and supplementing the missing translations.
2018-03-25 21:39:14 +01:00
games647 c7000846cd Replace Reflection with setter implementation 2018-03-21 11:16:27 +01:00
Johnny Cao d3c4c2ba6a Fixes #1866 (#1867) 2018-03-20 21:51:16 -07:00
Max Lee 95ac4a4853 Extra permissions for /seen and /whois information (#735)
* Implemented separate permissions for seen extras

* Add an extra permission to the whois command too.
IPs are sensitive information that should only be accessible to an as small as possible amount of people
2018-03-20 21:50:42 -07:00
Luck 0d5da063fb Upload createkit configs to hastebin instead of GitHub Gist (#1916) 2018-03-20 21:42:12 -07:00
md678685 06f04b8fba Update issue template to match actual command (#1892)
Update the issue template to accommodate for the actual `/ess version` command's output.
2018-03-15 11:51:17 -07:00
games647 d24fbc9f55 Remove final modifier to fix illegal reflective access warning
Java 9 runtimes report warnings for reflective access on JRE
classes (in this case Field.modifiers). Future versions of Java
may deny the access completely.

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

* JDK9 no longer has a tools.jar because of it's modular system, but ant is
no longer required. It was introduced in 3e9a2377a8
for GroupManager. Now GM is no longer maintained and removed in
    * 5ca02e6596 (calling the build.xml)
    * fa0bbde236 (removing the remaining module)
2018-03-13 16:06:39 +01:00
md678685 43e520a03e Update issue template for new version command 2018-03-07 07:56:03 +00:00
md678685 4e8e7bec3f Add /ess version subcommand (#1514) 2018-03-06 19:25:51 -08:00
md678685 fe7b6097c9 Fix kit reloading (#1855) 2018-02-17 09:42:58 -08:00
montlikadani 0d634853b6 Updated messages_hu.properties file (#1835) @montlikadani 2018-02-14 19:11:16 +00:00
Lucas2107 29b05eb167 Update messages_fr.properties (#1807) @lucas2107
* Update messages_fr.properties

New translations

* Update messages_fr.properties

* Update messages_fr.properties
2018-02-14 19:09:59 +00:00
Leomixer17 834454491e Update messages_it.properties (#1806) @Leomixer17 2018-02-14 19:08:56 +00:00
Jacek Maciejak a9a80b5766 Update messages_pl.properties (#1803) @RikoDEV 2018-02-14 19:08:37 +00:00
md678685 b21f42ee7c Update issue template 2018-02-13 15:29:57 +00:00
k-jiang d92884800b Fix #1799 locale not found in GeoIP2 database. Optimize code. Clean up old files. (#1817) 2018-02-11 23:44:59 +00:00
Lax e57d0e96e2 Proper version command. (#1838) 2018-02-10 21:45:25 -08:00
md678685 983f3a7935 Clear item in offhand slot in /clearinventory
GitHub fancy things: Fixes #950. Fixes #1426. Fixes #1834.
2018-02-10 16:03:56 +00:00
Trent Hensler 37dfd81cc9 EssentialsX invite link 2018-02-05 21:00:36 -07:00
Lax 05400429db Cancel target event on vanished players. Fixes #1809 (#1829) 2018-02-03 19:26:43 +00:00
Johnny Cao e4a8222d48 Fixes #1794: Hides error message if no MOTD present (#1811)
* Fixes #1794
2018-01-31 17:01:51 -08:00
Johnny Cao fb5ebdb0c2 Fixes #1637: Correctly handle /mail permissions (#1743) @AgentTroll
Fixes #1637

/mail stripped colors from the entire message before as reported by the issue. The desired fix was to only strip the color from the sent message rather than from the entire message format (e.g. prefixes coming before the message itself).

Fixed by formatting only the message before passing it to the localization.

Also had a minor issue with FormatUtil in which it failed to strip ampersand (&)-formatted color codes, which was amended by stripping both VANILLA_*_PATTERN as well as REPLACE_*_PATTERN in FormatUtil#formatString(...). It's not necessary to actualy strip any vanilla (i.e. section-prefixed) color codes since that's already done by FormatUtil#stripFormat(String), but I'd like to keep the changes as non-invasive as possible at the current moment.

Demo: git-Spigot-d20369f-7fc5cd8 (MC: 1.9) (Implementing API version 1.9-R0.1-SNAPSHOT)
https://streamable.com/umyi8

This is my first time contributing so please be gentle :)
2018-01-29 18:01:20 +00:00
Ali Moghnieh 1ef1cd98db Add default toggle for confirm commands in config.yml. 2018-01-28 17:23:43 +00:00
k-jiang d581f48cd1 Detect and update the old config.yml. Fixes #1783. (#1784) 2018-01-28 14:24:30 +00:00
md678685 752565b8f1 Add nickNamesOnlyColorChanges to messages files 2018-01-24 19:23:00 +00:00
md678685 8e61753894 Format prefixes and suffixes properly in Chat
Related: #1792
2018-01-23 08:32:55 +00:00
Trent Hensler ba35efd021 Properly check for empty set 2018-01-22 16:38:01 -08:00
Trent Hensler 09af6ad186 Don't add itemflags if none are present 2018-01-22 16:37:01 -08:00
md678685 16a496c706 Fix args order in GodStatusChangeEvent (#1790)
Fixes #1107
2018-01-22 21:01:12 +00:00
MD678685 71d50f4e1e Properly rename CommandDisposal 2018-01-22 14:56:17 +00:00
md678685 8a815b42d3 Fix disposal command class name
Fixes #1791.
2018-01-22 14:16:11 +00:00
Mitchell Cook d69e3a2f48 [Feature] Added disposal command. (#1729) @Mishyy
Added a portable disposal menu.

Closes #1721, and also closes #310.
2018-01-22 12:58:00 +00:00
md678685 e38b15531d Add jailList and noJailsDefined to messages and Commandjails (#1732)
* Add jailList and noJailsDefined to messages and Commandjails

* Sort message keys alphabetically
2018-01-22 09:20:31 +00:00
U-NIFLHEIM\Lax fcc7c3af78 Per-user toggles disabled by default 2018-01-21 18:40:13 -08: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
md678685 738efe8c50 Add Vault prefix/suffix support to EssXChat (#1663)
* Add Vault prefix/suffix support to EssXChat

Includes an example of how to use it in the config.
2018-01-21 01:37:30 -08:00
delbertina 0897ca57ff Removed redundant line in mute time try-catch. 2018-01-20 22:46:55 -06:00
k-jiang 938f94e130 Upgrade to GeoIP2, add db update. (#1748) 2018-01-20 19:29:48 +00: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
Trent Hensler ace361af60 Compile against 1.13 preview.
Still a lot of work to do. One thing to note is that I used LEGACY materials in a few spots where I didn't know what the new ones are as I'm not very familiar with the 1.13 update and what it changes.
2018-01-18 17:52:44 -08:00
delbertina 67528b25a8 Sorted messages files with the -f option 2018-01-18 15:18:22 -06:00
Trent Hensler d4138ce843 Match default to what's in the config. Resolves #1775 2018-01-18 10:34:02 -08:00
Trent Hensler 377c716d52 Add itemflag support to kits. Resolves #795.
Syntax is "itemflags:HIDE_ATTRIBUTES,HIDE_ENCHANTS"
2018-01-18 00:26:40 -08:00
Trent Hensler cd43355d4c Move kits to kits.yml (#1774)
* Move kits to kits.yml
We will now use a separate kits.yml file.
Any kits that were defined in the config.yml will be migrated over to the kits.yml file automatically on startup.
2018-01-18 00:25:00 -08: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
Trent Hensler 1f0f77ff72 Merge pull request #1757 from SupaHam/fix-metaitemstack-keyword-replacer
Allow KeywordReplacer to input replacements with underscore spacers.
2018-01-16 15:12:45 -08:00
Trent Hensler 147c5e0ddf Merge branch '2.x' into fix-metaitemstack-keyword-replacer 2018-01-16 15:11:05 -08:00
DoNotSpamPls 1518db17f8 Delete .travis.yml (#1739) 2018-01-16 15:39:12 +00:00
Johnny Cao ef1e57f445 Performs pagination bounds check. Fixes #1509 (#1754)
Adds pagination bounds check Fixes #1509
2018-01-16 12:56:39 +00:00
Johnny Cao 87c6672212 Add ignore check for /me (#1768). Resolves #1767 2018-01-16 12:33:35 +00:00
Leomixer17 ab087e941e Update messages_cs.properties (#1760) @Leomixer17
Based on #1664 - thanks to @Uranusak for submitting the original PR.
2018-01-11 18:21:20 +00:00
Leomixer17 4f70d623a1 Update messages_pl.properties (#1759)
Includes translations by @RikoDEV.
2018-01-07 17:51:53 +00:00
md678685 ba143f8657 Move instructions to top of issue template
People weren't reading them when they were at the bottom, so they have been moved to the top to encourage people to read them. This has the tradeoff of filling up the Discord webhook embed, so I've added another instruction that doubles as proof of reading the instructions.
2018-01-07 14:55:25 +00:00
Ali Moghnieh b6aea0a5f8 Fix splash potion support for /potion. Resolves #1166 2018-01-07 02:22:31 +00:00
Drew Mitchell 50e2d27d5b Fix NPE in /clearinventory. Fixes #1755 (#1756)
Issue was a NullPointerException due to senderUser not being null-checked. I opted to place the couple of lines of code into the sender.isPlayer() check as opposed to null-checking.
2018-01-07 01:45:19 +00:00
Ali Moghnieh f0bf359df3 Allow KeywordReplacer to input replacements with underscore spacers.
Resolves #1725 and provides a less breaking fix for #1722.

----

Revert "Consume everything after lore as lore in MetaItemStack. Fixes #1722."

This reverts commit 5fa2ce7d9e.
2018-01-07 01:22:42 +00:00
Marten fd6717d06d Fixed a spelling mistake (#1752) @MartenM
Saw this when using the Dutch language file. Decided to update it.
2018-01-06 20:02:39 +00:00
Leomixer17 126046a039 Added missing translations (#1704)
* Added missing translations

* Update messages_da.properties

* Update messages_da.properties

* Update messages_de.properties

* Update messages_en.properties

* Update messages_es.properties

* Update messages_et.properties

* Update messages_fi.properties

* Update messages_fr.properties

* Update messages_hu.properties

* Update messages_ko.properties

* Update messages_lt.properties

* Update messages_nl.properties

* Update messages_nl.properties

* Update messages_pt.properties

* Update messages_pt_BR.properties

* Update messages_ro.properties

* Update messages_ru.properties

* Update messages_sv.properties

* Update messages_tr.properties

* Update messages_zh.properties

* Update messages_zh_HK.properties

* Update messages_zh_TW.properties

* Update messages.properties

* Update messages_da.properties

* Update messages_de.properties

* Update messages_en.properties

* Update messages_es.properties

* Update messages_et.properties

* Update messages_fi.properties

* Update messages_fr.properties

* Update messages_hu.properties

* Update messages_ko.properties

* Update messages_lt.properties

* Update messages_nl.properties

* Update messages_pt.properties

* Update messages_pt_BR.properties

* Update messages_ro.properties

* Update messages_ru.properties

* Update messages_sv.properties

* Update messages_tr.properties

* Update messages_zh.properties

* Update messages_zh_HK.properties

* Update messages_zh_TW.properties
2018-01-06 19:59:50 +00:00
seema84 6705513cb3 Add [world] to /tppos usage (#1744) 2018-01-03 20:39:12 +00:00
Leomixer17 28fb18b6c7 Added a missing translation to messages_it.properties (#1740) 2018-01-02 10:18:36 +00:00
Leomixer17 17bb5fe1da Update messages_it.properties (#1656)
* Update messages_it.properties

* Added missing translation

* Fixed double "="
2018-01-02 00:33:55 +00:00
md678685 3e908b9c01 Update issue template to give clearer instructions 2017-12-31 18:18:28 +00:00
Trent Hensler 8977425475 Merge pull request #1734 from N3FS/sort-messages
Sort messages keys alphabetically
2017-12-29 13:49:30 -06:00
Dylan Keir 8f92e3f217 Fix JDK9 issue (#1713) 2017-12-29 14:46:09 +00:00
md678685 f07f132cfd Sort messages keys alphabetically 2017-12-28 13:56:14 +00: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
Trent Hensler cd7e0963ce Merge pull request #1724 from Drkmaster83/2.x
Implements PR#1516 - TPPos World-Teleport Permissions
2017-12-25 18:24:01 -06:00
Drkmaster83 9dc58948b2 Implements PR#1516 - TPPos World-Teleport Permissions
https://github.com/EssentialsX/Essentials/issues/1516
Considerations:
• TPPos on a target doesn't consider the target's world access permissions, reminiscent of the TP A to B command.
2017-12-25 01:08:08 -06: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
Ali Moghnieh d16e67c51e Remove debug message. 2017-12-22 20:01:58 +00:00
Ali Moghnieh 5fa2ce7d9e Consume everything after lore as lore in MetaItemStack. Fixes #1722. 2017-12-22 19:50:33 +00:00
Ali Moghnieh 0a0c45238c Merge branch '2.x' of github.com:EssentialsX/Essentials into 2.x 2017-12-22 19:46:41 +00:00
delbertina 3d33bbc33d Added 8 new messages for "...Reason" versions of mute messages and implemented em. 2017-12-20 00:35:51 -06:00
Trent Hensler ea36ee37a2 Use correct value 2017-12-19 00:22:00 -08:00
md678685 a907dab432 Show tempban expiry on join. Fixes #1680
Outputs a different message with the expiry included.

Add unlocalised tempbanJoin to locale files

Outputs a different message with the expiry included.
2017-12-19 00:08:42 -08: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
Francois Robinson 9a3b4db387 Added quotes to afk-list-name (#1696)
The custom text may not parse properly if the quotes are missing. By adding them to the default config, just like on lines `443` & `447`, it will discourage making the typo by mistake.
2017-12-18 16:40:59 +00: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
Trent Hensler cdabe4a46e Readme update 2017-12-14 12:30:13 -08:00
Trent Hensler 29bc7ca19e Update live support 2017-12-14 12:26:16 -08:00
Trent Hensler 36ee10a52b Add discord and update links in readme 2017-12-14 11:55:28 -08:00
Trent Hensler 1a820ad9b7 Initial removal of item IDs.
We do not rely on Bukkit's item ids anymore, though we still support them in commands via a mapping built off of the items.csv.
2017-12-12 22:06:25 -08:00
md678685 dcbc106e62 Fix powertools when clicking in air (#1657)
Should restore behaviour prior to #1534 and fix #1622.
2017-12-06 08:37:52 +00:00
Lax cdf777384e Add server logs to the issue template. (#1669) 2017-12-03 15:26:39 +00: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
md678685 3a6f04e461 Fix Commandclearinventoryconfirmtoggle class 2017-11-15 18:17:29 +00:00
Marten d36f6e45de Added 4 messages to messages_NL (#1629)
Added 4 missing messages to the language file.
Only did those that were also found in the EN file.
2017-11-14 10:49:45 +00:00
Ali 'SupaHam' M f8ddb50140 Rename Commandclearconfirmtoggle.java to Commandclearinventoryconfirmtoggle.java 2017-11-13 12:46:15 +00:00
Ali 'SupaHam' M be076509f2 Implement clear confirmation (#1623)
Introduces:
- `clearinventoryconfirmtoggle` command with shorter aliases
- `confirmClear` boolean in UserData
2017-11-12 16:44:53 +00:00
Minecrell 73457453bb Avoid using reflection for things SnakeYAML supports directly now (#1634)
Fixes #1631 properly.

e7ebc94a9e added a workaround to the
SnakeYAML constructor to avoid errors when unknown properties are
used in the storage files. Back then, it was necessary to copy the
method to catch the exception thrown when an unknown property was
encountered.

However, SnakeYAML 1.12 (included in Spigot 1.6.2+) added a method
to ignore missing properties without overriding parts of the
SnakeYAML implementation.

Delete the old workaround and make use of
PropertyUtils.setSkipMissingProperties(true) to achieve the same
effect.
2017-11-10 18:01:29 +00:00
Ali Moghnieh 3091849ff8 Improve confirmPay documentation. 2017-11-04 11:41:26 +00:00
João Paulo 5136eb84f4 Update messages_pt_BR.properties (#1616) 2017-11-01 22:03:37 +00:00
Ali 'SupaHam' M c14d565b56 Support mail chat formatting via essentials.mail base permission. (#1611)
`essentials.mail.url`, `essentials.mail.color`, etc.
2017-10-29 01:16:04 +00:00
Ali 'SupaHam' M 57e87d9d4e Switch ci repository to ci.ender.zone. (#1610) 2017-10-29 01:11:28 +00:00
Ali 'SupaHam' M c1eccf499e Add Mirror link to README (#1598) 2017-10-22 18:11:43 +01:00
Ali 'SupaHam' M e5b76083b7 Change CI link to ci.ender.zone (#1597) 2017-10-22 18:04:39 +01:00
Azewilous a8d9139b6c [Feature] Added new property 'socialSpyMsgFormat'
This feature allows the user to alter the format in which a socialSpy direct messages is seen.
2017-10-22 14:32:17 +01:00
Jacek Maciejak 703186e931 Update messages_pl.properties (#1493) 2017-10-22 10:28:49 +01:00
Andronachi Marian e6fc459080 Update player activity on PlayerInteractEvent. 2017-10-22 10:25:49 +01:00
Francois Robinson 90feb9941f Fixed 'sumbol' typo in config.yml 2017-10-22 10:04:54 +01:00
Minecrell 2c4ff35796 Ensure LOGGER is not equal to plugin logger before setting parent (#1570) 2017-09-30 16:51:32 +01:00
Platinteufel 13ccabecf2 Update messages_de.properties (#1520)
* Update messages_de.properties

* Update messages_de.properties
2017-09-27 12:16:29 +01: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
md678685 ed5aa1f469 Alter config options for EssentialsX Spawn listeners (#1491)
* Add spawn-join-listener-priority setting
* Make "none" an option for priority settings
* Register each listener with separate priorities
* Add note to spawn-join-listener priority
    Warns about effect on spawn-on-join
2017-09-16 15:23:56 +01:00
Josh b34697040a Update spawner blockstates (#1536)
Fixes #1525.
2017-09-14 07:36:39 +01: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
Luck 430f08b25f Add LuckPerms to "specialCasePlugins" in SuperpermsHandler (#1518) 2017-08-27 22:20:48 +01:00
md678685 f85170eea3 "1.7.10 is no longer supported" in README (#1512) 2017-08-24 12:34:01 +01:00
Lax 5a0ec91159 Link to new support IRC channel (#1511) 2017-08-24 12:33:43 +01:00
md678685 a049a03faa Catch NullPointerExceptions in SLPE (#1463)
* Catch NullPointerExceptions in SLPE
* Use the caught NPE's stacktrace
    Makes thrown exception actually useful
2017-08-21 10:40:23 +01:00
Ali Moghnieh 365ae356bd Format currency correctly by placing negative sign at beginning.
This is forcefully placed at the beginning of the formatted currency because of how `currency` message is customisable. Until a better solution arises this shall stay.
2017-08-19 20:11:21 +01:00
md678685 04755cee33 Fix version replacements and add version to config (#1492)
* Add version to newly created config files
* Fix version replacement in item map and messages
* Add EssX version number
2017-08-19 10:47:47 +01:00
md678685 e4fbe28f95 Add EssX version 2017-08-18 11:32:04 +01:00
md678685 1bc0768683 Fix version replacement in item map and messages 2017-08-18 11:24:29 +01:00
md678685 1f42e1e2c1 Add version to newly created config files 2017-08-18 11:24:04 +01:00
flcmc 91b2622ba2 Turn off god mode on login if player doesn't have the permission (closes #1445) (#1475) 2017-08-13 16:42:59 +01:00
flcmc eb341c0704 Make {player} referencing powertools activate only when the user has powertools enabled (#1474) 2017-08-13 16:03:46 +01:00
Leomixer17 09eecb1c3b Translated banJoin and banIpJoin (#1470) 2017-08-12 18:13:31 +01:00
flcmc 1562a8f3ca Implement tab completion for seen and whois. (#1440) 2017-08-12 14:42:57 +01:00
Ashazi 13fbd31124 Prevent flaming arrows damage from vanished and godmode players. (#1462) 2017-08-12 14:27:51 +01:00
Daniel Saukel 433ebe4a21 Fix a few GER translation issues (#1421) 2017-08-12 14:23:33 +01:00
Ali Moghnieh e5c7ba72e5 Add custom join ban messages. #420
blaze it
2017-08-12 13:46:27 +01:00
Ali Moghnieh 203d6561ac Allow unbreakable to not take any arguments, defaulting to true. Fixes #377 2017-08-07 14:05:20 +01:00
Florian CUNY 117704b0bc Added missing translations to messages_fr.properties (#1444)
Related to https://github.com/drtshock/Essentials/issues/1380
2017-08-07 13:25:03 +01:00
md678685 7958cd0b88 Add ability to click helmet slot to equip item. #960 2017-08-04 17:24:43 +01:00
Ali Moghnieh 51f2a04958 Fix import errors. 2017-08-04 16:26:57 +01:00
md678685 a27eb17684 Merge remote-tracking branch 'upstream/2.x' into 2.x-upstream 2017-08-04 12:09:03 +01:00
md678685 05d2b6ccda Fix 1.12.1+ NSME in /lightning 2017-08-04 12:08:55 +01:00
md678685 ec61ffcaad Fix 1.12.1+ NoSuchMethodError in /break (fixes #1438) 2017-08-04 12:08:40 +01:00
md678685 ed0ad87632 Use Paper's new ServerListPingEvent methods if present (#1436)
* Use Paper's new ServerListPingEvent methods if present
2017-08-04 12:00:25 +01:00
Adam Williams 4802744ce7 Spacing for antibuild place message in German (#1175)
#drtshock 2017-03-22 20:59:27 UTC
2017-08-04 00:47:06 +01:00
Uranusak adf7e22324 Update messages_cs.properties (#1216) 2017-08-04 00:43:07 +01:00
Esteban Juarez Rodriguez 09f63364dc Update of messages_es.properties (#1254)
Some of the current translations were modified and the new content was translated.
2017-08-04 00:41:50 +01:00
core.equip 8c256664b2 Fix escaping in german translation. (#1262) 2017-08-04 00:35:11 +01:00
EmanhMC 0354ffa4f8 Clarify java version requirements in README.md (#1299) 2017-08-04 00:28:41 +01:00
Leomixer17 d5f15b8283 Update messages_it.properties (#1316)
* Update messages_it.properties
2017-08-04 00:27:39 +01:00
NyanMeow c4009233a3 Update messages_zh.properties (#1330)
* Update messages_zh.properties
2017-08-04 00:25:09 +01:00
Leomixer17 e02bceaf5d Clarify mailClear deletion of mails (#1383)
* Update messages.properties
2017-08-04 00:11:47 +01:00
Kaleb M 8796dbeb56 [Fix] Essentials signs validity (#1402)
* [Fix] Essentials signs validity

Any sign in the format of &1[...] was a valid sign according to essentials, but 3rd party plugins with the same sign format would be treated equally (cancelling nearby explosions, etc)

Valid signs after this fix are:
- In the format of &1[...] as before
- Are essentials signs and enabled in the essentials config

* Revert "[Fix] Essentials signs validity"

This reverts commit 60d95b6585.

* [Fix - v2] Essentials signs validity

Any sign in the format of &1[...] was a valid sign according to essentials, but 3rd party plugins with the same sign format would be treated equally (cancelling nearby explosions, etc)
2017-08-04 00:09:12 +01:00
Florian CUNY fd63a7df4e [Feature] Added an option to spy chat messages from muted players (#1430)
Related to https://github.com/drtshock/Essentials/issues/1420
2017-08-04 00:04:42 +01:00
md678685 7fbc721db6 Fix usage of deprecated getTargetBlock (#1435) 2017-08-03 23:33:55 +01:00
Ali Moghnieh 210494d0d1 Support EntityPickupItemEvent. 2017-07-28 20:13:59 +01:00
Ali Moghnieh 9963476218 Write NMSVersion parsing special case for FakeServer. 2017-07-28 20:13:13 +01:00
md678685 50f2e7a95f Add a delay for sending the MOTD (#1396)
* Add delay-motd setting
* Move MOTD to Runnable
* Refactored according to comments
* Delay motd loading as well as sending
2017-07-28 19:20:44 +01:00
md678685 d7685dc1bc Add UUID to /whois (#1394)
* Add UUID to /whois

* Add untranslated English messages

I'm not sure whether "UUID" necessarily needs translating for most languages, but I've put it in all of them so that they can be translated if needed.

* Hi there o/
2017-07-15 18:38:09 +01:00
md678685 301a3a72df Check for essentials.warp.list permission on /warp tab complete (#1378) 2017-07-10 23:07:54 +01:00
CreedTheFreak 518a43db9c [Fix] Disallow muted players to use /r (#1375) 2017-07-09 15:17:07 +01:00
Ali Moghnieh 243e69649f Be more verbose in handleCrash(Throwable). 2017-07-03 14:24:43 +01:00
Ali Moghnieh 781204aa20 Trim comma separation in items.csv parsing. 2017-07-03 14:23:36 +01:00
md678685 9a714eb537 Add an issue template (#1362) 2017-07-03 04:14:58 +01:00
Ali Moghnieh d5cbfefc21 Set use-bukkit-permissions to true by default.
See #1356 for more information.

This change was made with the confident presumption that the use of built-in EssentialsX permissions is very very low compared to those who use feature-complete permission plugins.
2017-06-30 21:12:55 +01:00
Ali Moghnieh 12930cfce4 Return online players instead of nothing when tab completing. (Fixes #1331) 2017-06-29 03:41:13 +01:00
Ali Moghnieh 298c292ffb Amend items.csv to support potions in all items.
This commit makes use of 3fba6e9a which implements the ability to parse NBT in `items.csv`.
2017-06-29 03:30:35 +01:00
NJDaeger 341263b934 Removed null value from AbstractVaultHandler (#1327)
I'm in the process of writing a permissions plugin, and every time I try to talk it threw an error. The error was caused by this null value that was existing. I removed it and changed it to get the Player's world name. This should fix my error.
2017-06-24 15:41:51 +01:00
Ali Moghnieh 11a03bbce9 Add notify-player-of-mail-cooldown config option.
This feature allows for the ability to specify a cooldown for how often individual players are notified of their outstanding unread mails.
2017-06-22 22:54:51 +01:00
Ali Moghnieh 3831464665 Fix /condense functionality after 1.12. (#1298)
Prior to this commit `/condense` would return the first best item to condense an ItemStack into, with no consideration of better forms of condensation.

This commit adds a local variable `bestRecipes` which stores all the valid recipes and sorts through them for the best, then picks out the best. The best recipe is defined by a compare(o2, o1) where o1 and o2 are integers of the SimpleRecipe's input ItemStack amount.
2017-06-22 22:21:42 +01:00
Ali Moghnieh 2fe05b4ff4 Fix silent error when creating signs.
If the signFormatSuccess message is empty an error occurs silently that prevents the sign from being created from Essentials behalf. This commit tackles that issue by creating `getSuccessName(IEssentials)` and invoking it where possible to notify the console when this error occurs.
2017-06-19 05:18:33 +01:00
Ali Moghnieh ec3dc50e20 Fix typo in OfflinePlayer#setBanned(boolean). 2017-06-18 21:32:24 +01:00
Ali Moghnieh 171b2b6a37 Capitalise Parrot in Mob. 2017-06-18 21:00:02 +01:00
Ali Moghnieh 14a02c0602 Update to 1.12. :D
To the best of my knowledge ;)
2017-06-18 19:54:04 +01:00
Ali Moghnieh 34e3582557 Reorder items.csv based on item id (and date of creation). 2017-06-18 19:24:55 +01:00
Ali Moghnieh 01592e9770 Rename darkgreeysclay to darkgreysclay in items.csv. 2017-06-18 16:53:19 +01:00
Ali 'SupaHam' M 3fba6e9ad0 Add NBT support in items.csv (#1276)
This commit adds a new 4th column reading in `items.csv` to enable the ability to specify NBT data for newly constructed items.
2017-06-18 16:30:54 +01:00
Ali 'SupaHam' M bbe0ca9302 Implement tab completion for all commands. (#1282)
List of supported commands:
```
/afk
/balance
/balancetop
/ban
/banip
/bigtree
/book
/broadcastworld
/burn
/clearinventory
/condense
/delhome
/deljail
/delwarp
/eco
/enchant
/enderchest
/essentials
/exp
/ext
/feed
/fireball
/firework
/gamemode
/getpos
/give
/hat
/heal
/help
/helpop
/home
/ignore
/invsee
/item
/itemdb
/jump
/kick
/kill
/kit
/lightning
/list
/mail
/me
/msg
/mute
/near
/nick
/nuke
/pay
/potion
/powertool
/ptime
/pweather
/recipe
/remove
/repair
/sell
/showkit
/skull
/speed
/tempban
/thunder
/time
/togglejail
/tp
/tpa
/tpaall
/tpahere
/tpall
/tphere
/tpo
/tpohere
/tppos
/tree
/warp
/weather
/world
/worth```
2017-06-11 01:17:43 +01:00
Ali Moghnieh e572788a8c Disable /recipe for 1.12 until duplication bug can be fixed. #1289 2017-06-09 15:02:56 +01:00
Pokechu22 4c0857fbb5 Implement tab completion framework (#1203) 2017-06-06 01:31:41 +01:00
Pokechu22 44ed1e2d44 Add eclipse files to .gitignore 2017-06-06 01:08:34 +01:00
Ali Moghnieh 8fd532c648 Translate now instead of static "now" in DateUtil. 2017-06-04 20:57:06 +01:00
Ali Moghnieh 7c0fa46b4d Add playtime to /whois. #1212 Courtesy of @molor. 2017-06-03 09:31:53 +01:00
Ali Moghnieh 85d0644868 Readd messages from c28d749. 2017-05-31 14:19:18 +01:00
md678685 4bd3cffc4e Readd missing messages (#1271) 2017-05-31 14:05:18 +01:00
md678685 3ecebdc758 Add missing enable and disable functions to Metrics class (#1270)
* Replace mcstats with bStats

Won't show up on the bStats website, until @drtshock or someone else signs up and creates a Bukkit plugin named "EssentialsX" on the bStats website. If you want to test, you can change `pluginName` to `"EssXmdtest"`, or any other value as desired.

* Add missing enable and disable functions to Metrics class
2017-05-31 11:31:08 +01:00
md678685 f13e355010 Replace mcstats with bStats
Won't show up on the bStats website, until @drtshock or someone else signs up and creates a Bukkit plugin named "EssentialsX" on the bStats website. If you want to test, you can change `pluginName` to `"EssXmdtest"`, or any other value as desired.
2017-05-31 03:50:01 +01:00
Ali Moghnieh c28d749548 Create /tpacancel.
`/tpacancel` allows tp requesters to cancel sent requests before the target client can accept them. This aids in combatting long-lived tp requests in PvP environment.

`/tpacancel <player>` cancels all a tp request sent to <player> only.
2017-05-31 03:30:05 +01:00
Ali 'SupaHam' M d0760ddd04 Register SWEEPING_EDGE enchantment. Resolves #1263 2017-05-25 01:36:33 +01:00
Ali Moghnieh af5d2c2fca Remove Supervisor support.
This reverts commit 442d97a1b1, fcbd3deb6b, and 6231a25413.

Due to the lack of proper dependency deployment and availability users are unable to build EssentialsX without doing some manual installations. Until issue is resolved Supervisor support is dropped.
2017-05-04 13:55:18 +01:00
Ali Moghnieh 4bfabaa1d3 Check if getTeleportRequest() is null in /tpdeny. Fixes #1229. 2017-05-04 13:46:31 +01:00
Platinteufel 747420b4c8 Update messages_de.properties (#1091) 2017-02-12 09:52:20 -06:00
Maxetto 78b710dc22 Set PORTAL as an Unsafe Destination 2017-01-20 09:17:11 -06:00
vemacs 7973f544ff Revert "Fix broken add-prefix-in-playerlist behavior", as it seems to break more things for other users 2017-01-20 09:08:36 -06:00
vemacs 0b1e1676d0 Add iron nugget to items.csv (resolves #1049) 2017-01-17 21:55:35 -06:00
md_5 705c1c60c8 Fix erroneous usage of setAmount(0) on mirrored ItemStacks 2017-01-17 21:49:05 -06:00
vemacs abfec5a60f Revert "Fix getItemInMainHand behavior breaking /worth (#1053)" 2017-01-17 21:46:04 -06:00
vemacs ca28d8aa84 Fix getItemInMainHand behavior breaking /worth (#1053) 2017-01-05 12:13:08 -05:00
Maxetto 198d852995 Fix broken add-prefix-in-playerlist behavior 2017-01-04 11:48:01 -05:00
Ali Moghnieh 5f83766dc1 Implement player based toggle for pay confirmation prompts. Fixes #1032
This commit adds a new `/payconfirmtoggle` command with `/payconfirmon` and `/payconfirmoff` as well.
2016-12-25 18:08:16 +00:00
Ali Moghnieh 442d97a1b1 Add Supervisor to softdepend in plugin.yml.
Add SupaHam to authors list.
2016-12-18 15:58:58 +00:00
Ali Moghnieh fcbd3deb6b Exclude Spigot from Supervisor dependency. 2016-12-18 15:14:43 +00:00
Ali 'SupaHam' M dadc6b2d3a Implement confirmation dialogue for /pay. (#1002) 2016-12-18 15:03:03 +00:00
Ali Moghnieh 6231a25413 Initial implementation of Supervisor.
EssentialsReportContext provides all online players' userdata files if report level is 400 or higher, as well as config.yml if report level is over 200.
2016-12-18 15:00:22 +00:00
Ali Moghnieh bc08b11011 NOOP sendTitle in OfflinePlayer. 2016-12-18 14:17:16 +00:00
vemacs 36b08e9b1d Fix compile 2016-12-12 10:09:43 -06:00
vemacs d73ec779e0 Fix #1015 2016-12-09 19:11:04 -06:00
Ali Moghnieh 6bc9f2140c Catch Exception in Commandpay for payUser call. 2016-12-03 15:23:53 +00:00
Luke Anderson a6f1e305ef [Fix] When the minimum pay amount is zero, users are unable to pay zero. 2016-12-03 14:32:50 +00:00
Ali Moghnieh 5fda1d018b Add support for spawn_egg durability value in Minecraft 1.11. 2016-12-02 17:02:04 +00:00
vemacs c919eba206 Fix missing setVillager call 2016-11-28 17:25:29 -06:00
vemacs 61b3ca531c Fix build 2016-11-28 17:20:24 -06:00
vemacs 96164f5851 Restore basic pre-1.11 compat 2016-11-28 17:13:36 -06:00
Roy Curtis 4102b11f15 More items.csv fixes (#992)
* Adjust ID for beetroot soup from Pocket Edition ID (459) to Java ID (436)
* Fix two IDs for strength arrows
2016-11-27 17:53:39 +00:00
Ali Moghnieh 3c18efc4a6 Fix /tpaccept timing out requests too soon. 2016-11-23 13:41:11 +00:00
Roy Curtis cfc2b7ff2f Add 3rd column to Purpur Stairs items.csv entries
Purpur Stairs in items.csv are missing their data column. This breaks code that parses `items.csv` and expects a consistent number of columns.

For example, this breaks the Levitate command library: https://github.com/KennethWussmann/Levitate/blob/a8a57e95126ca62087a88a18c26ee7f1e846fe04/src/main/java/de/ketrwu/levitate/syntax/ItemStackSyntax.java#L94
2016-11-22 20:55:04 +00:00
Ali Moghnieh ad94cca95b Check for timeout in /tpa and /tpaccept. Fixes #818.
This commit adds a method called hasOutstandingTeleportRequest() in IUser - implemented fully in User.
2016-11-22 20:39:31 +00:00
Ali Moghnieh 6ade8132af Implement NOOP openMerchant(Merchant, boolean) in OfflinePlayer. 2016-11-21 18:11:40 +00:00
Ali Moghnieh e5b5994593 Disallow negative number input for /pay. 2016-11-21 18:05:17 +00:00
Ali Moghnieh 944ddf8d70 Further changes for 1.11 update.
- Dropped usage of deprecated methods for a cleaner future.
- Zombies no longer throw errors in SpawnMob due to setVillager(false).
- Removed MobData where they have been replaced with actual entities.
2016-11-20 20:23:01 +00:00
Ali Moghnieh 8b0659a2b4 Update to 1.11.
- Support new enchantments.
- Support new mobs.
- Rename MobData WHITHER_SKELETON to WITHER_SKELETON.
- implement NOOP methods of new API methods for fake classes.
- Amend item dictionary.
2016-11-20 16:03:56 +00:00
Ali Moghnieh 35388c3b19 Add spawn-on-join examples in config.yml. 2016-10-30 13:47:56 +00:00
Ali Moghnieh 27ab90ab2a Improve spawn-on-join with ability to specify groups. 2016-10-30 13:29:21 +00:00
vemacs d41af02ade Fix cache invalidation when resetting user 2016-10-14 08:25:53 -04:00
vemacs e0a578d06c Fix #857 2016-10-12 12:35:25 -05:00
Trent Hensler db47460a79 Too much http 2016-09-08 13:07:13 -07:00
Trent Hensler a1bcbdc181 Remove ess3 repo and use our own. 2016-09-08 12:58:39 -07:00
NDGAM3R d1dda6a166 Add normal fire resistance potion to items.csv (#875) 2016-09-05 22:28:51 -05:00
Trent Hensler 7290dbc5a5 Merge pull request #861 from Markersx/fix-version
[Fix] Versions
2016-08-31 10:28:44 -07:00
Mark 8bc47c45a4 Fix version EssentialsXMPP 2016-08-30 19:31:09 -07:00
Mark 1f5b659f2d Fix version EssentialsSpawn 2016-08-30 19:30:42 -07:00
Mark a591dba8ef Fix version EssentialsProtect 2016-08-30 19:30:13 -07:00
Mark 85d6c836a8 Fix version EssentialsGeoIP 2016-08-30 19:29:45 -07:00
Mark 7498a5f983 Fix version EssentialsChat 2016-08-30 19:29:07 -07:00
Mark 63b5068591 Fix version EssentialsAntiBuild 2016-08-30 19:28:37 -07:00
Trent Hensler c54da35a39 Fix version 2016-08-29 18:44:55 -07:00
Trent Hensler 6789e5c0de Merge pull request #850 from md678685/patch-1
Remove extraneous + from Commandfly
2016-08-29 18:15:50 -07:00
md678685 1fed66d652 Remove extraneous + in Commandfly 2016-08-27 10:01:26 +01:00
Faris Rehman f42904e5ae Add FlyStatusChangeEvent (#835) 2016-08-26 21:45:38 -05:00
Ryan 58828d7924 Don't force player out of vehicle on teleport. Fixes #582 (#833) 2016-08-26 21:29:22 -05:00
md678685 ee64f7c4ff [Fix] Remove vanished players from server list ping (#837) (#841)
Add listener for ServerListPingEvent and remove any vanished players.
Also refactored EssentialsPluginListener serverListener to
pluginListener
2016-08-26 21:27:52 -05:00
Nathan Guedes 3c0424226e Update messages_pt_BR.properties. (#778) 2016-08-20 21:16:13 -04:00
Ryan dd226dfdcf Implement MuteStatusChangeEvent. Fixes #819 (#832) 2016-08-20 21:13:26 -04:00
Ryan 16e05cc17b Remove double locale set call. (#826) 2016-08-19 09:23:44 -04:00
Blinky™ 13bceb9f5d Update Vault repo 2016-08-17 14:41:00 -06:00
Ali Moghnieh 03c652cd55 Fix command cooldowns command matching. 2016-08-07 15:58:34 +01:00
Ali Moghnieh 00301b26e6 Add debug for command cooldowns. 2016-08-06 17:53:24 +01:00
Ali Moghnieh 611429b6f6 Use afk player-list name in User#setDisplayName(). 2016-08-06 17:45:54 +01:00
Platinteufel 34979c8e84 Update messages_de.properties 2016-08-05 02:25:00 +02:00
Ali Moghnieh 3a6da5cd26 Add 1.10 blocks and Polar Bear egg entries in items.csv. 2016-08-04 17:41:14 +01:00
Ali Moghnieh 9c18b94ec8 Fix shulkeregg entries in items.csv 2016-08-04 17:19:39 +01:00
Ali Moghnieh 5187be5d02 Set default currency-symbol-format-locale to US locale. 2016-08-04 16:38:31 +01:00
Nathan Guedes 1c009e1ebc Update messages_pt_BR.properties.
Translate the last lines that was in english and a line in european portuguese.
2016-07-28 23:57:33 +01:00
Ali Moghnieh 8927fe9ea9 Remove isHidden() check for idling kick. Resolves #773 2016-07-28 19:58:04 +01:00
Ali Moghnieh 63b5cb9ec7 Add prefix/suffix toggle for playerlist. Resolves #771
This commit adds two new configurable options:
- `add-prefix-in-playerlist`: enable prefix in playerlist
- `add-suffix-in-playerlist`: enable suffix in playerlist

These were added to prevent very long names in the playerlist.
2016-07-28 17:17:26 +01:00
Ali Moghnieh 30d5fbdf8d Revert "Add mending enchantment to serializer."
This reverts commit 743ac51c4c.
2016-07-28 16:57:06 +01:00
Ali Moghnieh 5960f55339 Fix banner/shield deserializer with PatternType. 2016-07-26 22:03:33 +01:00
Ali Moghnieh 743ac51c4c Add mending enchantment to serializer. 2016-07-26 22:02:50 +01:00
Ali Moghnieh 2493c655f8 Create /paytoggle command. Resolves #413 2016-07-26 16:23:34 +01:00
Ali Moghnieh f1d9cda5eb Create allow-bulk-buy-sell config option. Resolves #765. 2016-07-26 12:25:20 +01:00
Ali Moghnieh a76b20f1b5 Display time since AFK in /whois. Resolves #761.
This commit adds a getAfkSince() method to IUser.

This commit adds a whoisAFKSince message which is sent when a player is AFK, it follows the same format as whoisAFK which is still used. whoisAFK remains unchanged but is sent only when the player is not AFK.
2016-07-26 01:36:29 +01:00
Ali Moghnieh 017082c07a Check recipient socialspy exempt during PMs. Resolves #166 2016-07-25 13:10:06 +01:00
Ali Moghnieh 352c92b880 Implement Shield item serialization. 2016-07-25 12:06:24 +01:00
Ali Moghnieh 948cce4ceb Remove whitespace before colon in SocialSpy broadcast. 2016-07-23 14:59:20 +01:00
Ali Moghnieh 6fe87184ae Add socialSpyPrefix message. 2016-07-23 00:30:49 +01:00
Ali Moghnieh c4c303dbfb Don't socialspy broadcast raw /msg and /r. 2016-07-23 00:09:18 +01:00
Ali Moghnieh 87adbb477d Allow bulk buy/sell when sneaking. Resolves #65 2016-07-22 23:56:26 +01:00
Ali Moghnieh 3245ce10ac Prevent multiple tpa requests in a row. Resolves #59 2016-07-22 20:51:47 +01:00
Ali Moghnieh 5540683013 Remove +180 on yaw in . 2016-07-22 16:26:56 +01:00
Ali Moghnieh 75d1254dda Implement better PM social spy. Resolves #27 2016-07-22 15:52:53 +01:00
Ali Moghnieh 83b944eb4b Use User#isAuthorized() instead of Player#hasPermission(). 2016-07-22 15:33:26 +01:00
Ali Moghnieh 6cbb8c846b Make old /createkit toggleable in config. 2016-07-13 23:25:20 +01:00
Ali Moghnieh e0d69d05eb Format {UNIQUE} in KeywordReplacer. 2016-07-13 22:54:52 +01:00
Ali Moghnieh 4f971ad8e5 Change /createkit functionality.
/createkit pastebins the current inventory into gist.github.com and returns a URL with the kit code.
2016-07-13 22:43:20 +01:00
Ali Moghnieh fa59a3f65c Fix up messages_pt_BR.properties. 2016-07-13 22:08:19 +01:00
Ali Moghnieh 8d921d78c5 AHHHH it's Hydra! 2016-07-13 22:04:44 +01:00
Ali Moghnieh 953e44c4a4 Remove the HEAD! 2016-07-13 21:53:46 +01:00
MisterSanglad b664159231 Update messages_fr 2016-07-13 14:32:17 +02:00
Ali Moghnieh 5867cd2e1b Merge branch '2.x' of github.com:drtshock/Essentials into 2.x 2016-07-12 20:39:09 +01:00
Ali Moghnieh 535fb43915 Format {UNIQUE} in custom join message. 2016-07-12 20:36:55 +01:00
Blinky™ 0952115776 Switch to transparent images for our dark mode users 2016-07-12 11:12:01 -06:00
Ali Moghnieh 79401c3cf7 There's a reason we test code. Thanks, hobbit! 2016-07-12 00:46:08 +01:00
Ali Moghnieh 0ab9f04ea4 Document no-god-in-worlds feature usage in code. 2016-07-12 00:03:08 +01:00
Ali Moghnieh 04f14285e7 Directly teleport Player in EssentialsSpawn when joining. 2016-07-11 15:12:47 +01:00
Ali Moghnieh 2a2aef53fb This is the real fix for MessagingTests. 2016-07-11 00:47:25 +01:00
Ali Moghnieh 3651e672d4 Fix MessagingTest units. 2016-07-11 00:43:43 +01:00
Ali Moghnieh 9dfa650d7e Merge branch 'create-afk-message' into 2.x 2016-07-10 22:47:54 +01:00
Blinky™ a0a166b553 Properly align logo 2016-07-10 14:38:21 -06:00
Blinky™ e7f4b46de8 Bold logo font 2016-07-10 14:25:02 -06:00
Blinky™ b5148cd0ec Update logo in readme 2016-07-10 14:23:36 -06:00
Ali Moghnieh e90b0c28c6 Disallow mute players and unauthorized players from setting AFK message. 2016-07-10 20:27:48 +01:00
Ali Moghnieh 3a439bcdb5 Merge branch '2.x' into create-afk-message 2016-07-10 19:56:23 +01:00
Ali Moghnieh 23e8498b47 Clear trailing whitespaces in ISettings and Settings. 2016-07-10 17:58:15 +01:00
Ali Moghnieh c9f1b0fdc5 Add the option to disable disabled-sign name protection. (#699)
This allows EssentialsX users to use other plugins that provide signs such as [Kit] and not have EssentialsX interfere with the final sign name.
2016-07-10 17:45:43 +01:00
Ali 'SupaHam' M 19f6510840 Create VanishStatusChangeEvent. (#661) 2016-07-10 09:09:53 -06:00
vemacs 0a1feaf044 Fix Vault-based permission logging (forgot after refactor) 2016-07-09 18:42:42 -06:00
Guilherme Penedo 890c32949d Updated and changed most of the pt translation 2016-07-08 13:53:49 +01:00
Dima Melikhov 8b37bb5bd7 Update messages_ru.properties 2016-07-07 20:52:43 +01:00
Guilherme Penedo 1aff0c2dcb Update messages_pt_BR.properties
Fixed special characters, spelling mistakes, (some) gramatical mistakes. Added invalidBanner and commandCooldown messages
2016-07-07 20:34:19 +01:00
Nathan Guedes a7f137d122 Update messages_pt_BR.properties with corrections in accents, spaces, commas and dots. 2016-07-07 19:12:06 +01:00
Benjozork 148fa7d6da Fixed french translations 2016-07-07 18:13:35 +01:00
Ali Moghnieh 20594d2523 Add essentials.commandcooldowns.bypass permission. 2016-07-07 17:24:28 +01:00
Ali Moghnieh 142315140e Implement NOOPs in OfflinePlayer instead of throwing exceptions.
This resolves issues like #721.
2016-07-07 16:58:44 +01:00
Ali Moghnieh 8d3d2ebd50 Enable longer display names/player list-names feature
For 1.8 servers and above.
2016-07-07 04:59:09 +01:00
Ali Moghnieh e674056b3a Create NMSVersion for better backwards compatibility. 2016-07-07 04:45:27 +01:00
Trent Hensler 785bd5bfcf Merge branch 'SupaHam-custom-currency-formatting' into 2.x 2016-07-06 15:44:37 -07:00
Ali Moghnieh fb72555e6b Merge branch '2.x' into custom-currency-formatting 2016-07-06 21:22:23 +01:00
Ali Moghnieh 42f4d43682 Make _isNpcsInBalanceRanking private. 2016-07-06 21:22:13 +01:00
Ali Moghnieh caeb59ede4 Merge branch '2.x' into custom-currency-formatting 2016-07-06 21:21:24 +01:00
Ali Moghnieh 992ef5dc91 Add npcs-in-balance-ranking configurable option. Resolves #716. 2016-07-06 19:34:25 +01:00
Ali Moghnieh d37433e81c Merge branch '2.x' into custom-currency-formatting 2016-07-05 18:46:01 +01:00
vemacs d75e0ce26e Use string comparison for gamemode, fixes #703 2016-07-02 12:00:31 -06:00
Ali Moghnieh 09acbcdb05 Implement Command Cooldowns. Resolves #110 2016-06-30 12:52:28 -07:00
Ali Moghnieh 864dadab80 Add debug message in EssentialsSign. 2016-06-27 21:46:32 +01:00
Ali Moghnieh d174cea42e Do not apply starting balance for NPCs. Resolves #191
NPC balances are usually banks e.g. Factions plugin depending on EssentialsEco to provide economy functionality for the Faction.
2016-06-27 21:45:31 +01:00
Ali Moghnieh e95fad0453 Don't list NPCs in /baltop output. 2016-06-26 22:10:36 +01:00
Ali Moghnieh ebe6abd885 Make /tp parse arguments as double instead of integer. 2016-06-26 15:25:52 +01:00
Ali Moghnieh 0a563b91a2 Create teleport-to-center configuration option.
This option toggles whether essentials should rounds all teleportations off to the center of the block.
2016-06-26 15:21:35 +01:00
vemacs 5cbcd7469b Nullcheck user iteration in EssentialsTimer (fixes #675) 2016-06-25 09:47:06 -06:00
Ali Moghnieh dabcb51034 Allow colour codes in nickname-prefix. 2016-06-24 11:24:54 +01:00
Ali Moghnieh 0237d485bf Merge branch '2.x' into custom-currency-formatting. 2016-06-20 12:55:31 +01:00
Ali Moghnieh b673630a7e Implement spawn-on-join configuration.
Admins can now specify whether all joining players should be teleported to the user's group spawn when joining the server. Players can be assigned the essentials.spawn-on-join.exempt permission to become exempt from this feature.
2016-06-19 21:07:45 +01:00
Ali Moghnieh 282ec81af1 Implement configurable currency formatting.
This commit enables users of different countries around the world to configure currency formatting displayed to users in a familiar manner.

Prior to this commit US formatting (symbols) was forced upon users. This is now configurable via locale values e.g. en-US, de, fr-ch.

This commit adds two new configurations:
- currency-format
- currency-symbol-format-locale

One method ISettings#getCurrencyFormat()
2016-06-19 20:03:54 +01:00
Ali Moghnieh a267fb16b8 Ignore flight check on spectator mode.
If a player is in Spectator mode, we should not interfere with their flight. This is an extension to the already existing creative mode check.
2016-06-19 03:33:48 +01:00
Ali Moghnieh 795ffec8b8 Remove trailing space. 2016-06-18 21:38:20 +01:00
Ali Moghnieh dba9dab985 Make UserBalanceUpdateEvent's new balance mutable.
This commit makes it reliable to modify user balance from within events.
2016-06-18 18:33:51 +01:00
Ali Moghnieh abfa815cf1 Add space in userAFKWithMessage in messages_nl. 2016-06-18 18:21:36 +01:00
Ali Moghnieh 872b25e0c5 Merge branch '2.x' into create-afk-message 2016-06-18 18:20:45 +01:00
Ali Moghnieh 3fa810e329 Add space in userAFK messages_nl.properties. 2016-06-18 18:14:59 +01:00
Ali Moghnieh 4951c4822e Rename userIsAwayWithReason and userAFKWithReason to userIsAwayWithMessage and userAFKWithMessage respectively. 2016-06-18 17:54:21 +01:00
Ali Moghnieh 5842b5f51d Implement AFK messages.
This commit makes it possible for players to set an afk message to detail their reasoning for being away to other players. This can be especially useful for the /msg command; instead of replying the user is afk, it will specify why they are afk so the sender can act further on that information.

Two methods have been added to IUser: getAfkMessage() and setAFKMessage(String).

All locale files have two new messages: userAFKWithReason and userIsAwayWithReason. They all use the messages that do not have the suffix WithReason, i.e. userAFK and userIsAway. Furthermore, the userIsAwayWithReason will not utilise the second parameter, the reason, to prevent spam and unnecessary text in global chat. However, the second parameter ({1}) is available for use in userIsAwayWithReason. userAFKWithReason, which is sent to /msg senders, does use the {1} as it controllable spam by the command sender themselves.

/afk usage is now: /afk [player/message...]
2016-06-18 17:44:17 +01:00
Ali Moghnieh ac4a1565a1 Implement empty OfflinePlayer methods instead of NSY exceptions. 2016-06-18 14:08:58 +01:00
Ali Moghnieh 203e8b0a75 Broadcast mute notify with mute duration if present.
This commit adds a new locale message code muteNotifyFor, which takes three parameters: muter, muted, duration.
2016-06-18 14:00:51 +01:00
Ali Moghnieh c75594f314 Fix piston bug with AntiBuild.
Prior to this commit, BlockPistonRetractEvent#getRetractLocation() was being used, which is now deprecated after 4 years of when this code was written.
2016-06-18 04:08:15 +01:00
vemacs 690dbea924 Fix compile 2016-06-12 09:25:14 -06:00
vemacs e7c81504a9 Force legacy spawn egg provider for 1.8.x due to client rendering bug 2016-06-12 09:23:25 -06:00
vemacs fdd5bc5a8e Use more cached methods 2016-06-10 07:44:16 -06:00
vemacs 91bebabc7f Add polar bear spawning support 2016-06-09 20:19:59 -06:00
vemacs 5eec83f726 Remove old spawn egg providers in favor of reflection-based implementation 2016-06-09 19:25:45 -06:00
vemacs 827891f10a Add reflection based spawn egg provider 2016-06-09 19:18:07 -06:00
Trent Hensler f4fa24cd7f Build against 1.10 2016-06-09 10:07:22 -07:00
vemacs 2bf1f24db2 Update spawn egg provider to 1.10 2016-06-08 20:33:03 -06:00
Blinky™ 34c6155fe9 Update build instructions 2016-05-21 14:46:49 -06:00
vemacs 3ead31ef14 Update human name 2016-05-21 14:43:36 -06:00
vemacs d0ea32dfa1 1.9.4 spawn egg support 2016-05-21 14:15:07 -06:00
Trent Hensler 7c1a0ed719 Fix elytra wing item id. Resolves #578 2016-04-17 12:41:51 -07:00
Taybosquee b050b13aa3 Add 1.9 entries to item.csv 2016-04-10 11:32:25 -06:00
vemacs 60548e4523 Cleanup 2016-04-01 20:52:20 -06:00
vemacs 8fe002f820 Fix giving normal water bottles for 1.9 2016-04-01 20:50:03 -06:00
vemacs 65a2e942c4 Attempt fixing kit/createkit for splash potions in 1.9 2016-03-31 11:54:19 -06:00
Trent Hensler 4adb59ab98 Don't make artifact for GM 2016-03-29 17:09:22 -07:00
Trent Hensler fa0bbde236 Not more distributing groupmanager. 2016-03-29 16:59:36 -07:00
vemacs e5b1e6c0ad Stick override annotation 2016-03-28 19:51:16 -06:00
vemacs 731455649e [Experimental] Attempt supporting lingering potion type by passing it through 2016-03-28 19:38:53 -06:00
vemacs ec1215b227 Restore 1.8 compatibility 2016-03-28 17:42:33 -06:00
vemacs dcb14170b9 Fix meta setting (works for 1.9) 2016-03-28 17:31:25 -06:00
vemacs c266778c1e [Likely breaks 1.8 compatibility, will be fixed] Use non-deprecated methods 2016-03-28 17:21:57 -06:00
vemacs 8116ce39d7 [Experimental] Attempt restoring potion effect ID compatibility to 1.9 2016-03-28 16:54:17 -06:00
vemacs 8167002092 Fix compile 2016-03-28 10:36:02 -06:00
Trent Hensler 5cddb84a58 Update travis 2016-03-27 11:16:54 -07:00
Literallie a9e41841e9 Fix that annoying extra "6" in German /mem
This has been bothering me and my staff forever, it's just that there's an extra number 6 in front of the word "entities" in the German translation of /mem. This commit fixes that issue by prepending that with a section sign so it gets correctly interpreted as color code.
2016-03-25 17:50:50 +01:00
Trent Hensler 37f6deab85 Add children for gamemode perms so super perms work correctly. Solves #156. 2016-03-23 18:08:22 -07:00
vemacs a4aa6a22b7 Fix compile 2016-03-18 10:19:16 -06:00
vemacs d57f7af453 Fix compile 2016-03-18 10:18:13 -06:00
vemacs 7f8c801c07 Throw some more unsupported ops 2016-03-11 17:44:14 -07:00
vemacs c627b26f49 Fix compile 2016-03-11 17:39:10 -07:00
vemacs 7c788dfa31 Switch back to CI 2016-03-11 07:58:29 -07:00
vemacs 3896b27c54 Update README 2016-03-10 16:20:17 -07:00
vemacs 97561667a0 Java 7-ize this class 2016-03-10 12:36:57 -07:00
vemacs bdb81123d6 Refactor spawn egg provider to separate classes 2016-03-10 09:28:08 -07:00
vemacs f1c57371a3 Refactor providers to a generic implementation in preparation for future spawn egg APIs 2016-03-10 08:54:07 -07:00
vemacs 873f9404bf Restore old inventory clear behavior for 1.9 2016-03-08 18:07:04 -07:00
vemacs 7eac272386 Fix clone(), formatting tweaks 2016-03-08 17:44:57 -07:00
Trent Hensler e6d177c09a Revert "Don't require extra argument to see armor with invsee. Resolves #472."
Handling this with armor and without NMS isn't clean. Advise using OpenInv if players want extended capability.

This reverts commit 6eb63fd3fd.
2016-03-08 15:38:50 -08:00
vemacs 65f2051e87 Add spawn egg NMS for 1.9 2016-03-08 12:28:23 -07:00
vemacs 767abe83f9 Fix giving spawn eggs in 1.9 (use SpawnEgg API) 2016-03-08 12:12:21 -07:00
Trent Hensler 6eb63fd3fd Don't require extra argument to see armor with invsee. Resolves #472.
Before, you had to do  to see armor. Now it just adds it if you have the permission.
2016-03-07 15:37:42 -08:00
Trent Hensler 03c59a9f17 Remove outdated netbeans styles. 2016-03-07 11:45:29 -08:00
Trent Hensler 3fd925c1fd Use proper AFK toggle to make test pass. 2016-03-07 11:19:16 -08:00
Trent Hensler 6ea8f7b621 Update vault version.
This solves the issue of trying to resolve old dependencies that led to 1m+ compile time for me.
2016-03-07 11:10:43 -08:00
vemacs 4e77fc0f0b Update potions to 1.9 2016-03-06 16:19:06 -07:00
vemacs 6d347881b7 Formatting 2016-03-06 11:14:08 -07:00
vemacs 73ad945101 Simplify copy operation 2016-03-06 11:02:05 -07:00
vemacs d39615d906 Try correcting overflow behavior for non-sign situations 2016-03-06 10:49:16 -07:00
vemacs dcc6e2f23f Correct overflow behavior after https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/c44c41ef02307f87bd978a6021a10d9b3d751d5e 2016-03-05 09:29:53 -07:00
vemacs 24e068b94d Send invalid message when attempting to spawn unavailable mob 2016-03-05 09:03:32 -07:00
vemacs 6b6cf41782 Also do a nullcheck on enchants 2016-03-05 09:01:15 -07:00
vemacs d17bd144a2 Add 1.9 Enchantments (FROST_WALKER, MENDING) 2016-03-05 08:49:46 -07:00
Trent Hensler a5686a17e2 Proper directory structure with this maven project. 2016-03-04 10:06:28 -08:00
Trent Hensler 2fab3b9957 EssentialsXGroupManager 2016-03-03 17:39:29 -08:00
Trent Hensler 9e2a9abee1 Have GM be consistent with other modules. 2016-03-03 17:38:29 -08:00
Trent Hensler 10eed23430 Add GroupManager
This doesn't mean we are actively supporting it, just means I wanted to appease people begging for a binary that works on 1.9.
2016-03-03 17:18:27 -08:00
vemacs 7967f62131 Deduplicate toggle argument handling code 2016-03-03 12:54:18 -07:00
vemacs 8102bab3ff Add our 1.9 changes to the readme 2016-03-03 08:45:06 -07:00
vemacs dd026700be Minor cleanup 2016-03-03 07:57:37 -07:00
vemacs 0001665ece Don't spam startup logs for PermissionsHandler 2016-03-03 07:44:49 -07:00
vemacs d0a7c5a0ec Remove PEX binary from repo, as we use Vault metadata now 2016-03-02 20:59:17 -07:00
vemacs ba97e5fff5 Don't allow double loads 2016-03-02 08:48:32 -07:00
vemacs e90455463f Better solution than synchronization 2016-03-02 08:46:29 -07:00
vemacs 72760096f5 Never write empty names file 2016-03-02 08:33:11 -07:00
vemacs 148cbd06e0 1.9 -> 1.9-R0.1 2016-03-01 19:11:49 -07:00
vemacs 62c2c57d4d [Experimental] Support Unbreakable meta tag 2016-03-01 18:16:13 -07:00
vemacs b8f7918a4a [Experimental] Rewrite UUIDMap to use one single ScheduledExecutorService 2016-03-01 17:52:39 -07:00
vemacs 526118e7d3 Update sounds to 1.9, fix compile 2016-03-01 17:05:57 -07:00
vemacs 37c20d5b6d Update API to 1.9-SNAPSHOT (note: compatibility is retained) 2016-03-01 16:53:08 -07:00
vemacs 5b60998b0a Use try-with-resources 2016-03-01 11:52:29 -07:00
vemacs 833713bee2 setAccessible(true) on legacy cache methods 2016-03-01 11:49:54 -07:00
vemacs cf1f2f8f03 Don't hardcode inv length 2016-03-01 10:21:04 -07:00
vemacs f6cbda0e04 Also limit maxYears in parser 2016-03-01 09:43:28 -07:00
vemacs 7d33814d5b Change to Vault Metadata API for PEX build perms 2016-03-01 09:29:45 -07:00
vemacs 7c59d61b32 Limit max time delta in years to 100k 2016-03-01 09:24:06 -07:00
vemacs 844a4a0574 Truncate contents length for 36 to playerInventory 2016-03-01 08:51:09 -07:00
vemacs 5968a6bc27 Run seen fallback code asynchronously, and clean it up 2016-03-01 08:36:41 -07:00
vemacs f94e242a75 Change spectator mode string matching to be consistent with other gamemodes 2016-03-01 08:05:00 -07:00
vemacs ddee7d1b94 Add 1.9 mobs (just one) to Mob 2016-02-29 20:52:02 -07:00
Blinky™ 30fce436dd Merge pull request #408 from AdamQpzm/2.x
Add fix for enchants & kits on 1.7
2016-02-06 07:35:56 -05:00
AdamQpzm dfdc6a52be Add fix for enchants & kits on 1.7 2016-02-06 11:24:36 +00:00
Ali Moghnieh ba5ce33464 Test for updateActivity all the time in PlayerCommandPreprocessEvent. 2016-01-30 16:07:14 +00:00
Ali Moghnieh 7809615896 Fix /time permissions to allow players to check time with just essentials.time. Remvoe timeSetAllPermission message as it is no longer used. 2016-01-25 01:17:47 +00:00
Ali Moghnieh 27a297a18d Move last-message-reply-recipient-timeout to a more appropriate position in the config.yml. 2016-01-20 16:02:41 +00:00
Ali Moghnieh bbf657e251 Add afk-list-name config property for changing the player list name of AFK players. 2016-01-20 14:15:53 +00:00
Ali Moghnieh c6d2746959 Add world-time-permissions configurable variable (false by default) that justifies whether /time should check for per world permissions. This was recommended by Khobbits as newbies might get confused by this feature. 2016-01-20 11:46:37 +00:00
vemacs d895d40fbf Move legacy field to class 2016-01-19 11:01:09 -07:00
Blinky™ a1d40f24a7 Update README.md 2016-01-19 08:57:03 -07:00
vemacs fd697aeb83 Restore spawnmob compatibility to 1.7.x, also provide framework for future version support 2016-01-19 08:45:52 -07:00
vemacs 6e05327934 Ship full Metrics (might help fix our graphing issues) 2016-01-19 08:09:44 -07:00
vemacs a4871cac36 [Experimental] Attempt to implement compatibility for 1.7 servers 2016-01-18 21:05:49 -07:00
vemacs b17f5d32c9 Add configuration option for toggling "fly mode enabled" message on login 2016-01-18 19:21:29 -07:00
vemacs 3896bcbd64 Allow skipping version check per request 2016-01-18 15:49:43 -07:00
vemacs 9c986aa25f Forcibly load OfflinePlayer class per @Byteflux's suggestions to prevent LinkageError 2016-01-18 15:02:20 -07:00
Ali Moghnieh 419d2d8282 Prettify currency display further. 2016-01-14 18:20:06 +00:00
Ali Moghnieh d570570394 In Commandtime:
- Make world name normalization lowercase the name as well.
- Permission checks will now always consider essentials.time.world.all for convenience.
2016-01-14 18:16:36 +00:00
Ali Moghnieh 0347badeda Update time world permissions prefix from essentials.time.set to essentials.time.world. 2016-01-14 17:56:41 +00:00
Ali Moghnieh eb924b9861 Add per world permission for setting world time.
Add two new locale messages: timeSetWorldPermission and timeSetAllPermission.
Add two new permissions essentials.time.set.all and essentials.time.set.<world>.
2016-01-14 12:32:48 +00:00
Ali Moghnieh 38c8a8e666 /Vanish no longer broadcasts user activity on PlayerCommandPreProcessEvent.
Implement more hard coded customizability with commands that shouldn't broadcast afk activity on PlayerCommandPreProcessEvent.
2016-01-12 23:53:09 +00:00
AdamQpzm 9f75f1aad3 Add bypass permission to nick command
This should allow users of wildcard permissions to be able to change their nicks as intended, without any changes to their current setup.
2016-01-04 21:32:19 +00:00
drtshock a669163196 Remove colour in permission checks.
As @supaham pointed out, this can cause issues with giving a player a wildcard permission and then negating the specific node if both nodes aren't negated.
2016-01-02 12:17:43 -08:00
Tux 87842a36ba Allow color-only nickname changes. 2016-01-02 12:11:17 -08:00
Ali Moghnieh 2d3691107d Create broadcastworld command for broadcasting to a world instead of the whole server. 2016-01-02 12:57:37 +00:00
Ali Moghnieh 134fbdf1df Fix Essentials Signs abuse using colours. Prior to this commit, the sign creation stage could be bypassed by typing &1&1[Test] assuming that was the success-name of the Essentials Sign. This commit prevents this by checking if the top line contains any of the success-name, without color. And so if anyone tries to type &1[repair] it will be displayed as [repair], but if someone tried &1[repairs] it will be displayed as §1[repairs], as repairs is not an Essentials Sign. It might be worth noting that all signs are checked including disabled signs to prevent abuse ahead of time. So even if [repair] is disabled all colours will still be stripped from [repair]. 2016-01-02 11:51:11 +00:00
Ali Moghnieh ab490cd588 Make 'Prevent sign destruction' message print on debug to prevent spam. 2016-01-02 11:36:48 +00:00
Ali Moghnieh 2e903acbaa Add support for using /seen with UUID. 2016-01-02 10:46:42 +00:00
Ali Moghnieh 06417910e2 Add 10 seconds of graceful time before doing first check to prevent misinterpretation of lack of activity. 2016-01-02 10:16:34 +00:00
Blinky™ c56dd6e302 Merge pull request #328 from AdamQpzm/2.x
Prevent extra colour codes from creating Essentials signs
2015-12-28 15:15:49 -07:00
AdamQpzm 19dcb33eb7 Prevent extra colour codes from creating...
...Essentials signs
2015-12-28 22:06:04 +00:00
Ali Moghnieh 540fa98a44 Ensure signsEnabled boolean is reset when reloading config. 2015-12-25 23:24:51 +00:00
drtshock 7428b7f981 Add groupmanager to gitignore. 2015-12-06 12:31:58 -08:00
drtshock 6fc19b92eb Turn off socialspy on login if player doesn't have the permission.
This fixes the case where players had socialspy enabled, lost the permission for it (got demoted) and then someone had to manually check and disable it for them as described in #299.
2015-12-06 12:30:55 -08:00
vemacs 1a701e69ca Add configuration option for the "#EasterEgg" regarding milk buckets and animals.
Requested by @prplz
2015-12-01 17:41:56 -07:00
vemacs 569c848764 Merge branch '2.x' of https://github.com/drtshock/Essentials into 2.x 2015-12-01 17:33:20 -07:00
vemacs ad93d15197 Only utilize usercache lookup for seen command 2015-12-01 17:32:53 -07:00
Ali Moghnieh 4a0507a838 Clone map of name->uuid when writing to file. Educated-guess for a fix for #213. 2015-11-30 19:51:22 +00:00
vemacs bc4737562d Use Essentials server instance instead of static Bukkit reference 2015-11-29 17:25:57 -07:00
vemacs 55f3a14343 Fix EconomyTest passing 2015-11-29 17:01:19 -07:00
vemacs 72e99a8833 Fall back to CraftBukkit userCache or Mojang for UUID lookups 2015-11-29 16:25:26 -07:00
Ali Moghnieh 0eb5063332 Duplicated code is so boring, ugh. Fixes #280. 2015-11-25 17:25:34 +00:00
Ali Moghnieh ca387687a5 Add last-message-reply-recipient-timeout setting for timing out reply-recipient in private messaging. 2015-11-24 22:48:18 +00:00
vemacs 2d376bc72f Restore LocationUtil compatibility with 1_8_R1 2015-11-15 07:59:19 -07:00
Blinky™ 58948b45b3 Merge pull request #273 from Fleodas/patch-1
Update messages_fr.properties
2015-11-10 17:33:29 -07:00
Fleodas 514f9b90f0 Update messages_fr.properties
Updated with last translations from crowdin, translation of the latest messages in French.
2015-11-11 01:20:32 +01:00
vemacs 0c41363914 Merge branch 'patch-2' of https://github.com/Androkai/Essentials into 2.x 2015-11-08 08:11:44 -07:00
vemacs 9bf0b65016 Merge branch 'issue-232' of https://github.com/sainttx/Essentials into 2.x 2015-11-08 07:59:47 -07:00
Ali 'SupaHam' M cdfe2b1487 Merge pull request #267 from EvilOlaf/patch-3
Fixes https://github.com/drtshock/Essentials/issues/265
2015-11-08 13:17:05 +00:00
Very Evil Olaf fe936a683f Fixes https://github.com/drtshock/Essentials/issues/265 2015-11-08 09:18:58 +01:00
Androkai e3cc5f2df8 add 4 missing strings
updated file with new strings from messages.properties
2015-11-07 22:36:31 +01:00
Blinky™ 3c0dc1e455 Merge pull request #263 from Androkai/patch-1
Translated missing strings and fixed some mistakes
2015-11-07 13:46:37 -07:00
Androkai d5b781fd60 Translated missing strings and fixed some mistakes
I downloaded a newer version from crowdin, compared it with this one, translated additional strings and fixed some old mistakes and inconsistencies in German word choice.
2015-11-07 21:45:22 +01:00
Ali Moghnieh 0a876c33a7 Add minimum-pay-amount setting to limit how little you can /pay someone.
Add 'minimumPayAmount' translatable message.
Create NumberUtil#displayCurrencyExactly(BigDecimal, IEssentials).
2015-11-07 17:23:40 +00:00
Ali Moghnieh fc8ee7f25f WHERE ARE THE BRAKES? Fix sending both UNREACHABLE and MESSAGES_IGNORED messages to /msg sender. 2015-11-03 23:39:18 +00:00
Ali Moghnieh cf448cd1cc Always set the message sender's reply-recipient when they send a message. 2015-11-03 00:40:56 +00:00
Ali Moghnieh 928f05ca8f Fix logic behind setting reply-recipient when receiving a message. 2015-10-31 23:28:05 +00:00
Ali Moghnieh 7b60552ec1 /tppos shouldn't add 180 to yaw. Fixes #225 2015-10-31 20:47:04 +00:00
Ali Moghnieh 26045e2ec0 Add isReachable API to IMessageRecipient.
Add translatable message recentlyForeverAlone.
Add behaviour that preserves reply-recipient only if they are reachable, and update reply-recipient if they are not reachable.
Fixes #248
2015-10-30 19:58:30 +00:00
Ali Moghnieh e5ebeaf724 Merge branch '2.x' of github.com:drtshock/Essentials into 2.x 2015-10-30 19:23:00 +00:00
Ali Moghnieh dc24bb53c2 Use recipient's display name instead of sender's name in messaging notifications. Fixes #249. 2015-10-30 19:22:39 +00:00
Matthew Steglinski 2175cb8a44 Group allowShortName check when checking if the short form version of 'splash' was used 2015-10-29 16:42:19 -04:00
Matthew Steglinski 756ea346e6 [Fix] Add option to not show one time use kits described in #188
* Adds toggleable config option 'skip-used-one-time-kits-from-kit-list' to exclude used kits with delay < 0 from displaying in the /kit list
2015-10-28 13:29:30 -06:00
Matthew Steglinski 23f3d69d38 [Fix] Call JailStatusChangeEvent when jailing and unjailing players. Fixes #161 2015-10-28 13:29:29 -06:00
Matthew Steglinski a134e99c8c [Fix] Listen to PortalCreateEvent to cancel portal creation by fire. Fixes #164 2015-10-28 11:35:29 -04:00
Matthew Steglinski 607f1980a1 [Fix] Adds splash potion persistence when serializing items. Fixes #232 2015-10-28 10:59:11 -04:00
Ali Moghnieh fb4af9fefc Rename and fix MessagingTest. 2015-10-28 13:37:17 +00:00
Ali Moghnieh 447b9db397 Rewrote messaging structure for more abstractness.
This commit adds a new boolean-configurable feature called last-message-reply-recipient, defaults to true for new installs and false for old installs, which states whether to use the new messaging functionality or not.
This commit deprecates Console#getCommandSender(Server) and provides Console#getInstance()#getCommandSender() for future usability.
2015-10-27 20:46:58 -06:00
Matthew Steglinski 77eb430b0b [Fix] Fixes drtshock/Essentials#189, adds toggleable config option 'ignore-colors-in-max-nick-length' to exclude ChatColors from nickname length 2015-10-27 22:37:33 -04:00
Ali Moghnieh d4ab25b200 Merge branch '2.x' of github.com:drtshock/Essentials into 2.x 2015-10-26 17:22:33 +00:00
Ali Moghnieh faaa4a4b1e Fix typo in German language file. Fixes #236 2015-10-26 17:22:10 +00:00
mickare a844e8b5ad Fix for offline player functionality (including /seen), implement automatic usermap repair 2015-10-17 08:20:33 -06:00
Taras 84143d06fa Revised config 2015-10-17 08:20:31 -06:00
Ali Moghnieh 9805f3f4d1 Add support for HEX RGB values. 2015-10-08 19:33:14 +01:00
Ali 'SupaHam' M bae6f89fa5 Merge pull request #221 from SupaHam/fix-item-color-deserialization
Add support for deserializing item color RGB values as integers.
2015-10-08 19:21:30 +01:00
Ali Moghnieh a721e04119 Add support for deserializing item color RGB values as integers. 2015-10-08 19:14:04 +01:00
Ali Moghnieh 6360c690cf Increment pendingDiskWrites every time we save please. 2015-10-08 18:47:10 +01:00
Ali Moghnieh aa75a3f20d Remove GroupManager from here! 2015-10-08 18:16:41 +01:00
Blinky™ 3edfec2491 Merge pull request #210 from ShadowRanger/2.x
[Fix] Properly apply damage causes
2015-09-27 20:37:47 -06:00
ShadowRanger c364adcf00 Updated & refactored LocationUtil 2015-09-28 12:25:46 +10:00
ShadowRanger 7d6714f713 Properly apply damage causes 2015-09-28 11:45:25 +10:00
drtshock 8485bd44f9 Correct check on bulk sell permission. 2015-09-23 15:02:44 -05:00
drtshock c0800afeeb Add configurable message for messaging someone with messages turned off. Adds #180
This message can also be removed to not send a message at all, keeping previous functionality.
2015-09-01 12:53:07 -05:00
Jikoo 046752f8c2 Fixes for graphical /recipe issues. Closes #134
- Fixed shaped recipe ItemStacks displaying 0s
- Fixed recipes supporting any data value of blocks missing textures
2015-08-19 10:42:16 -06:00
Blinky™ 9307f9b9c1 Update README.md 2015-08-19 10:42:15 -06:00
drtshock ee2018416e Add gamemode check when game moding self. 2015-08-10 09:58:20 -05:00
drtshock 6c38b6c6fb Hand sell message should be different from bulk sell. 2015-08-08 21:42:21 -05:00
drtshock cafb297594 Add essentials.chat.spy.exempt permission. Implements #83 2015-08-07 17:05:19 -05:00
drtshock 8bec43f7a2 New permission for changing all gamemodes. Fixes #79.
Need to give players essentials.gamemode.all or each gamemode permission on top of essentials.gamemode to be able to change.
2015-08-07 16:54:08 -05:00
drtshock fe1dd0d0f3 Add separate permission for bulk sell and hand sell. 2015-08-07 16:53:20 -05:00
drtshock b066d4dd83 Send emotes to yourself. 2015-08-01 19:24:23 -05:00
drtshock 792c7d5e91 Have me command respect chat radius. Implements #118.
Adds similar functionality to that of chat in essentials chat.
2015-08-01 16:38:09 -05:00
drtshock 76498e86f5 Add X naming to parent module. 2015-07-29 16:22:10 -05:00
vemacs 540a15160c Fix enable/disable message ordering in /msgtoggle 2015-07-29 11:26:36 -06:00
vemacs 6eb5aded38 Add msgtoggle to plugin.yml 2015-07-29 10:31:41 -06:00
vemacs 891605380f Add /msgtoggle command, untested (implements #89) 2015-07-28 20:29:17 -06:00
vemacs fe9348b3fb Add silent msg ignoring in msg command 2015-07-28 19:49:13 -06:00
vemacs c592a9d361 Add IgnoreMsg API 2015-07-28 19:45:33 -06:00
vemacs fae159cdbd Merge branch '2.x' of https://github.com/drtshock/Essentials into 2.x 2015-07-28 19:20:49 -06:00
vemacs d7b0f74a75 Give money back to sender if MaxMoneyException thrown (fixes #106) 2015-07-28 19:20:47 -06:00
drtshock d5301824fc Use Bukkit ChatColor instead of ess regex to strip colors. 2015-07-23 15:23:47 -05:00
vemacs 28607ce58c Fix compile 2015-07-23 15:23:47 -05:00
vemacs 9fb0ab57e6 Fix compile 2015-07-18 20:05:36 -06:00
Blinky™ 6143b088c3 Merge pull request #96 from CoolV1994/2.x
Fix Issue #91
2015-07-18 16:15:03 -06:00
CoolV1994 06e24b3bc2 [Fix]: tppos for Console
Use the correct arguments when using from Console
2015-07-18 18:02:21 -04:00
CoolV1994 3283b8c0a3 [Feature]: Add world argument to /tppos 2015-07-16 19:09:19 -04:00
CoolV1994 f43501e828 [Fix]: Relative Coordinates
Fixes the error when trying to do something like:
/tp ~ ~10 ~
2015-07-16 18:36:10 -04:00
vemacs 192ced4e4c Revert "Make disable-eco option visible in default config. Adds option requested multiple times."
This reverts commit dd65a1e76c.
2015-07-08 07:26:31 -06:00
drtshock dd65a1e76c Make disable-eco option visible in default config. Adds option requested multiple times.
This is apparently already in there but not visible. https://github.com/drtshock/Essentials/blob/cf9c9f707324826b0d1468a24ca42362ab2959bf/Essentials/src/com/earth2me/essentials/Settings.java#L644
2015-07-06 23:42:26 -05:00
drtshock 0b042dad43 Add separate permission for notifying ban ip. Resolves #60.
Permission is essentials.banip.notify and old one is essentials.ban.notify.
2015-07-06 16:19:32 -05:00
vemacs 14384f6bfa Put whole block into try-catch (just in case) 2015-07-05 09:41:11 -06:00
vemacs b9f293f8a7 Fix plugin startup 2015-07-05 09:37:17 -06:00
vemacs d03d85b52b Start metrics async 2015-07-05 09:27:53 -06:00
vemacs cf9c9f7073 Use metrics-lite, use global PluginMetrics config to control disable 2015-07-05 09:26:36 -06:00
vemacs 7fb263e75c Assign permissions in plugin.yml since they aren't assignable from player-commands 2015-07-05 09:10:04 -06:00
vemacs 1d20184f0b Implement #70 (untested), TODO assign default permissions 2015-07-03 13:07:25 -04:00
Blinky™ 500384abf3 Fix somehow removed drop-items-if-full option 2015-07-01 23:56:31 -05:00
Blinky™ d1b18da36e Clarify more 2015-07-01 23:53:52 -05:00
Blinky™ 3b3acbcfda Update README.md 2015-07-01 23:53:10 -05:00
Blinky™ 6c35dfcb3d Expose use-bukkit-permissions in config 2015-07-01 23:50:17 -05:00
vemacs 01ad006ca3 No magic numbers 2015-07-01 08:16:45 -05:00
Blinky™ 7e580920f6 Pig, not creeper 2015-06-30 17:20:11 -05:00
Blinky™ 5227824608 Default to pig spawner, fixes #67 2015-06-30 17:15:13 -05:00
vemacs 1c78f5cc3b Update metrics implementation, report to mcstats instead of Essentials metrics 2015-06-28 21:53:38 -05:00
vemacs 306aab0d8d Implement drop-items-if-full for /give command (default false) 2015-06-28 10:30:21 -05:00
vemacs e33c42e123 Optimizate imporst 2015-06-21 09:16:49 -04:00
vemacs 9ccfd4aac0 Fix compile, class definitions 2015-06-21 08:45:01 -04:00
vemacs 549da08f87 OCD message tweaking. Last thing. 2015-06-19 21:59:17 -04:00
vemacs b6c7799cc2 Fix compile, consider this stable 2015-06-19 21:48:11 -04:00
vemacs d063b5a894 Apply setUseSuperperms() to correct handler 2015-06-19 21:44:11 -04:00
vemacs cd78211cdf Remove redundant checkPermissions() call from poorly named listener 2015-06-19 21:39:42 -04:00
vemacs 4e9d6d22dd Actually fix no-Vault situation 2015-06-19 21:34:52 -04:00
vemacs 3a3d1a5981 Fix no-Vault situation 2015-06-19 21:30:27 -04:00
vemacs b15d868f77 Failing test? Delete it, not failing anymore 2015-06-19 20:56:55 -04:00
vemacs a6232b6bb6 [Untested] [Experimental] PermissionsHandler cleanup, add specific logging to detect Vault with no perms plugin 2015-06-19 15:47:58 -04:00
vemacs 6ca3712b79 Attempt PermissionsHandler cleanup, attempt to support Vault installed but no working perms/chat setup situations 2015-06-19 09:14:46 -04:00
vemacs db6724acdf Fix indentation, update getHumanName 2015-06-18 13:46:55 -04:00
vemacs 16c7bf2eb3 Add v1_8R2 to support 1.8.3 users not on the latest 1.8.3 build 2015-06-18 13:43:39 -04:00
vemacs 0331fafa77 Move common name setting stuff to superclass 2015-06-17 16:58:57 -04:00
vemacs 1d63209691 Rename this class to match the others 2015-06-17 15:22:00 -04:00
vemacs 140ece68d3 Cleanup dependencies, still waiting on build server to be fixed 2015-06-17 13:01:01 -04:00
vemacs e95ca8444e Simplify loadProvider method 2015-06-17 11:09:13 -04:00
vemacs dce381fb28 Advertise in readme 2015-06-17 11:00:23 -04:00
vemacs 121b262d1b Use returned value for setEntityType, attempt fixing name setting 2015-06-17 10:54:23 -04:00
vemacs 51b52ac343 [Experimental] Also catch provider instanciation exceptions 2015-06-17 10:38:25 -04:00
vemacs 8793add589 [Untested] [Experimental] [Need @drtshock to fix build server] Fully support all versions of Spigot and CraftBukkit from 1.8+ 2015-06-17 10:25:46 -04:00
vemacs e4f6bb363d Compile against Spigot's Bukkit maven repo 2015-06-17 09:02:28 -04:00
vemacs 6bd34f44ef Move downloads to top 2015-06-16 17:01:21 -04:00
vemacs be60e10ebd Bring back this? 2015-06-12 11:32:32 -06:00
vemacs 56cfffb2ef Fix double dependency, offlineplayer override 2015-06-12 11:28:41 -06:00
vemacs 20a59ddb6e Catch throwable for spawnerutil, move nasty warning to spawnerutil 2015-06-12 11:22:11 -06:00
vemacs bfa93cc189 Move initialization code to top 2015-06-05 16:49:05 -06:00
vemacs 480055b3d7 Give actually helpful error message for attempts to load on 1.7 2015-06-05 16:46:33 -06:00
drtshock 5e605f992a Reformat floatutil. 2015-06-05 10:38:06 -05:00
vemacs 3634cab1a5 Apply patch "Fixed exp for 1.8" from Spigot-Essentials, fixes #3 2015-06-04 20:44:02 -06:00
vemacs 8e2ffe08f8 Use items.csv from Spigot-Essentials (recommended to delete your current items.csv if you haven't made changes) 2015-06-04 20:41:32 -06:00
vemacs b6957db352 Apply patch "Fix float parsing issues" from Spigot-Essentials 2015-06-04 20:32:36 -06:00
vemacs ff3b1e810f Fix MetaItemStack canSpawn() method to try it on a clone, readd check to /give and /i 2015-06-04 11:18:47 -06:00
vemacs 14c4ed8379 Merge branch '2.x' of https://github.com/drtshock/Essentials into 2.x 2015-06-04 08:42:58 -06:00
vemacs a224894380 Fix inverted boolean value, fixes #53 2015-06-04 08:41:19 -06:00
vemacs f5a4c8f11e We require 1.8 2015-06-03 17:23:28 -06:00
vemacs 73ac6488ce Run IntelliJ IDEA inspections 2015-06-03 14:11:56 -06:00
vemacs c03765803c Move to switch statement (Java 7 sugar) 2015-06-03 14:03:26 -06:00
vemacs 65fc8a9c41 Don't spam fallback message 2015-06-03 13:20:42 -06:00
vemacs e8e15d2cd4 Merge branch '2.x' of https://github.com/drtshock/Essentials into 2.x 2015-06-03 13:12:22 -06:00
vemacs d7849f4120 Build against java 7 2015-06-03 13:11:43 -06:00
vemacs c48f68f0dc Update README.markdown 2015-06-03 10:06:29 -06:00
vemacs fe49e08340 Force superperms based permissions if a supported perms plugin is installed, but Vault isn't 2015-06-03 09:53:24 -06:00
vemacs 5051f3c4d7 Jungle -> SMALL_JUNGLE handling 2015-06-03 08:08:28 -06:00
vemacs 0c8695a888 Fix compile, avoid hardcoding tree values 2015-06-03 08:05:38 -06:00
vemacs d63e342f78 Remove version matching, it's pointless now 2015-06-03 07:44:18 -06:00
vemacs 9f4ccf9eaf Remove unused dependencies, add Vault softdepend 2015-06-03 07:08:21 -06:00
vemacs 1f14ac5c18 Copy logic from pre-refactor, should fix everything PermissionsHandler related, add Vault dependency to readme 2015-06-03 07:04:39 -06:00
vemacs 8f71261646 Fix issues relating to refactor 2015-06-02 18:08:44 -06:00
vemacs 1a9954428b Make Commandgive behavior more similar to Commanditem, fix shutdown spam 2015-06-02 17:57:20 -06:00
vemacs e43ae47a78 Simplify handler registration logic 2015-06-02 17:34:38 -06:00
vemacs 57213dd625 call setupProviders() for all handlers 2015-06-02 17:12:53 -06:00
vemacs ce5ffb9bd7 Call superclass constructor for GroupManager, fixes #48 2015-06-02 17:09:03 -06:00
vemacs 5375ff3790 Add reset color code before name (duplicate legacy vanilla behavior) 2015-06-02 14:02:08 -06:00
vemacs 37d4dc70e5 Set display name for given spawners 2015-06-02 13:56:54 -06:00
drtshock e7337d06b5 Merge branch '2.x' of https://github.com/drtshock/Essentials into 2.x 2015-06-02 14:47:53 -05:00
drtshock bcc76aff63 Build number in version. 2015-06-02 14:47:42 -05:00
vemacs 154d43819a Make permissions-plugin specific implementations extend Vault, fix build permission checks 2015-06-02 13:21:40 -06:00
vemacs 318e0eabea Make PermissionsEX handler use UUIDs 2015-06-02 13:20:34 -06:00
vemacs 0a2f1a3dfe Fix PrivilegesHandler 2015-06-02 13:09:54 -06:00
vemacs b19dbb1b8f Make permissions-plugin specific implementations extend Vault, fix build permission checks 2015-06-02 13:08:53 -06:00
vemacs 904a9700b2 Update README.markdown 2015-06-02 12:21:46 -06:00
vemacs f5daf7085e Add logo 2015-06-02 12:18:44 -06:00
vemacs f500e2ce9a Add wiki link to readme 2015-06-02 12:09:24 -06:00
drtshock e2a67365f9 Add CI link to readme. 2015-06-02 12:18:49 -05:00
vemacs 2273329e29 Add SpawnerUtil with primary Spigot 1.8.3+ EntityType setting, legacy data fallback. Fixes #22 2015-06-02 11:28:38 -05:00
vemacs be1acfdccd Don't override SuperpermsHandler hasPermission, fixes #45 2015-06-01 18:50:20 -06:00
vemacs 2f39811a46 Properly set default for force-disable-teleport-safety to false 2015-06-01 14:00:06 -05:00
vemacs f995676fad Add force-disable-teleport-safety option (default false). This option is useful for preventing "teleport-glitching" in Factions servers. 2015-06-01 14:00:06 -05:00
vemacs ea4c966003 Rename Vault setup method to be more descriptive, check if Chat class is available 2015-06-01 11:03:11 -06:00
vemacs fe5de8a854 Fix #35, implement prefix and suffix methods for VaultHandler 2015-06-01 10:19:11 -06:00
vemacs fa43f39015 Use UUID methods for zPermissions (merged from Spigot fork) 2015-06-01 09:11:41 -06:00
drtshock 4d0e6254dd Fix typo in Guardian. Fixes #40. 2015-06-01 08:44:49 -05:00
Paul Sauve e94e908bed Fix dependencies 2015-05-24 18:02:40 -05:00
drtshock 179dbe19fd Use separate config option for near radius.
We were using chat radius, which upset me when I wanted to change it but didn't want to start using local chat.
2015-05-16 19:36:57 -05:00
drtshock d6eb846488 Add blacklist of commands for muted players. Adds #30. 2015-05-12 21:44:36 -05:00
drtshock 6796d460dc Add option to put unique players in join message. 2015-05-08 15:55:02 -05:00
drtshock 4be2fc1a90 Update pom of EssentialsX 2015-05-03 15:09:22 -05:00
drtshock 20f79f117f Make sudo a loop command. Adds #23. 2015-05-03 15:08:32 -05:00
drtshock 4169996e7a Name the jars EssentialsX. 2015-04-24 15:32:50 -05:00
drtshock 667fc18abf Return at correct spot. 2015-04-24 12:35:29 -05:00
drtshock 4f72ff47bc More informative permission lag notices. 2015-04-22 11:26:41 -05:00
drtshock b7704a4ea8 Simplify a few things in EssentialsChat. 2015-04-22 10:58:04 -05:00
drtshock ac0858dcdb Add PermissionsHandler for Vault.
We'll use the VaultAPI if it's there for group checks.
This will also allow us to default to Player#hasPermission from Bukkit instead of going through each permission plugin.
2015-04-22 10:42:27 -05:00
drtshock 7439dc01a5 Update other info. 2015-04-20 18:26:03 -05:00
drtshock 090e0b6757 Add banner meta. Resolves #8. 2015-04-20 18:09:52 -05:00
drtshock effad664d5 Print stack trace if debug is enabled. 2015-04-20 17:49:23 -05:00
drtshock 01bf7d1389 Update readme 2015-04-20 14:51:56 -05:00
drtshock b7c7e4ad23 Add /showkit to view kit contents. 2015-04-20 14:33:36 -05:00
drtshock 5ca02e6596 Don't build groupmanager. 2015-04-20 13:09:56 -05:00
drtshock 6b2f87c5a9 Consistent versioning. 2015-04-20 12:51:51 -05:00
drtshock 9a265aac48 Add /createkit.
Allows you to create a kit in game using your inventory.
2015-04-20 12:51:22 -05:00
drtshock 5b052c170f Per gamemode permissions. Adds #16. 2015-04-17 16:54:25 -05:00
drtshock 555f151692 Allow commands in kits. Adds #15.
Syntax is /<command> with the ability to add {player} as an argument.
2015-04-17 14:48:23 -05:00
drtshock c22978c3f9 Add missing aliases to plugin.yml 2015-04-16 09:28:05 -05:00
drtshock 54b3a23ae2 Update items for 1.8.3 2015-04-16 09:25:40 -05:00
drtshock f5b40dba34 Add option to not send no new mail message on join. 2015-04-16 09:25:29 -05:00
drtshock f8160c6318 1.8.3 update. 2015-04-16 09:08:22 -05:00
drtshock b113bb59d4 Spectate gamemode. 2015-04-16 08:54:46 -05:00
drtshock 15bd41fefc Add new mobs. Update child to 1.8.3 2015-04-16 08:52:29 -05:00
drtshock 4e6aef3d24 Add Depth Strider enchantment. Resolves #4. 2015-04-16 08:50:43 -05:00
drtshock c798f995ca 1.8.3 2015-04-16 08:46:00 -05:00
drtshock 9bca2b44ab Update pom. 2015-04-16 08:32:04 -05:00
drtshock dde0b20775 Reformat 2015-04-14 23:06:16 -05:00
KHobbits ad13062117 Unrequired Dependacy 2014-09-06 17:22:25 +01:00
KHobbits d11a295ffd Merge branch '2.x' of github.com:essentials/Essentials into 2.x 2014-09-03 00:21:42 +01:00
KHobbits ffea359661 rework /seen to be a little stricter on argument matching. 2014-08-18 21:00:03 +01:00
md_5 037456c99d Fix missed cases from previous user iteration optimizations. 2014-08-16 19:04:13 +10:00
KHobbits 5125a137f4 Make sure we close any open inventories of players who leave. 2014-08-14 01:58:17 +01:00
KHobbits 3f1c996959 Use quicker ban lookup to reduce /seen lag. 2014-08-14 01:50:31 +01:00
KHobbits 53a7cd732f Add paging to mail.
Support aliases in rule and baltop output.
2014-08-11 19:03:24 +01:00
KHobbits 4fd026ff99 Add mailFormat TL key. 2014-08-11 18:46:04 +01:00
Necrodoom d9fbd68529 Misc clarification (socialspy and kit delay)
clarify allow-silent-join-quit
2014-08-11 00:12:43 +01:00
Necrodoom 49d80462d1 Remove outdated try-catches 2014-08-11 00:11:06 +01:00
Necrodoom 1d859e49ad Add /tempban missing syntax 2014-08-11 00:10:09 +01:00
FearFree a2c43d822c Add amount required to notEnoughMoney TL key.
See https://essentials3.atlassian.net/browse/ESS-5125 for request.
2014-07-19 20:31:50 +01:00
KHobbits 7907565377 Formatting fixes. 2014-07-19 20:11:45 +01:00
SidShakal d1c014fe16 Fix sticky piston retract breaking essentials sign
Sticky pistons could break signs that were mounted on blocks the pistons were retracting.

This patch extends the protection from just the piston base to include the extended piston arm and the block at the end of the piston arm as well.

This method will very likely need to be changed again when 1.8 comes out, but this should bring us a bit closer, by wrapping the block tests in a loop.
2014-07-19 20:08:38 +01:00
md_5 465041b98b Optimize player / user iteration.
* Add a method for backwards compatability with unmapped code.
* Convert all getOnlinePlayers() calls to use this method, part of the IEssentials interface
* Add a new method getOnlineUsers() Ljava/lang/Iterable;
* Convert appropriate calls to use this method
* Update Bukkit to #1945
* Update CraftBukkit to #3103
2014-07-19 20:07:50 +01:00
Alexander Likhachev ed56afda26 Add permission check before resetting speed on login The staff of my server asked me to do this fix, but I think it is very useful for all. This commit change is to reset player fly & run speed only if player has no permission to change speed. 2014-07-19 20:07:09 +01:00
KHobbits 23f14bc2d5 If a player already exists in the usermap, don't replace it with a eco npc. 2014-07-19 18:04:35 +01:00
KHobbits c829a32555 Clean up tempban messages to be a little clearer. 2014-07-14 21:23:56 +01:00
KHobbits ae984c2055 Update translations from Crowdin (http://translate2.ess3.net) 2014-07-12 22:12:51 +01:00
KHobbits 0c416c8366 Remove ban check from /ess cleanup, no longer required.
Fix ban upgrade script.
2014-07-12 19:13:23 +01:00
FearFree 51be2131f7 Update to new ban method. 2014-07-12 17:40:14 +01:00
KHobbits 575a8142ff Add ban reason to /banip 2014-07-12 17:23:11 +01:00
KHobbits 093a1f677b Still give 'nickNoMore' message when removing a nickname. 2014-07-12 16:48:01 +01:00
KHobbits 8311da2653 Allow for changing of username casing without adding 'nickname' prefix. 2014-07-12 16:43:57 +01:00
KHobbits b5976a52e0 Prevent users from setting unsafe homes when teleport safety is disabled. 2014-07-12 16:34:18 +01:00
KHobbits 4e6c98ac57 Allow people with god & fly to teleport to unsafe locations even when teleport safety is disabled. 2014-07-12 16:33:50 +01:00
KHobbits a2c692af39 Converge ban message translations, and add reason support to default tempban tl key. 2014-07-12 16:32:42 +01:00
KHobbits a131527a15 Switch sudo to command dispatch, this will allow vanilla commands to be executed. 2014-07-12 15:29:25 +01:00
KHobbits 0b925e6fc0 Don't cascade null usernames passed from eco api 2014-07-10 11:48:54 +01:00
KHobbits 97c8f5192e New permission :essentials.tp.position Required to use /tp [player] <x> <y> <z> 2014-07-06 18:41:12 +01:00
Necrodoom 7c372cd978 Add support for vanilla /tp <x> <y> <z> teleport syntax. 2014-07-06 18:41:01 +01:00
KHobbits 02fe58161c Allow forcing adult status on randomly generated /spawnmob mobs. 2014-07-06 18:25:00 +01:00
KHobbits 2ba2ebaa43 Update Bukkit
CB: 3092 B: 1938
2014-07-06 16:40:06 +01:00
KHobbits 549500eaf2 Show warp teleport status to teleport owner. 2014-06-28 18:10:32 +01:00
KHobbits 8e7589e450 Slightly reorder teleport messages to be less confusing. 2014-06-28 18:06:13 +01:00
KHobbits 9b69403ee1 Fix NPE with /list in console 2014-06-27 04:28:33 +01:00
KHobbits 6269ce9a3f Update essentials to support 3rd party vanish toggling. 2014-06-27 01:46:37 +01:00
KHobbits 0f6625aea9 Add some debugging to make it easier to diagnose kit errors. 2014-06-25 19:19:04 +01:00
KHobbits dbceccaa3e Kit cleanup and refactor. 2014-06-25 19:03:31 +01:00
KHobbits 6c7ba6a76f Allow multiple kits to be spawned per command. 2014-06-23 00:38:13 +01:00
KHobbits f76a517339 New permission: essentials.signs.trade.override.collect
People with this permission will collect the resources of other peoples trade signs broken with admin permissions (essentials.signs.trade.override).
2014-06-21 21:47:33 +01:00
Necrodoom 2c747ecf36 empty array is not null array 2014-06-19 16:22:38 +01:00
KHobbits 1f8b60081e Reduce a few nickname refresh calls. 2014-06-19 04:02:15 +01:00
KHobbits a800359e0b Force listener cleanup on plugin disable. 2014-06-19 02:59:08 +01:00
KHobbits 4854961901 Add a lag check for permission system checks.
This doesn't include normal permission checks, since the overhead could be detrimental.
2014-06-19 02:38:28 +01:00
KHobbits 50a815bdb9 Revert "Add spawn location cache to reduce blocking on player respawn."
This reverts commit 7804516793.
2014-06-17 23:27:46 +01:00
KHobbits 1690b9d83d If "sethome-multiple" config section is invalid, silently fallback to default config values. 2014-06-17 00:19:59 +01:00
KHobbits 7804516793 Add spawn location cache to reduce blocking on player respawn. 2014-06-16 19:55:34 +01:00
KHobbits c54e9b5dba Add default ban reason for tempban reason. 2014-06-14 22:06:26 +01:00
KHobbits 71936cfe22 Check for arraynull on pex group request. 2014-06-14 18:20:49 +01:00
KHobbits 27890e2b22 Only remove first date match from ban reason. 2014-06-14 16:27:34 +01:00
KHobbits da6df89126 Add optional {2} in 'tempBanned' TL key, for reason. 2014-06-14 16:21:05 +01:00
KHobbits 95ff197910 Show UUID in trackUUID debug message. 2014-06-07 18:21:10 +01:00
KHobbits 2215b0f53f Don't allow old UUID's to accidentally overwrite current UUID for user mapping.
Add some extra logging and uuid debug.
2014-06-07 18:08:25 +01:00
KHobbits 3887fdd47d New permission: essentials.itemspawn.meta-vanilla
Without this permission you cannot use vanilla itemmeta.  You can still use essentials style meta, if you have the appropriate permissions.
2014-06-07 16:08:51 +01:00
KHobbits 7e9328bd25 Try to use consistent UUIDs and not rely on Bukkit lookup while saving. 2014-06-07 15:45:57 +01:00
KHobbits 9d9af25c7f Add local echo of mail being sent on /mail send. 2014-06-05 00:07:27 +01:00
KHobbits 5a2fd19bcf Fix firework recipe in /recipe 2014-06-04 16:13:20 +01:00
KHobbits 3a50850734 Use strings for cachemap key, should prevent accidental key issues. 2014-06-01 21:50:24 +01:00
KHobbits 812de5c35c Add API logging to Eco API. 2014-05-31 20:37:44 +01:00
KHobbits bffea1d7c8 Extend getUser(Object) to match uuid and offline players. 2014-05-30 22:16:06 +01:00
KHobbits b00f458e67 Emulate player join for mocking. 2014-05-27 21:14:45 +01:00
KHobbits 80ef955eae Improve fakeServer model 2014-05-27 20:31:13 +01:00
KHobbits 44509ff6e4 Remove online player lookup in usermap.getUUIDMap(), throw log entry on failback. 2014-05-27 18:04:02 +01:00
KHobbits e1d4129869 Log takeMoney exception, even if we ignore it. 2014-05-27 10:46:25 +01:00
KHobbits 00655f724d Revert writecount reset, this could cause odd behavior. 2014-05-27 06:18:34 +01:00
KHobbits 4590e7ea26 Enforce userdata save on player dispose. 2014-05-27 04:52:52 +01:00
KHobbits 2ac1ce4f56 If we are modifying money, force transaction clear, this is important. 2014-05-27 03:41:18 +01:00
KHobbits f726035660 Don't check silentjoin.vanish if another plugin has hidden the join message. 2014-05-26 22:08:18 +01:00
KHobbits 57bb1ee475 New permission: essentials.silentjoin.vanish
The server needs silentjoin to be enabled first.
2014-05-25 19:31:55 +01:00
KHobbits 889dde7549 Abort transaction before updating funds on balance overflow. 2014-05-25 17:03:23 +01:00
KHobbits ada2fe01a2 Utilize write transactions for delaylogin task. 2014-05-25 01:38:37 +01:00
KHobbits cf29a0ba6a Rename listening methods to be a little more descriptive of their purpose. 2014-05-24 18:47:40 +01:00
KHobbits c929ebb89a Convert 9 anonymous scheduled tasks to named classes for better logging. 2014-05-18 21:32:07 +01:00
KHobbits 8159530906 Fix invalid TL key. 2014-05-18 19:47:18 +01:00
KHobbits 7e8ba9a256 Exempt named mobs by default from /remove
Named mobs can be removed using /remove named
Killing all mobs now requires /remove all,tamed,named
2014-05-18 14:43:07 +01:00
KHobbits b145ec59ea Tweak to player login event. 2014-05-18 13:26:27 +01:00
KHobbits 429a7275ee Update worth.yml to be more descriptive. 2014-05-17 04:31:44 +01:00
KHobbits 3bd0608b6e Update /condense syntax hint. 2014-05-17 04:21:51 +01:00
@ArkhamNetwork 9307e0cb71 Optimize PlayerLoginEvent 2014-05-17 04:05:51 +01:00
@ArkhamNetwork 4672e51806 Move the teleport timer to an async task. 2014-05-17 03:35:44 +01:00
KHobbits 18811122b3 Prevent near empty userdata file creation. 2014-05-17 03:06:48 +01:00
KHobbits cbaf126a25 Stop using old string player lookup. 2014-05-17 02:47:10 +01:00
KHobbits 8e7abe325e Prevent reading and writing the usermap at the same time. 2014-05-17 01:50:41 +01:00
Faris Rehman ed9e4ecd28 Add user messages. 2014-05-16 20:39:49 +01:00
KHobbits bd866de950 First draft of /condense 2014-05-16 20:30:06 +01:00
KHobbits 4ecb6b5fdb If Bukkit doesn't know who a player is, but we do, substitute the last known nickname when ban checking. 2014-05-10 21:52:45 +01:00
KHobbits 0d6bca2080 Update English TL keys. 2014-05-10 17:49:37 +01:00
KHobbits 05ef05dcac Update translations from crowdin (http://translate2.ess3.net/) 2014-05-10 16:11:03 +01:00
Luke Anderson (stuntguy3000) 7ba097c640 Improve messages/formatting 2014-05-10 16:03:39 +01:00
Burke D 6adacbb357 Grammatical changes to config.yml 2014-05-10 15:46:08 +01:00
clou44 69f62574c4 Updated Items.csv: Added nemofish and fishnemo.
Added shorter aliases for salmon, pufferfish, and clownfish.
2014-05-10 15:38:29 +01:00
KHobbits b00c31730f Only dispose users who are offline at point of disposal.
This should cater for quick reconnects on lagged servers.
2014-05-10 15:36:58 +01:00
KHobbits f09180659d Initialize TL Bundle on plugin start. 2014-05-06 07:00:57 +01:00
KHobbits c12373bf41 Remove '-' from valid account names again.
This could cause issues with NPC's converted to UUID before this version.
2014-05-05 22:46:46 +01:00
KHobbits 04666b66b4 Reload locale even if it is set to null. 2014-05-05 20:47:48 +01:00
KHobbits 363aee70d5 Better handle TL failover. 2014-05-05 14:48:25 +01:00
KHobbits 01d03d5d41 Update teleport timer to handle UUID rather than player names. 2014-05-05 13:01:20 +01:00
KHobbits 4575fc5aff Better handle corrupted chunks. 2014-05-04 19:39:35 +01:00
ElgarL 27e9e3aa88 Error in logic 2014-05-04 17:12:15 +01:00
ElgarL b0187698b9 Prevent players who have never logged in before from taking over existing accounts. 2014-05-04 16:22:58 +01:00
KHobbits 0364d4e0de Allow disabling userfile cache on uuid convert.
Add "ignore-userfiles-cache: true" to "upgrades-done.yml" to disable cache, forcing uuid lookup requests.
2014-05-04 13:25:20 +01:00
ElgarL 86b57804c6 Fix clones forgetting sub groups. 2014-05-04 12:50:22 +01:00
ElgarL 211dc220d8 Set a default mirror map if none is found in the config. 2014-05-04 12:50:21 +01:00
ElgarL aae586f79a Fix overloadedWorldHolder so it correctly calls the new WorldHolder code when the user is not overloaded. 2014-05-04 12:50:20 +01:00
ElgarL 32f49350cf Fixup javadocs 2014-05-04 12:50:18 +01:00
ElgarL 9739784e75 v2.1: - Update for CraftBukkit 1.7.8-R0.1(3050). - Add UUID support. Plugins can still query by player name but a UUID is faster and preferable. 2014-05-04 12:50:17 +01:00
ElgarL a0e93af758 Do not override higher level permissions with negations. 2014-05-04 12:50:16 +01:00
Necrodoom 81c6291338 Fix a /mangcheckp message 2014-05-04 12:50:15 +01:00
ElgarL 24509d60be Update mangcheckp to understand Exception nodes. 2014-05-04 12:50:14 +01:00
ElgarL f0947e9a7c Fix manucheckp to understand and report correctly on Exception nodes. 2014-05-04 12:50:13 +01:00
ElgarL 92bb4e0e66 Allow Exceptions in any inherited group to override negation of permissions. 2014-05-04 12:50:12 +01:00
Necrodoom 8f810ad447 Cleanup plugin description 2014-05-04 12:50:11 +01:00
ElgarL 3f35a6b59c Prevent adding sub groups for ranks the granting player doesn't have access to. 2014-05-04 12:50:09 +01:00
ElgarL 427dd714c9 Allow Exception permission to override negations when in the same group. 2014-05-04 12:50:08 +01:00
ElgarL 9d7a2043f7 Change to use LinkedHashSets to preserve ordering. Fixes an issue with populating bukkit perms in the wrong order. Fix wildcard negation in parent groups. 2014-05-04 12:50:07 +01:00
ElgarL ff3ec84b0d Fix Cyclic mirroring test (silly me) 2014-05-04 12:50:06 +01:00
ElgarL 1f9e72c5e2 Tidy imports 2014-05-04 12:50:05 +01:00
Necrodoom 67be18566c Improve Javadocs, clean ' strip checks, update changelog. 2014-05-04 12:50:04 +01:00
Necrodoom 862e71bc85 add recursive permission adding/removing
also other minor fixes
2014-05-04 12:50:03 +01:00
ElgarL 395655ba19 Check subgroup permissions with an equal priority so no one subgroup is higher ranked than another. 2014-05-04 12:50:02 +01:00
KHobbits 1bb569fff2 Fix attempting to spawn invalid items. 2014-04-30 05:41:42 +01:00
KHobbits e66ad88451 Skip npc's when doing cleanup. 2014-04-29 04:42:55 +01:00
KHobbits 3bf3093177 Better handle a write locked usermap.csv 2014-04-29 01:44:28 +01:00
KHobbits 5eb82add06 Run user dispose on another thread. 2014-04-28 23:12:35 +01:00
Corin Simpson-Bryars 8bd1a9f3bc Updating pom for vault
When deploying with Jenkins the build will fail due to there being no http://repo.ess3.net:8071/content/groups/public/net/milkbowl/vault/1.2.27 however there's a valid jar/dir for vault at http://repo.ess3.net:8071/content/groups/public/net/milkbowl/vault/Vault/1.2.32/
This will keep maven happy and the build not to error.
2014-04-28 00:52:06 +01:00
KHobbits 145d24c34c Fix /home for offline players. 2014-04-27 17:09:44 +01:00
KHobbits 229ff9f0e4 Update UUID mapping, if uuid for a username changes. 2014-04-27 01:35:52 +01:00
KHobbits 0557aa58b0 Switch AFK check to use UUID. 2014-04-27 01:10:44 +01:00
KHobbits b40aa43872 Delay uuidconversion for 10s and show warning.
UUID conversion should now better handle offline conversion.
2014-04-26 23:50:12 +01:00
KHobbits a1cdfa19b0 Fix time command exit statuses. 2014-04-24 10:24:35 +01:00
KHobbits d62b401db8 Skip empty user names on uuid conversion. 2014-04-22 18:07:02 +01:00
KHobbits 887957756e [Breaking] Fix ECO NPC's. This is a work around of CB's recent changes blocking invalid uuid lookups.
NPC's converted with the previous version will need manual changes.
2014-04-19 02:03:39 +01:00
KHobbits b6d6b24796 Only write to UUIDMap if the entry doesn't exist. 2014-04-18 06:48:14 +01:00
KHobbits b6c0871daa Format /seen account history list, optimize map loading. 2014-04-18 05:57:47 +01:00
KHobbits b080187808 Add previous account tracking to /seen 2014-04-18 04:48:34 +01:00
KHobbits 3c613fd59b Force CB 3050+ 2014-04-18 03:58:27 +01:00
KHobbits 547c6e4073 Fix offlineplayers with null names. 2014-04-17 06:09:08 +01:00
KHobbits 6098086a99 Optimize uuidmap writing, and use userConf write buffering. 2014-04-17 05:34:34 +01:00
KHobbits 87f90e9bdd Add progress status and /ess uuidconvert command for manual conversion. 2014-04-17 02:18:28 +01:00
KHobbits 65b1821196 Update Bukkit to 1.7.8-R0.1
Bukkit: 1922 CraftBukkit: 3050
2014-04-15 00:24:12 +01:00
KHobbits 756321d280 Add UUID mocking support, and fix tests. 2014-04-15 00:08:02 +01:00
KHobbits 3dbf69f163 Allow usermap to support legacy users, and restore ability to create user on first access, as well as server join. 2014-04-15 00:07:35 +01:00
KHobbits e8ace54036 Make eco npc methods use proper user config creation and resets. 2014-04-15 00:06:29 +01:00
KHobbits 22e1c14e7e Stop delayed writes from reversing user reset. 2014-04-15 00:05:56 +01:00
KHobbits cd38aeb544 Remove Ess object from FakeServer. 2014-04-14 00:03:07 +01:00
KHobbits 9e9409da1e Essentials UUID conversion. 2014-04-13 21:40:15 +01:00
KHobbits 36e580474f Converted emulated player class calls to use base class. 2014-04-13 01:01:49 +01:00
clou44 e007331581 Update items.csv
Added additional aliases for various flowers.
2014-04-10 23:31:05 +01:00
clou44 8d435ec86e Update items.csv
Added additional aliases for coal blocks.
2014-04-10 23:30:58 +01:00
KHobbits 214d64e4ad Update config.yml to reflect vanilla fallback no longer works. 2014-04-07 14:09:09 +01:00
KHobbits 737fadc390 Update Bukkit 1.7.5-R0.1
Bukkit 1919 CB: 3039
No UUID update yet.
2014-04-06 15:57:37 +01:00
KHobbits 10de6ac929 Cleanup 2014-04-06 15:44:37 +01:00
KHobbits fe9fbf585f Correctly handle line overflow in book pager
Fixes a bug with the last book pager tweak.
2014-04-05 15:33:38 +01:00
KHobbits af3f3fb4c7 Fix fly logic check (creative doesn't mean fly is enabled) 2014-03-31 03:26:48 +01:00
KHobbits 0e6a5240db Add chat configurables. 2014-03-30 15:50:32 +01:00
KHobbits f272a7ecd6 See if we can better handle book paging to fit more context on a line, without causing text loss after reaching character limit. 2014-03-29 16:07:32 +00:00
evonuts 104caea3c9 Minor phrasing fixes. 2014-03-26 22:08:37 +00:00
Matt Anthony 44fbd05df7 Add colors to a few TL keys. 2014-03-26 21:58:36 +00:00
KHobbits 6cfb5084e1 Add local echo to tempban command. 2014-03-26 20:08:38 +00:00
KHobbits ae1804758a Helpop should use broadcast method
Add local echo's to helpop and mute commands.
2014-03-26 20:06:01 +00:00
Necrodoom 4b470b32c5 Add socialspy wildcard support 2014-03-26 19:09:00 +00:00
Necrodoom cfe89dde17 Match /clearinventory multiple permission to /msg 2014-03-26 19:07:48 +00:00
Necrodoom 30dae51ddf Some messages fixes, and information addition. 2014-03-26 19:07:41 +00:00
KHobbits 0b11abf8f4 Revert "Do not allow a block with an Essentials Sign attached to it to be pulled with a sticky piston"
This reverts commit b673882b2f.
2014-03-26 15:14:40 +00:00
Chris Ward b673882b2f Do not allow a block with an Essentials Sign attached to it to be pulled with a sticky piston 2014-03-26 22:00:57 +11:00
KHobbits 200dbda6d3 Merge branch '2.x' of github.com:essentials/Essentials into 2.x 2014-03-23 18:14:21 +00:00
KHobbits 3538728733 Fix null teleport costs. 2014-03-23 18:12:33 +00:00
FearFree 5724c0c8df Future Java versions may not support _ as identifier. 2014-03-22 16:08:11 +11:00
KHobbits 0b5718f7ff Cleanup warp charging, to properly handle warp sign costs. 2014-03-19 00:01:47 +00:00
ElgarL c6b0dfaa4c Merge pull request #668 from necrodoom/patch-91
Fix messages
2014-03-12 15:41:53 +00:00
KHobbits 8fecd44786 Fix some /home errors with invalid data. 2014-03-09 17:59:07 +00:00
Dabo Ross 2ee590d85c Add IEssentialsSpawn class for API for Essentials Spawn with two methods, getSpawn(String) and setSpawn(String, Location).
Implement IEssentialsSpawn in EssentialsSpawn.
2014-03-09 17:31:36 +00:00
KHobbits b469439f7b Update translations from Crowdin
http://translate2.ess3.net/
2014-03-09 17:23:38 +00:00
Necrodoom a7d6e5440b Fix messages 2014-03-09 19:17:26 +02:00
Luke Anderson (stuntguy3000) 077074c855 Add missing language pointers 2014-03-09 17:14:09 +00:00
FearFree c59a204827 Remove op and replace with permission 2014-03-09 17:01:31 +00:00
KHobbits 1be30e4a0a Only enable teleport protection on plugin/command caused teleport events. 2014-03-09 01:13:41 +00:00
Dykam 28ec7c2d80 You can now access the old balance during the UserBalanceUpdateEvent Event 2014-03-04 19:44:55 +00:00
Kryptic Dot ee986768ce Cleaning up readme markdown 2014-03-04 19:29:47 +00:00
SkyBirdSoar de485b8d48 Fixed some grammatic errors, changed some sentences. 2014-03-04 19:26:16 +00:00
Zed Spencer-Milnes e443776dc1 Finish Sentence
# Setting to false means EssentialsAntiBuild will never prevent you from using.
->
# Setting to false means EssentialsAntiBuild will never prevent you from using items.

Am I glad to make such a profoud change to the source code.
2014-03-04 19:22:05 +00:00
Luke Anderson 859ffeaa0b Remove generated comments 2014-03-04 19:20:56 +00:00
KHobbits 545d706a70 Fix login death caused by built up fall damage using /fly. 2014-03-03 21:24:00 +00:00
KHobbits 9ec0ca25a5 User loading cleanup 2014-03-03 09:01:07 +00:00
KHobbits b0e165546e Round to gc output to 2 dp. 2014-03-03 08:34:43 +00:00
KHobbits 470f4c1b3e Constant user file casing. 2014-02-27 01:55:04 +00:00
KHobbits 3b35763fef Fix warp sign costs. 2014-02-25 07:09:32 +00:00
KHobbits 2d5c1fd51c Fix safety tp check above world height
Performance tweak to fly check
2014-02-23 17:41:25 +00:00
KHobbits 088c54e386 Fix customtext copy 2014-02-19 03:28:28 +00:00
KHobbits e409363426 Alternative implementation of unsafe enchant blocking for signs.
Permission: essentials.signs.enchant.allowunsafe - required to add unsafe enchants using enchant signs.
This reverts commit 3f2c2aadbb.
2014-02-19 01:18:40 +00:00
KHobbits 34599b7428 Fix projectiles compiling. 2014-02-19 00:58:20 +00:00
KHobbits 53c1c8a8b7 Update Bukkit to 1.7.3-R0.3 - Bukkit: 1903 CB: 3020
This also disables vanilla fallback, use new aliases file.
2014-02-19 00:36:54 +00:00
snowleo 3f2c2aadbb Split unsafe enchantments in kits to a new config option 2014-02-18 23:47:18 +01:00
KHobbits a1a190bb02 Merge branch '2.x' of github.com:essentials/Essentials into 2.x 2014-02-16 01:15:25 +00:00
KHobbits 6744b652e6 Use the absolute radius value. 2014-02-16 01:15:01 +00:00
Chris Ward 11b308cc8c Update repository URLs 2014-02-15 14:23:30 +11:00
KHobbits c50f559512 Allow sending customtext chapters as a parameter instead of reading commandLabel 2014-02-13 22:52:14 +00:00
KHobbits 98bee40bf7 Fix Stripping/blocking of urls containing caps. 2014-02-12 01:20:54 +00:00
Iaccidentally 970d342a60 Merge pull request #657 from evonuts/2.x
Fix spelling error (atleast) in translation files.
2014-02-11 02:27:10 -05:00
evonuts 2500c9af90 Fix spelling error (atleast) in translation files. 2014-02-11 20:15:14 +13:00
KHobbits fa765d3077 Fix world argument to ignore radius, and allow for skipping radius param in syntax. 2014-02-09 22:26:54 +00:00
KHobbits 9bc8f287a4 Fix ghost items with /recipe 2014-02-09 21:54:04 +00:00
Necrodoom 5e6ce8aecb Reorder ID 376 2014-02-09 21:37:03 +00:00
KHobbits 6174e4a98b Code cleanup and remove remote skull edit. 2014-02-08 01:23:54 +00:00
Luke Anderson (stuntguy3000) 5c74af42a3 Add /skull command 2014-02-08 00:25:34 +00:00
coegho ce48f2f326 [Fix] fireball-fire=true now prevents fire spread from fireballs 2014-02-08 00:22:56 +00:00
Necrodoom 2affce875c Restore 2 aliases 2014-02-08 00:16:11 +00:00
Necrodoom 52c8ebc61f Fix duplicates, a few more aliases addition/remove 2014-02-08 00:16:11 +00:00
KHobbits a9249deea7 Reformat pom 2014-02-08 00:13:46 +00:00
KHobbits d99c35cc35 Add bow as a skeleton keyword 2014-02-06 02:35:27 +00:00
Iaccidentally 518650e842 Modifier order consistency 2014-02-04 11:11:43 -05:00
KHobbits 20ff61909f Readme tweak. 2014-02-04 01:17:06 +00:00
KHobbits f0e4e8c5ba Add support for vanilla item names from api. 2014-02-02 19:04:09 +00:00
KHobbits 63300866f9 Fixed argument count for meta parsing. 2014-02-02 18:56:45 +00:00
KHobbits c8212371ff Allow the Essentials module to compile again. 2014-02-02 18:19:29 +00:00
KHobbits 0a6a79115a Raise minimum CB version to 2922 or 1.7.2-R0.1
This should prevent issued caused by UUID mismatch.
2014-02-02 17:13:44 +00:00
KHobbits 6798615507 Track UUID for future use. 2014-02-02 17:05:41 +00:00
KHobbits 016b39726c Restore teleporting to middle of block, when flying and unsafe is enabled. 2014-02-02 16:43:31 +00:00
KHobbits 882ebae257 [Breaking] Add exception when players have exceeded their account limit.
This might effect some plugins which hook Essentials for economy without using the API
2014-02-02 16:07:32 +00:00
KHobbits 161862bc53 Make sure we leave any vehicles before teleporting. 2014-02-02 15:04:07 +00:00
Iaccidentally 18b31a7e50 [FIX] Print a proper error when using tpaccept with no requester 2014-02-01 16:49:54 -05:00
Chris Ward 5b5be164b6 Allow the use of non-development Bukkit builds at runtime
Unsafe code is surrounded by sufficient handling
2014-01-30 10:43:26 +11:00
Chris Ward 466b4ae7c5 Restore Bukkit dependency to parent pom 2014-01-30 10:34:16 +11:00
KHobbits e7c468b20d Attempt to fix client issue with speed reset on world change. 2014-01-26 22:33:56 +00:00
KHobbits b9d09dd7b0 Make /speed persist on world change if permissions exist. 2014-01-26 20:00:41 +00:00
KHobbits 1c035457bb Force Bukkit version to match deps. 2014-01-25 23:29:48 +00:00
KHobbits 5070f15810 Use OSX character split on internal sign interface 2014-01-25 22:55:28 +00:00
Necrodoom c8faf03f5b Fix cauldron ID 2014-01-25 22:46:26 +00:00
Necrodoom 915cb51d1a Trim items.csv based on feedback 2014-01-25 22:46:25 +00:00
snowleo 52c3169a3c Read backup output async 2014-01-25 15:33:33 +01:00
Chris Ward 32b118d3c0 Add fullstops for @Necrodoom 2014-01-21 12:20:24 +11:00
Chris Ward 9ce1158aeb Add support for vanilla JSON metadata syntax (/give, /i, /kit, etc.) 2014-01-21 00:54:48 +11:00
Chris Ward 839bfe0c2e Update to Bukkit Development Builds
Change things so unit testing can run after Bukkit's breaking commit with classloader stuff
2014-01-20 21:20:13 +11:00
KHobbits f39ef36115 Fix hidden groups in /list 2014-01-14 21:55:30 +00:00
KHobbits eee18f40be Pass optional location parameters to teleport TL keys. 2014-01-12 01:23:12 +00:00
KHobbits 4084445b5b Config description cleanup. 2014-01-11 17:34:35 +00:00
Adam 8c882a5268 Reset Exhaustion on /feed 2014-01-08 01:07:38 +00:00
Chris Ward 3b0e86ae67 Add an upload-only pom file for GroupManager 2014-01-06 10:03:22 +11:00
KHobbits 3fecd3138d Check command cost, before running kit delay check, prevent accidentally delaying unran commands. 2014-01-03 08:16:17 +00:00
KHobbits d48c02021d Add and implement sign break/create/interact events to EssAPI
Implement AfkStatusChangeEvent
2013-12-31 17:47:52 +00:00
KHobbits 0b71b6e93d Remove redundant permission check. 2013-12-31 04:44:28 +00:00
KHobbits 99d25bfaea Fix NB parent compiling 2013-12-28 23:09:56 +00:00
KHobbits 46691871ad Add permission: essentials.msg.multiple and essentials.pay.multiple
Message permission will allow rough nick matches and wildcards, while pay will only allow wildcards.
2013-12-28 22:37:36 +00:00
Chris Ward 58440dd594 Add deploy plugin 2013-12-29 03:04:36 +11:00
Chris Ward 12c96e21b9 Use the Essentials Maven repository 2013-12-29 00:21:26 +11:00
Chris Ward 1d791fb110 Remove Ant, migrate Netbeans code style to pom.xml 2013-12-27 03:47:13 +11:00
Chris Ward 0384ac5d42 Travis - use Maven to build 2013-12-26 01:19:51 +11:00
SkyBirdSoar def1569fcc Add aliases to stationary water & stationary lava
New changes:
stillwater is an alias to 9:0 (Stationary water)
stilllava is an alias to 11:0 (Stationary lava)
2013-12-26 01:17:42 +11:00
Chris Ward 7d7e87e63a Pull geoip library from Maven 2013-12-26 01:12:04 +11:00
Chris Ward 8b26c7fc84 Use Ant to replace GroupManager's plugin.yml version 2013-12-22 19:21:19 +11:00
KHobbits 3017d2a7f4 Better matching of zombie and skeleton mobdata to avoid confusion. 2013-12-22 00:12:22 +00:00
KHobbits 23d2ffb134 Add {4} to homeSet TL key, this contains the name of the home being set. 2013-12-21 23:30:12 +00:00
KHobbits ad2f446602 Check command cost permissions prior to teleporting. Fixes ESS-4918 2013-12-21 23:19:58 +00:00
KHobbits bcd5350a4d Add extra /home message TL params
{1} = current home count
{2} = max home count
2013-12-21 17:42:55 +00:00
KHobbits b6b2ee61a4 Don't check for default worth durability if more than one durability price is defined.
This also adds support for '*' durability matching 'other'.
2013-12-21 03:33:27 +00:00
KHobbits 6362dbd5b3 Restore CB to lib folder 2013-12-21 02:39:26 +00:00
Chris Ward ee55584117 Use Bukkit beta build 2013-12-18 17:26:01 +11:00
KHobbits e5b522ed14 Try changing the config file home language up a little bit. 2013-12-17 19:23:28 +00:00
Necrodoom df219db1a4 fix gcWorld in de locale 2013-12-15 12:49:06 -06:00
Necrodoom f8e273767e Add cobweb aliases 2013-12-13 09:23:29 -06:00
Chris Ward 1bfab68932 Change teleport safety checks to use less expensive methods. 2013-12-13 19:41:57 +11:00
KHobbits 901b835ae0 Alter teleport cancel message to reflect config option. 2013-12-13 08:15:28 +00:00
Joshua Popoff 7d8d9d8959 Add the ability to disable teleport safety. Requested by a few people - teleport safety isn't always a good thing for some servers. Request is cancelled if not safe. 2013-12-13 17:07:26 +11:00
Chris Ward b70b58660f Remove Javadocs from the default compile, use the javadoc:javadoc goal to generate them. 2013-12-11 21:50:06 +11:00
Chris Ward 18a6d1761a Merge pull request #609 from Skylexia/patch-1
Fixed all the salmon.
2013-12-10 18:46:51 -08:00
Skylexia 9a197d65a3 Fixed all the salmon. 2013-12-10 20:42:56 -05:00
Iaccidentally b68e451c13 Merge pull request #607 from necrodoom/patch-67
Add new baked potato aliases - thanks clou44
2013-12-08 09:45:16 -08:00
Necrodoom 11949a4315 Add new baked potato aliases - thanks clou44 2013-12-08 19:44:14 +02:00
Chris Ward f52858d058 Strip all Mac OSX characters
Temporary workaround awaiting PR from Bukkit
2013-12-08 20:40:10 +11:00
md-5 90fc19cc7b Fix formatting from last commit 2013-12-08 17:00:53 +11:00
md_5 ddb1f76a26 Strip weird sign chars sent by OSX due to client bug 2013-12-08 16:57:44 +11:00
KHobbits 2584e0ab06 Update config.yml to reflect recent custom message settings. 2013-12-08 04:46:33 +00:00
KHobbits 5dbf4f5a00 Make it so both {world} and {worldname} work for both keyword parsers. 2013-12-07 23:58:47 +00:00
KHobbits af02a28ce5 Update Bukkit
Bukkit: #1859 CB: #2943
2013-12-07 22:26:41 +00:00
Necrodoom 5e9f5904fd Ignore empty chat events generated by plugins 2013-12-07 22:15:01 +00:00
KHobbits 946051de71 Add support for adding item meta to [free] signs.
Fix NPE on [sign] creation.
2013-12-07 20:25:23 +00:00
KHobbits 427b97433e Logger cleanup pt 1. 2013-12-07 20:03:05 +00:00
KHobbits f3b005e331 Cleanup /remove ingame syntax 2013-12-07 19:17:36 +00:00
KHobbits 5b64c31e86 Show warning when invalid mob type is specified for /remove 2013-12-07 19:03:29 +00:00
KHobbits 723e458a81 Remove requires at least one argument. 2013-12-07 18:46:25 +00:00
Chris Ward 309273dc6b Fix issue in login messages
Message wouldn't be displayed if silent join is enabled and custom is disabled. Probably.
2013-12-07 14:24:39 +11:00
Chris Ward d40e331c8a Disable the login message hooks automatically 2013-12-07 14:20:51 +11:00
Chris Ward c57e902173 Fix login messages 2013-12-07 13:44:41 +11:00
Chris Ward e864696b00 Revert "Fixed bug when logging in silently"
This reverts commit 5fe19dbd83.
2013-12-07 13:24:48 +11:00
Iaccidentally fed250fd74 Merge pull request #605 from Phryxiil/2.x
Fixed bug when logging in silently
2013-12-06 18:17:06 -08:00
Zarubinator 5fe19dbd83 Fixed bug when logging in silently 2013-12-06 21:15:27 -05:00
Chris Ward b836b3c041 Who doesn't love a good ol' NPE 2013-12-06 19:01:37 +11:00
Necrodoom 9550ef2a0d Fix glass pane IDs
remove duplicates in items.csv (thanks .itemdbparse)
2013-12-05 23:09:35 +00:00
Chris Ward bac26f966c Cleanup join/quit messages. 2013-12-05 23:08:29 +00:00
Chris Ward 278bb98649 Fix custom join messages Removes double message, adds colour codes and placeholders for the user's name. 2013-12-05 23:08:28 +00:00
TheReverend403 3839b6f1f5 Code cleanup 2013-12-05 23:06:04 +00:00
Necrodoom c0a58a5316 Update items.csv to 1.7.2 (beta file version) 2013-12-05 23:03:34 +00:00
KHobbits de7c2be960 Updated translations from crowdin 2013-12-05 23:03:34 +00:00
KHobbits c57c791e69 Cache join/quit messages. 2013-12-05 23:03:33 +00:00
Iaccidentally 1ae2b094f3 Add options to disable join/quit messages and custom join/quit messages 2013-12-05 23:03:33 +00:00
KHobbits dde8cd8f72 Merge remove and killall command, thanks to @Evonuts and @Iaccidentally. 2013-12-05 23:03:33 +00:00
Adam b3bad6a35a Add a title to [Disposal] and [Free] sign inventory 2013-12-05 23:03:33 +00:00
Chris Ward 25e4096a12 Update FakeServer - fixes compilation 2013-12-05 23:03:33 +00:00
KHobbits e411f61296 Update to first build of 1.7.2 - CraftBukkit is still buggy so expect issues
Bukkit: #1856 CB: #2922
2013-12-05 23:03:32 +00:00
iBo3oF caa3ac88aa Add Balance Update Event. 2013-12-05 23:03:31 +00:00
KHobbits f677d6a411 Tidy up string manipulation in trade signs. 2013-12-05 23:03:31 +00:00
KHobbits 4232216f76 Try to be a little less confusing with non-command debug errors. 2013-12-05 23:03:31 +00:00
KHobbits beef371ae6 Adding saddles to horses should properly tame horses. 2013-12-05 23:03:31 +00:00
Necrodoom 872df26e9d Do not block user damaging self (ender eye) 2013-11-17 19:19:42 +02:00
Joseph Jenniges 8146858ee0 Fix logic error with /kickall in console 2013-11-17 10:04:36 -06:00
snowleo 9b4e6e5dc6 Fix fromIndex = -20 2013-11-15 20:06:16 +01:00
KHobbits 53b1526906 Throw meaningful warnings when wrong Essentials version is used with unsupported mod packs. 2013-11-15 00:22:10 +00:00
Iaccidentally 82be7546d5 Tidy up Commandremove a bit, thanks to Evonuts 2013-11-10 23:25:42 +00:00
Iaccidentally f400f81e4d Add more functionality to the remove command. This now overlaps some functionality of the killall command, which should eventually be merged into this command and removed. new options: hostile, monsters, passive, animals, ambient, mobs, entities 2013-11-10 23:25:34 +00:00
KHobbits 5d1ea4aa88 Allow ignore to block tpahere requests. 2013-11-09 04:08:25 +00:00
KHobbits 7f8d62be02 Add a couple more enchant aliases for blast protection 2013-11-09 03:40:51 +00:00
Iaccidentally 3e725ef060 Cleanup various aspects of code, fix some formatting, more netbeans 7.4 stuff 2013-11-06 21:22:32 -05:00
Iaccidentally d5196e31b2 Add ability to supress join/leave messages :: new permissions: essentials.silentjoin & essentials.silentquit 2013-11-06 18:05:02 -05:00
Iaccidentally 235f134514 netbeans 7.4 stuff 2013-11-06 18:03:46 -05:00
KHobbits 6af1b923cc Update Bukkit and Craftbukkit jar files for stable 1.6.4
Bukkit: 1848 Craftbukkit: 2912
2013-10-28 00:29:01 +00:00
KHobbits 365888a8f9 Update Translation files from Crowdin:
http://translate2.ess3.net/
2013-10-28 00:21:41 +00:00
FearFree b8f5c9a8e4 Update for consistency.
Signed-off-by: KHobbits <rob@khobbits.co.uk>
2013-10-28 00:10:35 +00:00
FearFree ae89c80d4e Clarify no perm msgs for missing .offline perms
Signed-off-by: KHobbits <rob@khobbits.co.uk>
2013-10-28 00:10:33 +00:00
KHobbits 7436009ea4 Clarify message when ignoring exempt players. 2013-10-27 23:53:24 +00:00
Chris Ward 84ce3d39d8 Fix automatic versioning when compiling with Maven 2013-10-21 13:50:17 +11:00
KHobbits 9aa88bdf8d Add a little more group based debugging. 2013-10-21 01:20:09 +01:00
KHobbits f36f5ec0ce Add debug log entry when checking permission groups. 2013-10-20 17:45:37 +01:00
KHobbits b1d422ba8f Round up Y position when standing on half blocks. This should address some safelogin bugs. 2013-10-20 02:25:11 +01:00
KHobbits 049577c97e Restore deleted craftbukkit jar 2013-10-20 01:36:22 +01:00
KHobbits 92a9673652 Restore original give/take Money API 2013-10-19 12:26:28 +01:00
Chris Ward 1164bbd90d [Fix] Allow someone to change their nick to different case of the same thing 2013-10-19 12:19:40 +01:00
Chris Ward 4ea629628d Use a player's real name in /balance if they are vanished 2013-10-19 12:19:40 +01:00
Chris Ward 3e9a2377a8 Call Ant from Maven (for GM) 2013-10-19 12:19:40 +01:00
Chris Ward 48261daf89 Fix null pointer exception on kits with meta 2013-10-19 12:19:39 +01:00
Chris Ward 97d176ea27 Make looping commands see vanished players properly
Make /r check player existence in the correct order
2013-10-19 12:19:39 +01:00
Chris Ward e25e02d154 Add Maven Support 2013-10-19 12:19:39 +01:00
Chris Ward 50a9b5718c Fix double messages in targeted commands 2013-10-19 12:19:37 +01:00
Chris Ward 2615468a08 Remove .idea and *.iml from git 2013-10-18 17:32:47 +11:00
Chris Ward 298e677373 Fix /r 2013-10-18 17:23:27 +11:00
KHobbits 64e089e15b Cleanup 2013-10-18 00:07:35 +01:00
KHobbits be31b1695d Restore getUser API 2013-10-18 00:07:34 +01:00
KHobbits 6f85761f7f Extract CommandSender to CommandSource, this should prevent Ess user object leaks. 2013-10-16 21:05:33 +01:00
KHobbits cf9d79d24c Strip nickname prefix when doing displayname comparison. 2013-10-16 20:54:23 +01:00
Iaccidentally f53240191f Cleanup XMPP PR 2013-10-16 20:53:30 +01:00
patjense 27ee587887 add delayed task for XMPP presence update 2013-10-16 20:52:50 +01:00
patjense 601bdbff46 add XMPP presence management stack 2013-10-16 20:52:50 +01:00
patjense 12bf4e9dcf add update for global presence handler 2013-10-16 20:52:50 +01:00
KHobbits 59b501b2b1 Clean Imports 2013-10-11 03:44:41 +01:00
KHobbits 9e20f556e1 Allow for event based test cases. 2013-10-11 03:34:41 +01:00
Iaccidentally 375caa6f9e implement GodStatusChangeEvent 2013-10-11 03:14:51 +01:00
KHobbits cc34c02623 Update README.markdown 2013-10-07 01:34:42 +01:00
KHobbits cfa367dfc3 Allow recolouring own name. 2013-10-05 05:34:33 +01:00
KHobbits e1ff3542ae Cleanup 2013-10-05 03:27:40 +01:00
KHobbits 4951c204d2 Improve nick validation
Now matches nicks against userdata for conflicts
Now checks for empty string nicknames
2013-10-05 02:31:19 +01:00
KHobbits 122232a0e7 Add more API template and implement nick change event. 2013-10-05 02:11:39 +01:00
KHobbits 03368e45df Extract user match looping 2013-09-28 21:33:22 +01:00
Luke GB e6b76cadbc Adds even more clarification to metrics opt-out 2013-09-25 00:22:11 +01:00
TheReverend403 06e3d33845 Adds clarification to metrics opt-out 2013-09-25 00:18:43 +01:00
drtshock e853199d90 Format to the format with the formatter. 2013-09-24 09:38:30 +01:00
drtshock f7f7c2a68b Ignore list and no tpa to self. Fixes ESS-4456 ESS-4711
List users that you ignore when no arguments are given. Otherwise state
that no players are ignored.

Don't allow users to tpa or tpahere themself. This is a problem with
people "glitching" with how essentials finds a safe location to get
inside of places they shouldn't.
2013-09-24 09:38:29 +01:00
Iaccidentally 99c73f3d67 Update to 1.6.4 2013-09-19 21:38:15 -04:00
Chris Ward 6094485992 Cleanup 2013-09-18 22:22:56 +10:00
GunfighterJ 503d39ee55 Update ItemStack reference to getTypeId() 2013-09-17 23:23:45 +10:00
Chris Ward bd5fd2980f Require latest Bukkit RB 2013-09-17 21:08:20 +10:00
GunfighterJ a49895278b Push latest Bukkit RB 2013-09-17 06:06:34 -05:00
GunfighterJ 8d739d6a76 Fix translation typo 2013-09-15 16:43:16 -05:00
KHobbits 3963a528b3 Fix handling max warp pages. 2013-09-10 01:42:11 +01:00
KHobbits 7c686b4b58 Fix case sensitivity on {PLAYERLIST:group} 2013-09-06 23:54:37 +01:00
KHobbits 0a17489c9c Clarify kit errors 2013-09-05 15:40:43 +01:00
KHobbits 0926da3782 Expose other plugins ban masks. 2013-09-04 07:19:30 +01:00
KHobbits c056ba0059 Properly handle negative /clear amounts. 2013-09-04 06:35:53 +01:00
KHobbits df5d9a4db8 Reimplement 'private' keywords. 2013-09-01 00:24:11 +01:00
KHobbits 36c61eaa06 New enum cached, lazy generated KeywordReplacer
This runs before the pager, so keywords on other pages will still be parsed.
2013-08-31 23:11:08 +01:00
Pocketkid2 9908eb0619 Use Tamed instead of horse/ocelot/wolf 2013-08-31 19:36:41 +01:00
KHobbits 64743ef428 Add support for coloured authors on books
Fixes ESS-4690
2013-08-31 13:20:36 +01:00
KHobbits 2973b1335c Add debug output to keyword replacer 2013-08-30 13:37:49 +01:00
KHobbits 52e9cc6ba1 This tp req cancel isn't needed anymore. 2013-08-30 11:05:27 +01:00
KHobbits 62b4348842 Don't waste cpu on /baltop if eco is disabled. 2013-08-28 18:00:27 +01:00
KHobbits eca3be5cf3 Extend eco disable option to block eco lookups. This can be required to combat slow SQL economies.
This option is not recommended under normal circumstances.
2013-08-28 17:50:28 +01:00
KHobbits 3fb4d1f3bf Don't allow buying partial item sets via trade signs. 2013-08-28 13:42:08 +01:00
KHobbits f96359e31c Add another customtext example (including one with multiple aliases) 2013-08-20 23:43:40 +01:00
KHobbits cf79daddde Add support for {PLAYERLIST:GROUP} AND {PLAYERLIST:GROUP:<none>}
Replace <none> with what you want to show if there are no players from that group online.
2013-08-20 23:39:34 +01:00
Chris Ward ed007589f3 Add COORDS, UPTIME and TPS keywords 2013-08-20 22:14:29 +10:00
KHobbits b85aaea039 More colour. 2013-08-20 01:51:32 +01:00
KHobbits 3a4e4c59e4 Refresh default motd. 2013-08-19 22:00:30 +01:00
KHobbits 7f27de4bb7 Fix text file color code escaping (&&6 -> &6) Add support for color escaping in ingame chat Other formatting class cleanup 2013-08-19 21:37:44 +01:00
KHobbits a06a81c15d New command /customtext - This command is intended to be used with bukkit.yml aliases to make custom commands. 2013-08-19 21:37:33 +01:00
KHobbits a29e1bfe51 Add support for multiple bookmarks/chapter names
Clean up info file handling
2013-08-19 00:13:49 +01:00
KHobbits 3ccefb49c0 Fix tests 2013-08-18 22:48:13 +01:00
KHobbits 543672a2a8 Reset fall distance when toggling fly so fall damage is not accidentally applied. 2013-08-18 22:43:43 +01:00
KHobbits 8cba8da516 Fix a few issues with /list and group formatting. 2013-08-18 22:08:57 +01:00
KHobbits 3b8df2d18e Fix feed cooldown bypass permission:
Permission: essentials.feed.cooldown.bypass
2013-08-18 21:05:45 +01:00
KHobbits b8cdd7d1f7 Fix NPE in /kill when used from console. Thanks Necrodoom 2013-08-18 21:04:19 +01:00
KHobbits 92a2244650 Add muting offline players
Permission: essentials.mute.offline
2013-08-18 21:02:47 +01:00
KHobbits 75fe543579 Allow alternative command handler to also pass tab complete. 2013-08-15 21:58:23 +01:00
Necrodoom 7bc84d6cad items.csv - try move the most common item alias to top of aliases stack
without ore aliases remove
2013-08-15 21:37:55 +01:00
KHobbits 2928e8a99f Use essentials itemdb for charge messages. 2013-08-15 05:47:23 +01:00
KHobbits ffae86dd42 Use user object to send messages when possible. 2013-08-15 01:53:22 +01:00
KHobbits ff41588c3b Gracefully handle botched plugin starts 2013-08-13 23:41:54 +01:00
KHobbits 66eb9202ce Fix mail sendall from console skipping first param 2013-08-13 22:01:13 +01:00
Necrodoom f17ad2c4e7 fix config comment at heal-cooldown 2013-08-13 18:16:40 +01:00
Pocketkid2 794dd788a3 Update Commandremove.java
Fix class checking in /remove
2013-08-13 18:14:40 +01:00
Necrodoom b3cae17cab trim and replace spaces in chapter names to always work in commands 2013-08-13 18:07:27 +01:00
KHobbits 1ac5b4230e Teleport cleanup 2013-08-13 18:06:24 +01:00
GunfighterJ a3cae43f9f Fix NPE in /back when no previous location exists 2013-08-13 11:46:52 -05:00
KHobbits d329d27a4f Restore safe location for /top 2013-08-13 00:55:31 +01:00
KHobbits e9c0bd3bab Prevent inf loop when adding air to kits.
Should fix #4555
2013-08-12 00:26:51 +01:00
KHobbits c43574eab9 Fully support numerical worth yml data. 2013-08-11 23:43:45 +01:00
KHobbits 09e8b87650 When in fly+god mode or when in creative mode, don't use safe teleport location when teleporting to other players.
Enable fly in unsafe circumstances.
This only works when teleporting within worlds for permission reasons.
2013-08-11 22:42:29 +01:00
KHobbits ee05bf371d Update plugin.yml and add some aliases (Evonuts is going to hate me) 2013-08-11 22:10:56 +01:00
KHobbits fb9fc579d0 Allow toggling vanish for other players
Permission: essentials.vanish.others
2013-08-11 21:48:30 +01:00
KHobbits 8b11b870b1 General cleanup.
Add optional TL param for tempban/mute time in notify message
2013-08-11 21:34:26 +01:00
KHobbits 7401608cc5 The /tpahere command now stores the location of 'here' rather than using the current players location.
Cleanup teleport logic - This also fixes exploiting /tpahere to get accesses to restricted areas.
2013-08-11 16:37:21 +01:00
KHobbits 4cfa3fc3a2 Update Mob.java 2013-08-09 04:38:57 +01:00
Necrodoom 0d9db22d81 display syntax if more than one argument to avoid confusion with command purpose
more clearly, show syntax when people try to do /money give playername amount
2013-08-05 16:04:28 +01:00
KHobbits cc1ae2c243 Update Bukkit for 1.6.2R0.1 beta
CB: 2838 Bukkit: 2252
2013-08-05 04:15:26 +01:00
KHobbits 53faf70d10 Update Translations from crowdin 2013-08-05 00:19:44 +01:00
KHobbits 4d87033771 Force space after group in /list 2013-08-04 23:39:56 +01:00
GunfighterJ b08aaec6c0 Remove duplicate key 2013-08-04 12:53:46 -05:00
Pocketkid2 152cf98a9d Update Potions.java
Add extra alias
2013-08-04 11:38:48 -05:00
KHobbits 12cd467277 More missing syntax. 2013-08-03 02:48:50 +01:00
KHobbits bb7c8c308d Add missing command syntax for /spawnmob 2013-08-03 02:25:42 +01:00
Pocketkid2 c15540862d Update Commandkillall.java
Add support for horses
2013-07-29 21:40:52 +10:00
KHobbits ddc8c07cd7 Restore vault compat 2013-07-26 00:11:37 +01:00
Iaccidentally 0ef4dfd453 Merge pull request #524 from necrodoom/patch-40
fix mobdata typo
2013-07-25 10:51:08 -07:00
Necrodoom f50feedabb fix mobdata typo 2013-07-25 16:44:48 +02:00
GunfighterJ eb22254564 Close inventories before opening any others 2013-07-24 16:01:17 -05:00
KHobbits 3cfde70ec6 Use the correct name in /sethome if you don't have sethome.others permission. 2013-07-23 23:39:44 +01:00
KHobbits f251c9e694 Restore deprecated trade api
Fixes #4500
2013-07-23 22:48:32 +01:00
KHobbits 298da19334 Fix max radius. 2013-07-21 00:04:04 +01:00
okamosy e3c83be37e Refactored and cleaned up SpawnMob. Added context-aware help /spawnmob <mob>: 2013-07-20 21:29:13 +01:00
KHobbits c1e39c7007 Show if a IP is ip-banned on /seen <ip> 2013-07-19 02:25:50 +01:00
KHobbits 59515aed94 Cleanup worth and sell messages 2013-07-19 00:55:21 +01:00
snowleo 4eef8b5e84 Can't sell negative amount of items. 2013-07-19 01:01:52 +02:00
okamosy 8aac502ab6 Added horse armor /spawnmob horse:armor<iron|gold|diamond> 2013-07-17 23:32:25 +01:00
okamosy 3aca9f793b Added saddles to pigs and horses /spawnmob pig:saddle /spawnmob horse:saddle 2013-07-17 23:31:37 +01:00
KHobbits 4483ff40b4 Log notice when chat ignore is blocked by another plugin. 2013-07-17 23:26:26 +01:00
KHobbits e8d9951ee8 Add scaling object cap for usermap, prevent huge memory usage, also config file configurable. 2013-07-17 01:56:27 +01:00
okamosy bf675b230e Added horses to SpawnMob /spawnmob horse:<color><variant><style><chest> 2013-07-16 23:36:11 +01:00
KHobbits ba6fd95247 Fix radius logic 2013-07-15 23:15:35 +01:00
Necrodoom 419f51636a Max near radius 2013-07-15 23:10:55 +01:00
KHobbits f6f71126a1 Add missing param in /remove 2013-07-15 02:43:23 +01:00
KHobbits 1f3e52a4b9 Better handle esschat/GM reloading during async events. 2013-07-15 00:47:17 +01:00
KHobbits 0bfe1ec1de Update Craftbukkit
CB: 2814 Bukkit: 1792
2013-07-14 22:27:57 +01:00
KHobbits 00463a7899 Try to restore basic api functionality 2013-07-14 13:00:03 +01:00
KHobbits 11f87eccb0 Tidy and slightly expand user API 2013-07-14 12:41:27 +01:00
KHobbits 0d2dea41e3 Fix worth display bug 2013-07-14 12:09:49 +01:00
KHobbits 8009c1539a Fix local chat spy tag order. 2013-07-14 01:20:36 +01:00
KHobbits 29ea24f715 Throw syntax error instead of "For input string" 2013-07-14 01:07:59 +01:00
KHobbits a14104c529 Add support for /worth all and /worth hand 2013-07-14 01:03:08 +01:00
KHobbits d044ba2fb9 Whoops, wrong event. 2013-07-13 18:56:18 +01:00
KHobbits 5eb3d9fa42 Wrap ItemDb accessors and move Item string matching to itemdb class. 2013-07-13 18:52:53 +01:00
KHobbits fc63f63de6 Fix local message when no players are in the area
Allow any translation key to be silenced by blanking it in locale file
2013-07-13 18:46:26 +01:00
Iaccidentally cd51d718ba [API] flip! (╯°□°)╯︵ ┻━┻ 2013-07-13 13:40:46 -04:00
Iaccidentally 200ad81862 [API] fix implementation? 2013-07-13 12:52:08 -04:00
Iaccidentally c05ad0458f Merge branch 'API' of https://github.com/essentials/Essentials into API 2013-07-13 12:41:31 -04:00
Iaccidentally ecd2484cb9 [API] fix other modules to use new packages 2013-07-13 12:40:50 -04:00
KHobbits 43c2c02336 Fix failing XMPP build. 2013-07-13 17:36:35 +01:00
KHobbits adb5189d42 Add 'No one listening' message stub, will be empty by default and thus not sent. 2013-07-13 17:31:14 +01:00
KHobbits ef3b052c64 Remove old chat hook
Use Bukkit API for local chat handling
Implement localChatSpy event
2013-07-13 17:25:58 +01:00
Iaccidentally f5624d4cb6 [API] remove setters 2013-07-13 11:53:52 -04:00
Iaccidentally 624f7ab9f6 [API] Event framework 2013-07-13 11:48:05 -04:00
Iaccidentally dad348d3d0 [API] Move 2.x API to new package, create dummy classes for compatibility 2013-07-13 11:14:39 -04:00
Iaccidentally 3d0f0062a9 Merge branch '2.x' of https://github.com/essentials/Essentials into API 2013-07-13 10:38:28 -04:00
Necrodoom ab359f678a fix mute message when chatting
deny /mail if muted
2013-07-12 15:22:48 +01:00
GunfighterJ 406c9e807e Add horse to entity spawn protection blacklist 2013-07-11 12:37:09 -05:00
KHobbits d858555263 Don't cast sender to User. 2013-07-11 09:20:52 +01:00
KHobbits 72fd893733 Prevent speed from hitting absolute zero. 2013-07-11 08:58:22 +01:00
KHobbits 9f015c1bda Update TL files from Crowdin, this commit resets untranslated English to new colour scheme. 2013-07-10 22:36:27 +01:00
KHobbits 61ed77b60c Remove unused TL Keys 2013-07-10 22:14:23 +01:00
Iaccidentally e57aa0e088 tweak default setting for max nick length 2013-07-10 11:01:49 -04:00
Iaccidentally 2ad346e84c [FEATURE] Add configurable max nick length 2013-07-10 10:48:14 -04:00
KHobbits aa65a2b349 Update CB to 2808 2013-07-10 00:09:48 +01:00
KHobbits 499a1aee7f Fix TL handling with escaped ' marks. 2013-07-10 00:03:14 +01:00
KHobbits 3377e3483d Fix user comparison. 2013-07-09 09:08:26 +01:00
GunfighterJ 427d8cc4e0 Implement abstract methods 2013-07-08 19:28:24 -05:00
GunfighterJ 4e9a42671f Update to 1.6.2, adds new potion effect types 2013-07-08 19:22:38 -05:00
KHobbits a369f9aabb Standardize translation formatting. 2013-07-07 15:01:00 +01:00
KHobbits 2f4a19a5b8 Update Polish and Swedish translations from crowdin 2013-07-07 14:54:38 +01:00
KHobbits 6d360421f8 Translation cleanup
Allow '' in non format keys
Update French translation from crowdin
2013-07-07 14:52:31 +01:00
Gabriel D 03a10e80b9 Update some new text 2013-07-07 14:13:43 +01:00
KHobbits 1abacf00df More cleanup 2013-07-07 13:02:40 +01:00
KHobbits 3d29248ace Misc cleanup 2013-07-07 12:38:01 +01:00
KHobbits 3f5e2ad85a Whoops, we shouldn't be leaking the user object. 2013-07-07 11:51:12 +01:00
mrarroyo 817174e18f Fix punctuation 2013-07-07 02:17:25 +01:00
Chris Ward df2ab974bc Merge pull request #509 from necrodoom/patch-31
add horse egg
2013-07-02 02:25:49 -07:00
Necrodoom 423a722152 add horse egg 2013-07-02 12:20:20 +03:00
KHobbits 34f6487ba2 Add carpet to safe teleport materials. 2013-07-02 08:02:01 +01:00
KHobbits 522c3e85b2 Add command logging for CommandBlocks and other console types. 2013-07-02 07:16:42 +01:00
Iaccidentally 188a214de9 Merge pull request #503 from necrodoom/patch-26
update items.csv to Minecraft 1.6
2013-07-01 19:48:11 -07:00
GunfighterJ d0795fc3e7 Update Essentials for Bukkit 1.6.1-R0.1-SNAPSHOT 2013-07-01 21:38:27 -05:00
Necrodoom 95a2fce9a6 update items.csv to Minecraft 1.6 2013-07-01 13:03:24 -05:00
GunfighterJ d6ef0e1e50 Close the reader 2013-06-30 07:47:33 -05:00
GunfighterJ f6fd0bdb32 Force reading in UTF-8 from .txt files 2013-06-30 07:40:24 -05:00
Tyler Blair cb052e690c Update Plugin Metrics to R7 2013-06-29 18:05:42 +01:00
Iaccidentally 6af622b6b1 [API] Fix package naming 2013-06-28 15:30:47 -04:00
Iaccidentally dded3cae14 [API] fix references 2013-06-28 15:26:23 -04:00
Iaccidentally 6a3c5694ac [API] Cleanup 2013-06-28 15:21:49 -04:00
Iaccidentally 90c1df7cc7 [API] Remove some unneeded dependencies 2013-06-28 14:58:45 -04:00
Iaccidentally ff8c7b3315 [API] A basic example of a custom event, more to come. 2013-06-28 14:22:18 -04:00
KHobbits 0e43233e46 Add {TEAMPREFIX} {TEAMSUFFIX} and {TEAMNAME} to chat formatting. 2013-06-28 17:12:01 +01:00
KHobbits db234b9837 Force repair inventory refresh. 2013-06-28 14:14:43 +01:00
KHobbits 42b77864cd Minor colour tweak 2013-06-28 13:05:56 +01:00
KHobbits f485cbc48b Make the paging logic even more complicated. 2013-06-28 01:05:56 +01:00
KHobbits 0292cb59cd Drop messageFormat for simple string replace, remove duped ' marks. 2013-06-27 09:33:35 +01:00
KHobbits 3e519f95d5 Don't drop oversized stacks on the ground if player doesn't have oversized permission. 2013-06-26 21:44:34 +01:00
KHobbits 18d0183364 [Fix] Fix toggle syntax in plugin.yml 2013-06-26 08:57:26 +01:00
KHobbits 96cf363567 Merge pull request #504 from necrodoom/patch-30
[Fix] Fix socialspy toggle with no on/off param.
2013-06-26 00:51:51 -07:00
Necrodoom cfc6ed9364 fix socialspy toggles 2013-06-26 09:56:56 +03:00
KHobbits 3de3f00b11 Let's make the default group colour orange. 2013-06-26 01:22:18 +01:00
KHobbits c69c78f15c Don't automatically convert {chatparms} to [chatparams] 2013-06-25 18:04:31 +01:00
Necrodoom 0fdd367098 update items.csv to Minecraft 1.6 2013-06-25 19:04:29 +03:00
KHobbits 1a49cdd140 Fix null values. 2013-06-25 16:34:17 +01:00
ZerothAngel cd4bdb83d4 Add group/prefix/suffix support for zPermissions. 2013-06-25 16:24:23 +01:00
Luuk Jacobs f6fc9777b5 Reword some things, minor fixes and add punctuation.
more tiny fixes
minor unicode fix
2013-06-25 16:20:21 +01:00
KHobbits 9edc68bb2b Merge branch '2.x' of github.com:essentials/Essentials into 2.9 2013-06-25 16:00:32 +01:00
KHobbits 8f1f68f2be Merge pull request #502 from afistofirony/patch-1
Changing a spawner should update its BlockState.
2013-06-25 07:58:46 -07:00
KHobbits c0ed8649d0 Add missing variable. 2013-06-25 15:09:50 +01:00
Sahir f26466831a Changing a spawner should update its BlockState. 2013-06-25 17:07:43 +04:00
KHobbits c92ae00f9f Update KeywordReplacer.java 2013-06-24 13:31:07 +02:00
KHobbits 66355f0ead Update info.txt 2013-06-24 13:29:28 +02:00
KHobbits eeb9c13276 Merge pull request #499 from mozoa/patch-1
Update messages_nl.properties
2013-06-23 15:41:51 -07:00
KHobbits 9300529113 Merge pull request #501 from theudis/patch-6
Update messages_fr.properties
2013-06-23 15:41:30 -07:00
theudis 19e4acfc97 Update messages_fr.properties 2013-06-24 00:18:58 +03:00
KHobbits 1cb9ddf9fe [Feature] Allow the placing of spawners with predefined network id's (/i spawner:50)
[Permission] essentials.spawnerconvert.<mobname> - Allow the placing of specific mobspawners with premade network id's.
2013-06-23 16:11:24 +01:00
mozoa c801bc0173 Update messages_nl.properties
Reworded some strings
and changed the order of words
2013-06-23 16:49:08 +02:00
KHobbits 88d025cd0f Merge pull request #498 from mozoa/patch-1
Added /ci lines
2013-06-22 16:49:48 -07:00
mozoa dc1469105b Update messages_nl.properties 2013-06-22 22:51:38 +03:00
mozoa d3e0966b3f Update messages_nl.properties
Added new CI lines
bit indifferent about line 543 and 544
2013-06-22 22:49:26 +03:00
KHobbits a15e0b3875 [Feature] Expand /ci to allow removing certain amounts, and breakdown on the items removed. 2013-06-22 17:36:35 +01:00
KHobbits 52ba151b81 Clean up exception types. 2013-06-22 16:33:22 +01:00
KHobbits aa6c6b4d48 Fix missing Unicode in NL TL 2013-06-21 11:23:01 +01:00
KHobbits 7648e38ec2 Reduce restrictions on same item trading, so only identical items are blocked. 2013-06-20 21:14:28 +01:00
mozoa a67520477b Update NL locale 2013-06-20 21:07:58 +01:00
KHobbits f8fb8935d7 [Fix] Don't throw the wrong error message when using group limited kit signs. 2013-06-19 21:20:58 +01:00
GunfighterJ 8ae0ea98a3 Merge pull request #489 from necrodoom/patch-23
fix permission check typo (thanks to #4365)
2013-06-18 11:01:17 -07:00
Necrodoom 5338f6b706 fix permission check typo (thanks to #4365) 2013-06-18 20:57:30 +03:00
661 changed files with 105970 additions and 89817 deletions

No files matched your search

+183
View File
@@ -0,0 +1,183 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<!-- based on https://github.com/KyoriPowered/adventure/blob/master/.checkstyle/checkstyle.xml -->
<module name="Checker">
<property name="charset" value="UTF-8"/>
<property name="fileExtensions" value="java, properties, xml"/>
<property name="severity" value="error"/>
<!-- https://checkstyle.org/config_filefilters.html#BeforeExecutionExclusionFileFilter -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<!-- https://checkstyle.org/config_whitespace.html#FileTabCharacter -->
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<!-- https://checkstyle.org/config_misc.html#NewlineAtEndOfFile -->
<module name="NewlineAtEndOfFile"/>
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
<module name="SuppressionFilter">
<property name="file" value="${checkstyle.suppressions.file}"/>
</module>
<!-- https://checkstyle.org/config_filters.html#SuppressWithPlainTextCommentFilter -->
<module name="SuppressWithPlainTextCommentFilter"/>
<module name="TreeWalker">
<!-- https://checkstyle.org/config_misc.html#ArrayTypeStyle -->
<module name="ArrayTypeStyle"/>
<!-- https://checkstyle.org/config_imports.html#AvoidStarImport -->
<module name="AvoidStarImport"/>
<!-- https://checkstyle.org/config_misc.html#AvoidEscapedUnicodeCharacters -->
<module name="AvoidEscapedUnicodeCharacters">
<property name="allowByTailComment" value="true"/>
<property name="allowEscapesForControlCharacters" value="true"/>
<property name="allowNonPrintableEscapes" value="true"/>
<property name="severity" value="info"/>
</module>
<!-- https://checkstyle.org/config_misc.html#CommentsIndentation -->
<module name="CommentsIndentation"/>
<!-- https://checkstyle.org/config_whitespace.html#EmptyForInitializerPad -->
<module name="EmptyForInitializerPad"/>
<!-- https://checkstyle.org/config_whitespace.html#EmptyForIteratorPad -->
<module name="EmptyForIteratorPad"/>
<!-- https://checkstyle.org/config_whitespace.html#EmptyLineSeparator -->
<module name="EmptyLineSeparator">
<property name="allowMultipleEmptyLines" value="false"/>
<property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
<property name="allowNoEmptyLineBetweenFields" value="true"/>
<property name="tokens"
value="CLASS_DEF, CTOR_DEF, ENUM_DEF, IMPORT, INSTANCE_INIT, INTERFACE_DEF, METHOD_DEF, STATIC_IMPORT, STATIC_INIT, VARIABLE_DEF"/> <!-- remove PACKAGE_DEF, temporarily remove COMPACT_CTOR_DEF, RECORD_DEF -->
</module>
<!-- https://checkstyle.org/config_coding.html#FallThrough -->
<module name="FallThrough">
<property name="checkLastCaseGroup" value="true"/>
</module>
<!-- https://checkstyle.org/config_design.html#FinalClass -->
<module name="FinalClass"/>
<!-- https://checkstyle.org/config_coding.html#FinalLocalVariable -->
<module name="FinalLocalVariable"/>
<!-- https://checkstyle.org/config_whitespace.html#GenericWhitespace -->
<module name="GenericWhitespace"/>
<!-- https://checkstyle.org/config_design.html#HideUtilityClassConstructor -->
<module name="HideUtilityClassConstructor"/>
<!-- https://checkstyle.org/config_imports.html#IllegalImport -->
<module name="IllegalImport">
<property name="illegalPkgs" value="sun, jdk, com.sun"/>
</module>
<!-- https://checkstyle.org/config_coding.html#IllegalTokenText -->
<module name="IllegalTokenText">
<property name="format"
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
<property name="message"
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
<property name="tokens" value="CHAR_LITERAL, STRING_LITERAL"/>
</module>
<!-- https://checkstyle.org/config_misc.html#Indentation -->
<module name="Indentation"/>
<!-- https://checkstyle.org/config_blocks.html#LeftCurly -->
<module name="LeftCurly"/>
<!-- https://checkstyle.org/config_naming.html#MethodName -->
<module name="MethodName">
<property name="format" value="^[_]?[a-z][a-zA-Z0-9]*$"/>
</module>
<!-- https://checkstyle.org/config_whitespace.html#MethodParamPad -->
<module name="MethodParamPad"/>
<!-- https://checkstyle.org/config_javadoc.html#MissingJavadocMethod -->
<module name="MissingJavadocMethod">
<property name="allowMissingPropertyJavadoc" value="true"/>
<property name="tokens" value="METHOD_DEF, ANNOTATION_FIELD_DEF"/> <!-- remove CTOR_DEF, COMPACT_CTOR_DEF -->
</module>
<!-- https://checkstyle.org/config_javadoc.html#MissingJavadocType -->
<module name="MissingJavadocType"/>
<!-- https://checkstyle.org/config_coding.html#NoFinalizer -->
<module name="NoFinalizer"/>
<!-- https://checkstyle.org/config_whitespace.html#NoLineWrap -->
<module name="NoLineWrap"/>
<!-- https://checkstyle.org/config_whitespace.html#NoWhitespaceAfter -->
<module name="NoWhitespaceAfter">
<property name="allowLineBreaks" value="false"/>
</module>
<!-- https://checkstyle.org/config_whitespace.html#NoWhitespaceBefore -->
<module name="NoWhitespaceBefore">
<property name="allowLineBreaks" value="true"/>
</module>
<!-- https://checkstyle.org/config_coding.html#OneStatementPerLine -->
<module name="OneStatementPerLine"/>
<!-- https://checkstyle.org/config_misc.html#OuterTypeFilename -->
<module name="OuterTypeFilename"/>
<!-- https://checkstyle.org/config_imports.html#RedundantImport -->
<module name="RedundantImport"/>
<!-- https://checkstyle.org/config_modifier.html#RedundantModifier -->
<module name="RedundantModifier">
<property name="tokens"
value="ANNOTATION_FIELD_DEF, CLASS_DEF, CTOR_DEF, ENUM_DEF, INTERFACE_DEF, VARIABLE_DEF"/> <!-- remove METHOD_DEF and RESOURCE -->
</module>
<!-- https://checkstyle.org/config_coding.html#RequireThis -->
<module name="RequireThis"/>
<!-- https://checkstyle.org/config_blocks.html#RightCurly -->
<module name="RightCurly">
<property name="id" value="RightCurlyAlone"/>
<property name="option" value="alone"/>
<property name="tokens"
value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_DEF, INSTANCE_INIT, LITERAL_FOR, LITERAL_WHILE, METHOD_DEF, STATIC_INIT"/>
</module>
<module name="RightCurly">
<property name="id" value="RightCurlySame"/>
<property name="option" value="same"/>
<property name="tokens"
value="LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_IF, LITERAL_TRY"/> <!-- add LITERAL_DO -->
</module>
<!-- https://checkstyle.org/config_whitespace.html#SingleSpaceSeparator -->
<module name="SingleSpaceSeparator">
<property name="validateComments" value="true"/>
</module>
<!-- https://checkstyle.org/config_whitespace.html#TypecastParenPad -->
<module name="TypecastParenPad"/>
<!-- https://checkstyle.org/config_coding.html#UnnecessaryParentheses -->
<module name="UnnecessaryParentheses"/>
<!-- https://checkstyle.org/config_imports.html#UnusedImports -->
<module name="UnusedImports"/>
</module>
</module>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suppressions PUBLIC "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" "http://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<suppress files=".*[\\/]test[\\/]java[\\/].*" checks="RequireExplicitVisibilityModifier"/>
<!-- TODO: don't suppress I-prefixed API interfaces under com.earth2me.essentials -->
<suppress files="(com[\\/]earth2me[\\/]essentials[\\/]|net[\\/]ess3[\\/])(?:[^\\/]+$|(?!api)[^\\/]+[\\/])" checks="MissingJavadoc(Method|Type)"/>
</suppressions>
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/bukkit-0.0.1-SNAPSHOT.jar"/>
<classpathentry kind="lib" path="lib/Permissions3.jar"/>
</classpath>
+13
View File
@@ -0,0 +1,13 @@
# Currently used
patreon: EssentialsX
ko_fi: 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
#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
+5
View File
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: MOSS Discord Server
url: https://discord.gg/casfFyh
about: Need help with using EssentialsX? Join the MOSS Discord server for help.
+86
View File
@@ -0,0 +1,86 @@
---
name: Help!
about: Encountered a problem with EssentialsX? Not sure how to fix it?
labels: 'type: question'
---
<!-- EssentialsX help request guide
NOTE: Failure to fill out this template properly may result in your issue being
delayed or ignored.
Don't type between any arrows in the template, as this text will be hidden.
This includes this header block and any other explanatory text blocks.
Want faster support? Come join our Discord server to get help from both
developers and community members: https://discord.gg/F7gexAQ
If you're happy to wait (or you were sent here from Discord), read on:
1. Check the Common Issues page.
Read through the wiki page to see if you've encountered a regular issue:
https://essentialsx.net/wiki/Common-Issues.html
2. Fill out the template.
Run the commands in the console. Don't just put "latest" as a version, or
we will ignore it. This will help us understand what problem you've
encountered and help us find a solution.
3. When linking logs or config files, do not attach them to the post!
Copy and paste any logs into https://gist.github.com/, then paste a
link to them in the relevant parts of the template. Do not use Hastebin
or Pastebin, as this can cause issues when trying to solve issues in the
future.
**DO NOT drag logs into this text box!**
4. If you are encountering a performance issue, please include a link to a
Timings and/or profiler report.
-->
### Information
**Full output of `/ess version`:**
<!--
Run /ess version in the console, then paste the full output of the command
between the ```s.
-->
```
```
**Server startup log:**
<!--
Restart your server and upload `logs/latest.log` to
https://gist.github.com/. You may redact sensitive data (such as IP
addresses), but you should make it clear what data was removed. Once
uploaded, paste the link below this block.
-->
**EssentialsX config:**
<!--
Upload `plugins/Essentials/config.yml` (and other config files if relevant)
to https://gist.github.com/ then paste the link below this block.
-->
### Help request
**Problem:**
<!-- What problem did you encounter? Type below this line. -->
**What I have tried:**
<!-- What have you tried so far? Type below this line. -->
**Console stack trace:**
<!--
If you are reporting an error in the console, paste it between the ```s.
-->
```
```
**Screenshots:**
<!-- If relevant, include any screenshots or a video below this line. -->
+83
View File
@@ -0,0 +1,83 @@
---
name: Report a bug
about: Report an EssentialsX bug. Only use this if you're 100% sure there's something wrong with EssentialsX - otherwise, try "Help!".
labels: 'bug: unconfirmed'
---
<!-- EssentialsX bug reporting guide
NOTE: Failure to fill out this template properly may result in your issue being
delayed or ignored.
Don't type between any arrows in the template, as this text will be hidden.
This includes this header block and any other explanatory text blocks.
If you are reporting a bug, please follow the following steps:
1. Fill out the template in full.
Run the commands in the console. Don't just put "latest" as a version,
or we will ignore it.
2. When linking files, do not attach them to the post!
Copy and paste any logs into https://gist.github.com/, then paste a
link to them in the relevant parts of the template. Avoid using
Hastebin or Pastebin, as this makes providing support more difficult.
**DO NOT drag files into this text box!**
3. If you are reporting a performance issue, please include a link to a
Timings and/or profiler report.
4. If you are reporting a bug with commands or something else in-game,
please include screenshots to help us diagnose the problem.
-->
### Information
**Full output of `/ess version`:**
<!--
Run /ess version in the console, then paste the full output of the command
between the ```s.
-->
```
```
**Server startup log:**
<!--
Restart your server and upload `logs/latest.log` to
https://gist.github.com/. You may redact sensitive data (such as IP
addresses), but you should make it clear what data was removed. Once
uploaded, paste the link below this block.
-->
**EssentialsX config:**
<!--
Upload `plugins/Essentials/config.yml` (and other config files if relevant)
to https://gist.github.com/ then paste the link below this block.
-->
### Details
**Description:**
<!-- What is the bug? Type a brief summary below this line. -->
**Steps to reproduce:**
<!-- How did you cause it? Describe what you did to cause the bug below. -->
**Expected behavior:**
<!-- What did you expect to happen? Type below this line. -->
**Console stack trace:**
<!--
If you are encountering an error in the console, paste it between the ```s.
-->
```
```
**Screenshots:**
<!-- If necessary, include screenshots or a video below this line. -->
@@ -0,0 +1,52 @@
---
name: Request a feature
about: Suggest a feature you want to see in EssentialsX!
labels: 'type: enhancement'
---
<!-- EssentialsX feature request guide
NOTE: Failure to fill out this template properly may result in your issue being
delayed or ignored.
Don't type between any arrows in the template, as this text will be hidden.
This includes this header block and any other explanatory text blocks.
Not sure if your feature fits in EssentialsX? Feel free to ask on our Discord
server: https://discord.gg/F7gexAQ
If you have a feature suggestion for EssentialsX, read the following tips:
1. Fill out the template.
This will help us understand what you're requesting and why you want us
to add it.
2. Keep it simple.
Make sure it's easy to understand what you're requesting. A good way is
to keep it to one request per GitHub issue, as we can then easily track
feature requests.
3. Check whether it has already been asked or added.
You can search the issue tracker to see if your feature has already been
requested at https://github.com/EssentialsX/Essentials/issues. You can
also check the changelogs to see if the feature was recently added:
https://github.com/EssentialsX/Essentials/releases
4. Ask yourself: "Does this belong in EssentialsX?"
There are lots of features that we reject because most servers won't
need or use them. If your feature is very specific or already exists in
another plugin, it might not be a good fit for EssentialsX.
-->
### Feature request
**Feature description:**
<!-- What feature are you suggesting? Type below this line. -->
**How the feature is useful:**
<!--
How is the feature useful to players, server owners and/or developers?
Type below this block.
-->
+82
View File
@@ -0,0 +1,82 @@
---
name: Bug fix
about: Use this if your PR fixes a bug in EssentialsX.
labels: 'type: bugfix'
---
<!-- EssentialsX bug fix submission guide
NOTE: Failure to fill out this template properly may result in your PR being
delayed or ignored without warning.
Don't type between any arrows in the template, as this text will be hidden.
This includes this header block and any other explanatory text blocks.
Want to discuss your PR before submitting it? Join the EssentialsX Development
server: https://discord.gg/CUN7qVb
By contributing to EssentialsX, you agree to license your code under the
GNU General Public License version 3, which can be found at the link below:
https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE
If you are submitting a bug fix, please follow the following steps:
1. Fill out the template in full.
This includes providing screenshots and a link to the original bug
report. If there isn't an existing bug report, we recommend opening a new
detailed bug report BEFORE opening your PR to fix it, else your PR may be
delayed or rejected without warning.
You can open a new bug report by following this link:
https://github.com/EssentialsX/Essentials/issues/new/choose
2. When linking logs or config files, do not attach them to the post!
Copy and paste any logs into https://gist.github.com/, then paste a
link to them in the relevant parts of the template. Do not use Hastebin
or Pastebin, as this can cause issues with future reviews.
**DO NOT drag logs into this text box!**
3. If you are fixing a performance issue, please include a link to a
Timings and/or profiler report, both before and after your PR.
4. If you are fixing a visual bug, such as in commands, please include
screenshots so that we can more easily review the proposed fix.
(You may drag screenshots directly into this box.)
-->
### Information
<!--
Replace #nnnn with the number of the original issue. If this PR fixes
multiple issues, you should repeat the phrase "fixes #nnnn" for each issue.
-->
This PR fixes #nnnn.
### Details
**Proposed fix:**
<!-- Type a description of your proposed fix below this line. -->
**Environments tested:**
<!--
Below this line, put an "x" inside the box for the environments you have
tested this bug fix on, and if relevant alter the OS and Java version
accordingly. If this feature does not apply to an environment, strike
through the environment using ~~strikethrough~~. If you have tested on
other environments, add a new line with relevant details.
-->
- [ ] [Latest](https://papermc.io/downloads) Paper Version (any OS, any Java 8+ version)
- [ ] CraftBukkit/Spigot/Paper 1.12.2 (any OS, any Java 8+ version)
- [ ] CraftBukkit 1.8.8 (any OS, any Java 8+ version)
**Demonstration:**
<!--
Below this block, include screenshots/log snippets from before and after as
necessary. If you have created or used a test case plugin, please link to a
download of the plugin, source code and exact version used where possible.
-->
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: MOSS Discord Server
url: https://discord.gg/casfFyh
about: Need help with using EssentialsX? Join the MOSS Discord server for help.
- name: EssentialsX Development Discord Server
url: https://discord.gg/CUN7qVb
about: Got questions or want to discuss changes before opening your PR? Join the EssentialsX Development Discord server. (Need help? Join MOSS instead.)
@@ -0,0 +1,82 @@
---
name: Feature addition
about: Use this if your PR adds a new feature to EssentialsX.
labels: 'type: enhancement'
---
<!-- EssentialsX feature submission guide
NOTE: Failure to fill out this template properly may result in your PR being
delayed or ignored without warning.
Don't type between any arrows in the template, as this text will be hidden.
This includes this header block and any other explanatory text blocks.
Want to discuss your PR before submitting it? Join the EssentialsX Development
server: https://discord.gg/CUN7qVb
By contributing to EssentialsX, you agree to license your code under the
GNU General Public License version 3, which can be found at the link below:
https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE
If you are submitting a new feature, please follow the following steps:
1. Fill out the template in full.
This includes providing screenshots and a link to the original feature
request. If there isn't an existing feature request, we strongly
recommend opening a new feature request BEFORE opening your PR to
implement it, as this allows us to review whether we're likely to accept
your feature in advance, and also allows us to discuss possible
implementations for the feature. If there is no associated feature
request, your PR may be delayed or rejected without warning.
You can open a new feature request by following this link:
https://github.com/EssentialsX/Essentials/issues/new/choose
2. If you are fixing a performance issue, please use the "Bug fix" PR template
instead. The "bug fix" template is better suited to performance issues.
3. Include a demonstration.
If you are adding commands, please provide screenshots and/or a video
demonstration of the feature. Similarly, if you are adding a new API,
please include a link to example code that takes advantage of your
proposed API. This will aid us in reviewing PRs and speed up the process
significantly.
-->
### Information
<!--
Replace #nnnn with the number of the original issue. If this PR implements
features from multiple issues, you should repeat the phrase "closes #nnnn"
for each issue.
-->
This PR closes #nnnn.
### Details
**Proposed feature**
<!-- Type a description of your proposed feature below this line. -->
**Environments tested:**
<!--
Below this block, put an "x" inside the box for the environments you have
tested this bug fix on, and if relevant alter the OS and Java version
accordingly. If this feature does not apply to an environment, strike
through the environment using ~~strikethrough~~. If you have tested on
other environments, add a new line with relevant details.
-->
- [ ] [Latest](https://papermc.io/downloads) Paper Version (any OS, any Java 8+ version)
- [ ] CraftBukkit/Spigot/Paper 1.12.2 (any OS, any Java 8+ version)
- [ ] CraftBukkit 1.8.8 (any OS, any Java 8+ version)
**Demonstration:**
<!--
Below this block, include screenshots/code snippets from before and after
as necessary. If you have created or used a test case plugin, please link
to a download of the plugin, source code and exact version used where
possible.
-->
+38
View File
@@ -0,0 +1,38 @@
name: Build EssentialsX
on:
push:
branches:
- 2.x
- mc/*
pull_request:
branches:
- 2.x
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Git repo
uses: actions/checkout@v1
- name: Restore Maven cache
uses: actions/cache@v1
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
run: mvn package verify --file pom.xml
- name: Copy artifacts
run: mkdir -p ./out/ && cp -t ./out/ **/target/Essentials*.jar
- uses: actions/upload-artifact@master
with:
name: Plugin jars
path: out/
+22 -47
View File
@@ -1,47 +1,22 @@
.DS_Store
/BuildAll/nbproject/private/
/EssentialsProtect/nbproject/private/
/EssentialsChat/nbproject/private/
/EssentialsGroupBridge/nbproject/private/
/EssentialsGeoIP/nbproject/private/
/EssentialsSpawn/nbproject/private/
/EssentialsXMPP/nbproject/private/
/EssentialsGroupManager/nbproject/private/
/BuildAll/build/
/EssentialsGroupBridge/dist/
/EssentialsGroupBridge/build/
/EssentialsGeoIP/dist/
/EssentialsGeoIP/build/
/EssentialsGroupManager/build/
/EssentialsGroupManager/dist/
/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
/.idea
*.iml
/EssentialsGroupManager/bin
/EssentialsGroupManager/.externalToolBuilders
/EssentialsAntiBuild/nbproject/private/
/EssentialsAntiBuild/dist/
/EssentialsAntiBuild/build/
/jars
/out
# Other IDE files
*.classpath
*.project
*.settings/
.idea/*
*.iml
.DS_Store
# Checkstyle-IDEA config
!.idea/checkstyle-idea.xml
# Essentials files
/Essentials/userdata
/Essentials/config.yml
/Essentials/kits.yml
/Essentials/userdata/testplayer1.yml
/Essentials/usermap.csv
# Build files
target/
jars/
out/
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="active-configuration" value="PROJECT_RELATIVE:$PROJECT_DIR$/.checkstyle/checkstyle.xml:EssentialsX" />
<entry key="checkstyle-version" value="8.36.2" />
<entry key="copy-libs" value="true" />
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
<entry key="location-2" value="PROJECT_RELATIVE:$PROJECT_DIR$/.checkstyle/checkstyle.xml:EssentialsX" />
<entry key="property-2.checkstyle.suppressions.file" value=".checkstyle/suppressions.xml" />
<entry key="scan-before-checkin" value="false" />
<entry key="scanscope" value="JavaOnly" />
<entry key="suppress-errors" value="false" />
</map>
</option>
</component>
</project>
-17
View File
@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Essentials</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
-17
View File
@@ -1,17 +0,0 @@
language: java
jdk:
- oraclejdk7
- openjdk7
- openjdk6
script: ant collect
notifications:
irc:
channels:
- "irc.esper.net#lain"
on_success: change
on_failure: always
email:
recipients:
- "khobbits@ess3.net"
on_success: change
on_failure: always
-74
View File
@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="BuildAll" default="default" basedir=".">
<description>Builds, tests, and runs the project BuildAll.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar-with-manifest: JAR building (if you are using a manifest)
-do-jar-without-manifest: JAR building (if you are not using a manifest)
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="BuildAll-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>
File diff suppressed because it is too large. Load diff
-8
View File
@@ -1,8 +0,0 @@
build.xml.data.CRC32=cab45985
build.xml.script.CRC32=7a797370
build.xml.stylesheet.CRC32=28e38971@1.50.3.46
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=b4df970c
nbproject/build-impl.xml.script.CRC32=8905537e
nbproject/build-impl.xml.stylesheet.CRC32=6ddba6b6@1.53.1.46
-129
View File
@@ -1,129 +0,0 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=BuildAll
application.vendor=
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs=true
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width=2
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab=2
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=2
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=120
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap=none
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineAnnotationArgs=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineArrayInit=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineAssignment=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineBinaryOp=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineCallArgs=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineDisjunctiveCatchTypes=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineFor=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineImplements=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineMethodParams=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineParenthesized=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineTernaryOp=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineThrows=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineTryResources=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.blankLinesAfterClassHeader=0
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.blankLinesBeforeClass=2
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement=NEW_LINE
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.expand-tabs=false
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indent-shift-width=4
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indentCasesFromSwitch=false
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement=NEW_LINE
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement=NEW_LINE
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeCatchOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeElseOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeFinallyOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeWhileOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceAfterTypeCast=false
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaces-per-tab=4
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.tab-size=4
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/BuildAll.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
includes=**
jar.compress=true
javac.classpath=\
${reference.Essentials.jar}:\
${reference.EssentialsChat.jar}:\
${reference.EssentialsAntiBuild.jar}:\
${reference.EssentialsProtect.jar}:\
${reference.EssentialsSpawn.jar}:\
${reference.EssentialsGeoIP.jar}:\
${reference.EssentialsXMPP.jar}:\
${reference.EssentialsGroupManager.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.processorpath=\
${javac.classpath}
javac.source=1.6
javac.target=1.6
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=default_platform
project.Essentials=../Essentials
project.EssentialsChat=../EssentialsChat
project.EssentialsGeoIP=../EssentialsGeoIP
project.EssentialsGroupManager=../EssentialsGroupManager
project.EssentialsAntiBuild=../EssentialsAntiBuild
project.EssentialsProtect=../EssentialsProtect
project.EssentialsSpawn=../EssentialsSpawn
project.EssentialsXMPP=../EssentialsXMPP
reference.Essentials.jar=${project.Essentials}/dist/Essentials.jar
reference.EssentialsChat.jar=${project.EssentialsChat}/dist/EssentialsChat.jar
reference.EssentialsGeoIP.jar=${project.EssentialsGeoIP}/dist/EssentialsGeoIP.jar
reference.EssentialsGroupManager.jar=${project.EssentialsGroupManager}/dist/EssentialsGroupManager.jar
reference.EssentialsAntiBuild.jar=${project.EssentialsAntiBuild}/dist/EssentialsAntiBuild.jar
reference.EssentialsProtect.jar=${project.EssentialsProtect}/dist/EssentialsProtect.jar
reference.EssentialsSpawn.jar=${project.EssentialsSpawn}/dist/EssentialsSpawn.jar
reference.EssentialsXMPP.jar=${project.EssentialsXMPP}/dist/EssentialsXMPP.jar
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src
test.src.dir=test
-84
View File
@@ -1,84 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>BuildAll</name>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
<libraries xmlns="http://www.netbeans.org/ns/ant-project-libraries/1">
<definitions>..\lib\nblibraries.properties</definitions>
</libraries>
<references xmlns="http://www.netbeans.org/ns/ant-project-references/1">
<reference>
<foreign-project>Essentials</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
<reference>
<foreign-project>EssentialsChat</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
<reference>
<foreign-project>EssentialsGeoIP</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
<reference>
<foreign-project>EssentialsGroupManager</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
<reference>
<foreign-project>EssentialsAntiBuild</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
<reference>
<foreign-project>EssentialsProtect</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
<reference>
<foreign-project>EssentialsSpawn</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
<reference>
<foreign-project>EssentialsXMPP</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
</references>
</configuration>
</project>
+31
View File
@@ -0,0 +1,31 @@
Contributing to EssentialsX
===========================
Want to help improve EssentialsX? There are several ways you can support and contribute to the project.
If you'd like to make a financial contribution to the project, you can join our [Patreon](https://www.patreon.com/essentialsx/),
or to make a one-off donation you can visit our [Ko-fi page](https://ko-fi.com/essentialsx). If you can't make a
donation, don't worry! There are lots of other ways to contribute:
* Do you run a server? Take a look at our ["help wanted"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22help+wanted%22)
and ["bug: unconfirmed"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22bug%3A+unconfirmed%22)
issues, where you can find issues that need extra testing and investigation.
* Do you speak multiple languages? If so, we always welcome contributions to our [Crowdin project](https://crowdin.com/project/essentialsx-official).
* Do you enjoy helping others? If so, why not contribute to the [EssentialsX documentation](https://github.com/EssentialsX/wiki)?
You can also join the [MOSS Discord community](https://discord.gg/casfFyh) and provide direct community support to
other EssentialsX users.
* If you're a developer, you could look through our ["open to PR"](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22status%3A+open+to+PR%22)
issues. We're always happy to receive bug fixes and feature additions as pull requests.
Submitting a PR
---------------
EssentialsX has extensive templates for PRs that detail how to submit your PR. To find out more, see the PR templates for:
* [Bug fixes](https://github.com/EssentialsX/Essentials/blob/2.x/.github/PULL_REQUEST_TEMPLATE/bug-fix.md)
* [New features](https://github.com/EssentialsX/Essentials/blob/2.x/.github/PULL_REQUEST_TEMPLATE/new-feature.md)
Want to discuss a feature before opening a PR? Join the [EssentialsX Development Discord server](https://discord.gg/CUN7qVb). Note that this server is **not for end-users** - if you need support with EssentialsX, you should join [MOSS](https://discord.gg/casfFyh) instead.
By contributing to EssentialsX, you agree to license your code under the [GNU General Public License version 3](https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE).
-84
View File
@@ -1,84 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="Essentials" default="default" basedir=".">
<description>Builds, tests, and runs the project Essentials.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar-with-manifest: JAR building (if you are using a manifest)
-do-jar-without-manifest: JAR building (if you are not using a manifest)
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="Essentials-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
<!--target name="-post-jar">
<jar jarfile="${dist.dir}/Essentials.jar">
<zipfileset src="${dist.jar}" excludes="META-INF/*" />
<zipfileset src="${dist.dir}/lib/Register.jar" excludes="META-INF/*" />
<manifest>
<attribute name="Classpath" value="Essentials.jar"/>
</manifest>
</jar>
</target-->
</project>
File diff suppressed because it is too large. Load diff
-11
View File
@@ -1,11 +0,0 @@
build.xml.data.CRC32=7d758acf
build.xml.script.CRC32=3233ee78
build.xml.stylesheet.CRC32=28e38971@1.38.2.45
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=a830bc14
nbproject/build-impl.xml.script.CRC32=21ffdddf
nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46
nbproject/profiler-build-impl.xml.data.CRC32=ab78ce15
nbproject/profiler-build-impl.xml.script.CRC32=abda56ed
nbproject/profiler-build-impl.xml.stylesheet.CRC32=f10cf54c@1.11.1
-3
View File
@@ -1,3 +0,0 @@
DoNotUseThreads
LongVariable
SignatureDeclareThrowsException
-154
View File
@@ -1,154 +0,0 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=true
annotation.processing.processors.list=lombok.core.AnnotationProcessor
annotation.processing.run.all.processors=false
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=Essentials
application.vendor=
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs=true
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width=2
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab=2
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=2
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=120
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap=none
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineAnnotationArgs=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineArrayInit=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineAssignment=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineBinaryOp=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineCallArgs=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineDisjunctiveCatchTypes=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineFor=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineImplements=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineMethodParams=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineParenthesized=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineTernaryOp=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineThrows=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.alignMultilineTryResources=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.blankLinesAfterClassHeader=0
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.blankLinesBeforeClass=2
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement=NEW_LINE
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.expand-tabs=false
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.importGroupsOrder=*
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indent-shift-width=4
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indentCasesFromSwitch=false
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement=NEW_LINE
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement=NEW_LINE
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeCatchOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeElseOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeFinallyOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.placeWhileOnNewLine=true
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.separateImportGroups=false
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceAfterTypeCast=false
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaces-per-tab=4
auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.tab-size=4
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/Essentials.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
file.reference.BOSEconomy7.jar=../lib/BOSEconomy7.jar
file.reference.bPermissions.jar=../lib/bPermissions.jar
file.reference.bpermissions2.jar=../lib/bpermissions2.jar
file.reference.bukkit.jar=../lib/bukkit.jar
file.reference.iCo4.jar=../lib/iCo4.jar
file.reference.iCo5.jar=../lib/iCo5.jar
file.reference.iCo6.jar=../lib/iCo6.jar
file.reference.lombok.jar=../lib/lombok-0.10.8.jar
file.reference.MultiCurrency.jar=../lib/MultiCurrency.jar
file.reference.Permissions3.jar=../lib/Permissions3.jar
file.reference.PermissionsBukkit-1.2.jar=../lib/PermissionsBukkit-1.2.jar
file.reference.PermissionsEx.jar=../lib/PermissionsEx.jar
file.reference.Privileges.jar=..\\lib\\Privileges.jar
file.reference.Vault.jar=../lib/Vault.jar
file.reference.SimplyPerms.jar=../lib/SimplyPerms.jar
includes=**
jar.archive.disabled=${jnlp.enabled}
jar.compress=true
jar.index=${jnlp.enabled}
javac.classpath=\
${file.reference.Permissions3.jar}:\
${file.reference.iCo4.jar}:\
${file.reference.iCo5.jar}:\
${file.reference.iCo6.jar}:\
${file.reference.MultiCurrency.jar}:\
${file.reference.BOSEconomy7.jar}:\
${file.reference.PermissionsEx.jar}:\
${file.reference.bPermissions.jar}:\
${file.reference.PermissionsBukkit-1.2.jar}:\
${file.reference.lombok.jar}:\
${reference.EssentialsGroupManager.jar}:\
${file.reference.bukkit.jar}:\
${file.reference.Vault.jar}:\
${file.reference.Privileges.jar}:\
${file.reference.bpermissions2.jar}:\
${file.reference.SimplyPerms.jar}
# Space-separated list of extra javac options
javac.compilerargs=-Xlint:unchecked
javac.deprecation=false
javac.processorpath=\
${javac.classpath}
javac.source=1.6
javac.target=1.6
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${libs.junit_4.10.classpath}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.reference.PermissionsEx.jar=../lib/PermissionsEx-javadoc.jar
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
jnlp.codebase.type=no.codebase
jnlp.descriptor=application
jnlp.enabled=false
jnlp.mixed.code=default
jnlp.offline-allowed=false
jnlp.signed=false
jnlp.signing=
jnlp.signing.alias=
jnlp.signing.keystore=
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=true
platform.active=default_platform
project.EssentialsGroupManager=../EssentialsGroupManager
reference.EssentialsGroupManager.jar=../EssentialsGroupManager/dist/EssentialsGroupManager.jar
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=-Djline.terminal=jline.UnsupportedTerminal
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src
test.src.dir=test
-28
View File
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>Essentials</name>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
<libraries xmlns="http://www.netbeans.org/ns/ant-project-libraries/1">
<definitions>../lib/nblibraries.properties</definitions>
</libraries>
<references xmlns="http://www.netbeans.org/ns/ant-project-references/1">
<reference>
<foreign-project>EssentialsGroupManager</foreign-project>
<artifact-type>jar</artifact-type>
<script>build.xml</script>
<target>jar</target>
<clean-target>clean</clean-target>
<id>jar</id>
</reference>
</references>
</configuration>
</project>
+118
View File
@@ -0,0 +1,118 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.ess3</groupId>
<artifactId>EssentialsXParent</artifactId>
<version>2.18.2</version>
</parent>
<artifactId>EssentialsX</artifactId>
<build>
<finalName>EssentialsX-${full.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<showDeprecation>false</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>io.papermc.lib</pattern>
<shadedPattern>com.earth2me.essentials.paperlib</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.github.milkbowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
</exclusions>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.luckperms</groupId>
<artifactId>api</artifactId>
<version>5.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc</groupId>
<artifactId>paperlib</artifactId>
<version>1.0.6-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>BaseProviders</artifactId>
<version>2.18.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>NMSReflectionProvider</artifactId>
<version>2.18.2</version>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
</exclusions>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>PaperProvider</artifactId>
<version>2.18.2</version>
<exclusions>
<exclusion>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId>
</exclusion>
</exclusions>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.ess3</groupId>
<artifactId>1_8Provider</artifactId>
<version>2.18.2</version>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
</exclusion>
</exclusions>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
+3 -3
View File
@@ -13,6 +13,6 @@ Minecraft colors:
&8 &&8 &9 &&9 &a &&a &b &&b
&c &&c &d &&d &e &&e &f &&f
&0
&&k &kMagic&r &&l &lBold
&&m &mStrike&r &&n &nUline
&&o &oItalic&r &&r &rReset
&&k &kMagic&r &&l &lBold&r
&&m &mStrike&r &&n &nUline&r
&&o &oItalic&r &&r &rReset
@@ -1,138 +1,108 @@
package com.earth2me.essentials;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.ess3.api.IEssentials;
import org.bukkit.command.Command;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.PluginCommandYamlParser;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AlternativeCommandsHandler
{
private static final Logger LOGGER = Logger.getLogger("Minecraft");
private final transient Map<String, List<PluginCommand>> altcommands = new HashMap<String, List<PluginCommand>>();
private final transient Map<String, String> disabledList = new HashMap<String, String>();
private final transient IEssentials ess;
public class AlternativeCommandsHandler {
private static final Logger LOGGER = Logger.getLogger("Essentials");
private final transient Map<String, List<PluginCommand>> altcommands = new HashMap<>();
private final transient Map<String, String> disabledList = new HashMap<>();
private final transient IEssentials ess;
public AlternativeCommandsHandler(final IEssentials ess)
{
this.ess = ess;
for (Plugin plugin : ess.getServer().getPluginManager().getPlugins())
{
if (plugin.isEnabled())
{
addPlugin(plugin);
}
}
}
public AlternativeCommandsHandler(final IEssentials ess) {
this.ess = ess;
for (final Plugin plugin : ess.getServer().getPluginManager().getPlugins()) {
if (plugin.isEnabled()) {
addPlugin(plugin);
}
}
}
public final void addPlugin(final Plugin plugin)
{
if (plugin.getDescription().getMain().contains("com.earth2me.essentials"))
{
return;
}
final List<Command> commands = PluginCommandYamlParser.parse(plugin);
final String pluginName = plugin.getDescription().getName().toLowerCase(Locale.ENGLISH);
public final void addPlugin(final Plugin plugin) {
if (plugin.getDescription().getMain().contains("com.earth2me.essentials")) {
return;
}
final List<Command> commands = PluginCommandYamlParser.parse(plugin);
final String pluginName = plugin.getDescription().getName().toLowerCase(Locale.ENGLISH);
for (Command command : commands)
{
final PluginCommand pc = (PluginCommand)command;
final List<String> labels = new ArrayList<String>(pc.getAliases());
labels.add(pc.getName());
for (final Command command : commands) {
final PluginCommand pc = (PluginCommand) command;
final List<String> labels = new ArrayList<>(pc.getAliases());
labels.add(pc.getName());
PluginCommand reg = ess.getServer().getPluginCommand(pluginName + ":" + pc.getName().toLowerCase(Locale.ENGLISH));
if (reg == null)
{
reg = ess.getServer().getPluginCommand(pc.getName().toLowerCase(Locale.ENGLISH));
}
if (reg == null || !reg.getPlugin().equals(plugin))
{
continue;
}
for (String label : labels)
{
List<PluginCommand> plugincommands = altcommands.get(label.toLowerCase(Locale.ENGLISH));
if (plugincommands == null)
{
plugincommands = new ArrayList<PluginCommand>();
altcommands.put(label.toLowerCase(Locale.ENGLISH), plugincommands);
}
boolean found = false;
for (PluginCommand pc2 : plugincommands)
{
if (pc2.getPlugin().equals(plugin))
{
found = true;
}
}
if (!found)
{
plugincommands.add(reg);
}
}
}
}
PluginCommand reg = ess.getServer().getPluginCommand(pluginName + ":" + pc.getName().toLowerCase(Locale.ENGLISH));
if (reg == null) {
reg = ess.getServer().getPluginCommand(pc.getName().toLowerCase(Locale.ENGLISH));
}
if (reg == null || !reg.getPlugin().equals(plugin)) {
continue;
}
for (final String label : labels) {
final List<PluginCommand> plugincommands = altcommands.computeIfAbsent(label.toLowerCase(Locale.ENGLISH), k -> new ArrayList<>());
boolean found = false;
for (final PluginCommand pc2 : plugincommands) {
if (pc2.getPlugin().equals(plugin)) {
found = true;
break;
}
}
if (!found) {
plugincommands.add(reg);
}
}
}
}
public void removePlugin(final Plugin plugin)
{
final Iterator<Map.Entry<String, List<PluginCommand>>> iterator = altcommands.entrySet().iterator();
while (iterator.hasNext())
{
final Map.Entry<String, List<PluginCommand>> entry = iterator.next();
final Iterator<PluginCommand> pcIterator = entry.getValue().iterator();
while (pcIterator.hasNext())
{
final PluginCommand pc = pcIterator.next();
if (pc.getPlugin() == null || pc.getPlugin().equals(plugin))
{
pcIterator.remove();
}
}
if (entry.getValue().isEmpty())
{
iterator.remove();
}
}
}
public void removePlugin(final Plugin plugin) {
final Iterator<Map.Entry<String, List<PluginCommand>>> iterator = altcommands.entrySet().iterator();
while (iterator.hasNext()) {
final Map.Entry<String, List<PluginCommand>> entry = iterator.next();
entry.getValue().removeIf(pc -> pc.getPlugin() == null || pc.getPlugin().equals(plugin));
if (entry.getValue().isEmpty()) {
iterator.remove();
}
}
}
public PluginCommand getAlternative(final String label)
{
final List<PluginCommand> commands = altcommands.get(label);
if (commands == null || commands.isEmpty())
{
return null;
}
if (commands.size() == 1)
{
return commands.get(0);
}
// return the first command that is not an alias
for (PluginCommand command : commands)
{
if (command.getName().equalsIgnoreCase(label))
{
return command;
}
}
// return the first alias
return commands.get(0);
}
public PluginCommand getAlternative(final String label) {
final List<PluginCommand> commands = altcommands.get(label);
if (commands == null || commands.isEmpty()) {
return null;
}
if (commands.size() == 1) {
return commands.get(0);
}
// return the first command that is not an alias
for (final PluginCommand command : commands) {
if (command.getName().equalsIgnoreCase(label)) {
return command;
}
}
// return the first alias
return commands.get(0);
}
public void executed(final String label, final PluginCommand pc)
{
final String altString = pc.getPlugin().getName() + ":" + pc.getLabel();
if (ess.getSettings().isDebug())
{
LOGGER.log(Level.INFO, "Essentials: Alternative command " + label + " found, using " + altString);
}
disabledList.put(label, altString);
}
public void executed(final String label, final PluginCommand pc) {
final String altString = pc.getPlugin().getName() + ":" + pc.getLabel();
if (ess.getSettings().isDebug()) {
LOGGER.log(Level.INFO, "Essentials: Alternative command " + label + " found, using " + altString);
}
disabledList.put(label, altString);
}
public Map<String, String> disabledCommands()
{
return disabledList;
}
public Map<String, String> disabledCommands() {
return disabledList;
}
}
@@ -0,0 +1,455 @@
package com.earth2me.essentials;
import com.earth2me.essentials.api.IAsyncTeleport;
import com.earth2me.essentials.commands.WarpNotFoundException;
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.IUser;
import net.ess3.api.InvalidWorldException;
import net.ess3.api.events.UserWarpEvent;
import net.ess3.api.events.teleport.PreTeleportEvent;
import net.ess3.api.events.teleport.TeleportWarmupEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static com.earth2me.essentials.I18n.tl;
public class AsyncTeleport implements IAsyncTeleport {
private final IUser teleportOwner;
private final IEssentials ess;
private AsyncTimedTeleport timedTeleport;
private TeleportType tpType;
public AsyncTeleport(final IUser user, final IEssentials ess) {
this.teleportOwner = user;
this.ess = ess;
tpType = TeleportType.NORMAL;
}
public void cooldown(final boolean check) throws Throwable {
final CompletableFuture<Boolean> exceptionFuture = new CompletableFuture<>();
if (cooldown(check, exceptionFuture)) {
try {
exceptionFuture.get();
} catch (final ExecutionException e) {
throw e.getCause();
}
}
}
public boolean cooldown(final boolean check, final CompletableFuture<Boolean> future) {
final Calendar time = new GregorianCalendar();
if (teleportOwner.getLastTeleportTimestamp() > 0) {
// Take the current time, and remove the delay from it.
final double cooldown = ess.getSettings().getTeleportCooldown();
final Calendar earliestTime = new GregorianCalendar();
earliestTime.add(Calendar.SECOND, -(int) cooldown);
earliestTime.add(Calendar.MILLISECOND, -(int) ((cooldown * 1000.0) % 1000.0));
// This value contains the most recent time a teleportPlayer could have been used that would allow another use.
final long earliestLong = earliestTime.getTimeInMillis();
// When was the last teleportPlayer used?
final long lastTime = teleportOwner.getLastTeleportTimestamp();
if (lastTime > time.getTimeInMillis()) {
// This is to make sure time didn't get messed up on last teleportPlayer use.
// If this happens, let's give the user the benifit of the doubt.
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
return false;
} else if (lastTime > earliestLong
&& cooldownApplies()) {
time.setTimeInMillis(lastTime);
time.add(Calendar.SECOND, (int) cooldown);
time.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0));
future.completeExceptionally(new Exception(tl("timeBeforeTeleport", DateUtil.formatDateDiff(time.getTimeInMillis()))));
return true;
}
}
// if justCheck is set, don't update lastTeleport; we're just checking
if (!check) {
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
}
return false;
}
private boolean cooldownApplies() {
boolean applies = true;
final String globalBypassPerm = "essentials.teleport.cooldown.bypass";
switch (tpType) {
case NORMAL:
applies = !teleportOwner.isAuthorized(globalBypassPerm);
break;
case BACK:
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.back"));
break;
case TPA:
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.tpa"));
break;
}
return applies;
}
private void warnUser(final IUser user, final double delay) {
final Calendar c = new GregorianCalendar();
c.add(Calendar.SECOND, (int) delay);
c.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0));
user.sendMessage(tl("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis())));
}
@Override
public void now(final Location loc, final boolean cooldown, final TeleportCause cause, final CompletableFuture<Boolean> future) {
if (cooldown && cooldown(false, future)) {
return;
}
final ITarget target = new LocationTarget(loc);
nowAsync(teleportOwner, target, cause, future);
}
@Override
public void now(final Player entity, final boolean cooldown, final TeleportCause cause, final CompletableFuture<Boolean> future) {
if (cooldown && cooldown(false, future)) {
future.complete(false);
return;
}
final ITarget target = new PlayerTarget(entity);
nowAsync(teleportOwner, target, cause, future);
future.thenAccept(success -> {
if (success) {
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
}
});
}
private void runOnMain(final Runnable runnable) throws ExecutionException, InterruptedException {
if (Bukkit.isPrimaryThread()) {
runnable.run();
return;
}
final CompletableFuture<Object> taskLock = new CompletableFuture<>();
Bukkit.getScheduler().runTask(ess, () -> {
runnable.run();
taskLock.complete(new Object());
});
taskLock.get();
}
protected void nowAsync(final IUser teleportee, final ITarget target, final TeleportCause cause, final CompletableFuture<Boolean> future) {
cancel(false);
final PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
teleportee.setLastLocation();
if (!ess.getSettings().isForcePassengerTeleport() && !teleportee.getBase().isEmpty()) {
if (!ess.getSettings().isTeleportPassengerDismount()) {
future.completeExceptionally(new Exception(tl("passengerTeleportFail")));
return;
}
try {
runOnMain(() -> teleportee.getBase().eject()); //EntityDismountEvent requires a sync context.
} catch (final ExecutionException | InterruptedException e) {
future.completeExceptionally(e);
return;
}
}
teleportee.setLastLocation();
final Location targetLoc = target.getLocation();
if (ess.getSettings().isTeleportSafetyEnabled() && LocationUtil.isBlockOutsideWorldBorder(targetLoc.getWorld(), targetLoc.getBlockX(), targetLoc.getBlockZ())) {
targetLoc.setX(LocationUtil.getXInsideWorldBorder(targetLoc.getWorld(), targetLoc.getBlockX()));
targetLoc.setZ(LocationUtil.getZInsideWorldBorder(targetLoc.getWorld(), targetLoc.getBlockZ()));
}
PaperLib.getChunkAtAsync(targetLoc).thenAccept(chunk -> {
Location loc = targetLoc;
if (LocationUtil.isBlockUnsafeForUser(teleportee, chunk.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
if (ess.getSettings().isTeleportSafetyEnabled()) {
if (ess.getSettings().isForceDisableTeleportSafety()) {
//The chunk we're teleporting to is 100% going to be loaded here, no need to teleport async.
teleportee.getBase().teleport(loc, cause);
} else {
try {
//There's a chance the safer location is outside the loaded chunk so still teleport async here.
PaperLib.teleportAsync(teleportee.getBase(), LocationUtil.getSafeDestination(ess, teleportee, loc), cause);
} catch (final Exception e) {
future.completeExceptionally(e);
return;
}
}
} else {
future.completeExceptionally(new Exception(tl("unsafeTeleportDestination", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())));
return;
}
} else {
if (ess.getSettings().isForceDisableTeleportSafety()) {
//The chunk we're teleporting to is 100% going to be loaded here, no need to teleport async.
teleportee.getBase().teleport(loc, cause);
} else {
if (ess.getSettings().isTeleportToCenterLocation()) {
loc = LocationUtil.getRoundedDestination(loc);
}
//There's a *small* chance the rounded destination produces a location outside the loaded chunk so still teleport async here.
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
}
}
future.complete(true);
});
}
@Override
public void teleport(final Location loc, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
teleport(teleportOwner, new LocationTarget(loc), chargeFor, cause, future);
}
@Override
public void teleport(final Player entity, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
teleportOwner.sendMessage(tl("teleportToPlayer", entity.getDisplayName()));
teleport(teleportOwner, new PlayerTarget(entity), chargeFor, cause, future);
}
@Override
public void teleportPlayer(final IUser otherUser, final Location loc, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
teleport(otherUser, new LocationTarget(loc), chargeFor, cause, future);
}
@Override
public void teleportPlayer(final IUser otherUser, final Player entity, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
final ITarget target = new PlayerTarget(entity);
teleport(otherUser, target, chargeFor, cause, future);
future.thenAccept(success -> {
if (success) {
otherUser.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
}
});
}
private void teleport(final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
double delay = ess.getSettings().getTeleportDelay();
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
delay = event.getDelay();
Trade cashCharge = chargeFor;
if (chargeFor != null) {
chargeFor.isAffordableFor(teleportOwner, future);
if (future.isCompletedExceptionally()) {
return;
}
//This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world.
if (!chargeFor.getCommandCost(teleportOwner).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(teleportOwner), ess);
}
}
if (cooldown(true, future)) {
return;
}
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass") || teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
if (cooldown(false, future)) {
return;
}
nowAsync(teleportee, target, cause, future);
if (cashCharge != null) {
cashCharge.charge(teleportOwner, future);
if (future.isCompletedExceptionally()) {
return;
}
}
return;
}
cancel(false);
warnUser(teleportee, delay);
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
}
private void teleportOther(final IUser teleporter, final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
double delay = ess.getSettings().getTeleportDelay();
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
delay = event.getDelay();
Trade cashCharge = chargeFor;
if (teleporter != null && chargeFor != null) {
chargeFor.isAffordableFor(teleporter, future);
if (future.isCompletedExceptionally()) {
return;
}
//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);
}
}
if (cooldown(true, future)) {
return;
}
if (delay <= 0 || teleporter == null
|| teleporter.isAuthorized("essentials.teleport.timer.bypass")
|| teleportOwner.isAuthorized("essentials.teleport.timer.bypass")
|| teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
if (cooldown(false, future)) {
return;
}
nowAsync(teleportee, target, cause, future);
if (teleporter != null && cashCharge != null) {
cashCharge.charge(teleporter, future);
if (future.isCompletedExceptionally()) {
return;
}
}
return;
}
cancel(false);
warnUser(teleportee, delay);
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
}
@Override
public void respawn(final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
double delay = ess.getSettings().getTeleportDelay();
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
delay = event.getDelay();
if (chargeFor != null) {
chargeFor.isAffordableFor(teleportOwner, future);
if (future.isCompletedExceptionally()) {
return;
}
}
if (cooldown(true, future)) {
return;
}
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass")) {
if (cooldown(false, future)) {
return;
}
respawnNow(teleportOwner, cause, future);
if (chargeFor != null) {
chargeFor.charge(teleportOwner, future);
}
return;
}
cancel(false);
warnUser(teleportOwner, delay);
initTimer((long) (delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
}
void respawnNow(final IUser teleportee, final TeleportCause cause, final CompletableFuture<Boolean> future) {
final Player player = teleportee.getBase();
PaperLib.getBedSpawnLocationAsync(player, true).thenAccept(location -> {
if (location != null) {
nowAsync(teleportee, new LocationTarget(location), cause, future);
} else {
if (ess.getSettings().isDebug()) {
ess.getLogger().info("Could not find bed spawn, forcing respawn event.");
}
final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, player.getWorld().getSpawnLocation(), false);
ess.getServer().getPluginManager().callEvent(pre);
nowAsync(teleportee, new LocationTarget(pre.getRespawnLocation()), cause, future);
}
});
}
@Override
public void warp(final IUser otherUser, String warp, final Trade chargeFor, final TeleportCause cause, final CompletableFuture<Boolean> future) {
final UserWarpEvent event = new UserWarpEvent(otherUser, warp, chargeFor);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
warp = event.getWarp();
final Location loc;
try {
loc = ess.getWarps().getWarp(warp);
} catch (final WarpNotFoundException | InvalidWorldException e) {
future.completeExceptionally(e);
return;
}
otherUser.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
if (!otherUser.equals(teleportOwner)) {
teleportOwner.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
}
teleport(otherUser, new LocationTarget(loc), chargeFor, cause, future);
}
@Override
public void back(final Trade chargeFor, final CompletableFuture<Boolean> future) {
back(teleportOwner, chargeFor, future);
}
@Override
public void back(final IUser teleporter, final Trade chargeFor, final CompletableFuture<Boolean> future) {
tpType = TeleportType.BACK;
final Location loc = teleportOwner.getLastLocation();
teleportOwner.sendMessage(tl("backUsageMsg", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
teleportOther(teleporter, teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND, future);
}
@Override
public void back(final CompletableFuture<Boolean> future) {
nowAsync(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND, future);
}
public void setTpType(final TeleportType tpType) {
this.tpType = tpType;
}
//If we need to cancelTimer a pending teleportPlayer call this method
private void cancel(final boolean notifyUser) {
if (timedTeleport != null) {
timedTeleport.cancelTimer(notifyUser);
timedTeleport = null;
}
}
private void initTimer(final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
timedTeleport = new AsyncTimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn);
}
public enum TeleportType {
TPA,
BACK,
NORMAL
}
}
@@ -0,0 +1,151 @@
package com.earth2me.essentials;
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import org.bukkit.Location;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import static com.earth2me.essentials.I18n.tl;
public class AsyncTimedTeleport implements Runnable {
private static final double MOVE_CONSTANT = 0.3;
private final IUser teleportOwner;
private final IEssentials ess;
private final AsyncTeleport teleport;
private final UUID timer_teleportee;
private final long timer_started; // time this task was initiated
private final long timer_delay; // how long to delay the teleportPlayer
// note that I initially stored a clone of the location for reference, but...
// when comparing locations, I got incorrect mismatches (rounding errors, looked like)
// so, the X/Y/Z values are stored instead and rounded off
private final long timer_initX;
private final long timer_initY;
private final long timer_initZ;
private final ITarget timer_teleportTarget;
private final boolean timer_respawn;
private final boolean timer_canMove;
private final Trade timer_chargeFor;
private final TeleportCause timer_cause;
private int timer_task;
private double timer_health;
AsyncTimedTeleport(final IUser user, final IEssentials ess, final AsyncTeleport teleport, final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
this.teleportOwner = user;
this.ess = ess;
this.teleport = teleport;
this.timer_started = System.currentTimeMillis();
this.timer_delay = delay;
this.timer_health = teleportUser.getBase().getHealth();
this.timer_initX = Math.round(teleportUser.getBase().getLocation().getX() * MOVE_CONSTANT);
this.timer_initY = Math.round(teleportUser.getBase().getLocation().getY() * MOVE_CONSTANT);
this.timer_initZ = Math.round(teleportUser.getBase().getLocation().getZ() * MOVE_CONSTANT);
this.timer_teleportee = teleportUser.getBase().getUniqueId();
this.timer_teleportTarget = target;
this.timer_chargeFor = chargeFor;
this.timer_cause = cause;
this.timer_respawn = respawn;
this.timer_canMove = user.isAuthorized("essentials.teleport.timer.move");
timer_task = ess.runTaskTimerAsynchronously(this, 20, 20).getTaskId();
}
@Override
public void run() {
if (teleportOwner == null || !teleportOwner.getBase().isOnline() || teleportOwner.getBase().getLocation() == null) {
cancelTimer(false);
return;
}
final IUser teleportUser = ess.getUser(this.timer_teleportee);
if (teleportUser == null || !teleportUser.getBase().isOnline()) {
cancelTimer(false);
return;
}
final Location currLocation = teleportUser.getBase().getLocation();
if (currLocation == null) {
cancelTimer(false);
return;
}
if (!timer_canMove && (Math.round(currLocation.getX() * MOVE_CONSTANT) != timer_initX || Math.round(currLocation.getY() * MOVE_CONSTANT) != timer_initY || Math.round(currLocation.getZ() * MOVE_CONSTANT) != timer_initZ || teleportUser.getBase().getHealth() < timer_health)) {
// user moved, cancelTimer teleportPlayer
cancelTimer(true);
return;
}
class DelayedTeleportTask implements Runnable {
@Override
public void run() {
timer_health = teleportUser.getBase().getHealth(); // in case user healed, then later gets injured
final long now = System.currentTimeMillis();
if (now > timer_started + timer_delay) {
try {
teleport.cooldown(false);
} catch (final Throwable ex) {
teleportOwner.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
if (teleportOwner != teleportUser) {
teleportUser.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
}
}
try {
cancelTimer(false);
teleportUser.sendMessage(tl("teleportationCommencing"));
final CompletableFuture<Boolean> future = new CompletableFuture<>();
future.exceptionally(e -> {
ess.showError(teleportOwner.getSource(), e, "\\ teleport");
return false;
});
if (timer_chargeFor != null) {
timer_chargeFor.isAffordableFor(teleportOwner);
}
if (timer_respawn) {
teleport.respawnNow(teleportUser, timer_cause, future);
} else {
teleport.nowAsync(teleportUser, timer_teleportTarget, timer_cause, future);
}
future.thenAccept(success -> {
if (timer_chargeFor != null) {
try {
timer_chargeFor.charge(teleportOwner);
} catch (final ChargeException ex) {
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
}
}
});
} catch (final Exception ex) {
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
}
}
}
}
ess.scheduleSyncDelayedTask(new DelayedTeleportTask());
}
//If we need to cancelTimer a pending teleportPlayer call this method
void cancelTimer(final boolean notifyUser) {
if (timer_task == -1) {
return;
}
try {
ess.getServer().getScheduler().cancelTask(timer_task);
if (notifyUser) {
teleportOwner.sendMessage(tl("pendingTeleportCancelled"));
if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getBase().getUniqueId())) {
ess.getUser(timer_teleportee).sendMessage(tl("pendingTeleportCancelled"));
}
}
} finally {
timer_task = -1;
}
}
}
+120 -141
View File
@@ -1,154 +1,133 @@
package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.ess3.api.IEssentials;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Backup implements Runnable
{
private static final Logger LOGGER = Logger.getLogger("Minecraft");
private transient final Server server;
private transient final IEssentials ess;
private transient boolean running = false;
private transient int taskId = -1;
private transient boolean active = false;
import static com.earth2me.essentials.I18n.tl;
public Backup(final IEssentials ess)
{
this.ess = ess;
server = ess.getServer();
if (server.getOnlinePlayers().length > 0)
{
ess.runTaskAsynchronously(new Runnable()
{
@Override
public void run()
{
startTask();
}
});
}
}
public class Backup implements Runnable {
private static final Logger LOGGER = Logger.getLogger("Essentials");
private transient final Server server;
private transient final IEssentials ess;
private final AtomicBoolean pendingShutdown = new AtomicBoolean(false);
private transient boolean running = false;
private transient int taskId = -1;
private transient boolean active = false;
private transient CompletableFuture<Object> taskLock = null;
public void onPlayerJoin()
{
startTask();
}
public Backup(final IEssentials ess) {
this.ess = ess;
server = ess.getServer();
if (!ess.getOnlinePlayers().isEmpty() || ess.getSettings().isAlwaysRunBackup()) {
ess.runTaskAsynchronously(this::startTask);
}
}
public synchronized void stopTask()
{
running = false;
if (taskId != -1)
{
server.getScheduler().cancelTask(taskId);
}
taskId = -1;
}
public void onPlayerJoin() {
startTask();
}
private synchronized void startTask()
{
if (!running)
{
final long interval = ess.getSettings().getBackupInterval() * 1200; // minutes -> ticks
if (interval < 1200)
{
return;
}
taskId = ess.scheduleSyncRepeatingTask(this, interval, interval);
running = true;
}
}
public synchronized void stopTask() {
running = false;
if (taskId != -1) {
server.getScheduler().cancelTask(taskId);
}
taskId = -1;
}
@Override
public void run()
{
if (active)
{
return;
}
active = true;
final String command = ess.getSettings().getBackupCommand();
if (command == null || "".equals(command))
{
return;
}
if ("save-all".equalsIgnoreCase(command))
{
final CommandSender cs = server.getConsoleSender();
server.dispatchCommand(cs, "save-all");
active = false;
return;
}
LOGGER.log(Level.INFO, _("backupStarted"));
final CommandSender cs = server.getConsoleSender();
server.dispatchCommand(cs, "save-all");
server.dispatchCommand(cs, "save-off");
private synchronized void startTask() {
if (!running) {
final long interval = ess.getSettings().getBackupInterval() * 1200; // minutes -> ticks
if (interval < 1200) {
return;
}
taskId = ess.scheduleSyncRepeatingTask(this, interval, interval);
running = true;
}
}
ess.runTaskAsynchronously(
new Runnable()
{
@Override
public void run()
{
try
{
final ProcessBuilder childBuilder = new ProcessBuilder(command);
childBuilder.redirectErrorStream(true);
childBuilder.directory(ess.getDataFolder().getParentFile().getParentFile());
final Process child = childBuilder.start();
final BufferedReader reader = new BufferedReader(new InputStreamReader(child.getInputStream()));
try
{
child.waitFor();
String line;
do
{
line = reader.readLine();
if (line != null)
{
LOGGER.log(Level.INFO, line);
}
}
while (line != null);
}
finally
{
reader.close();
}
}
catch (InterruptedException ex)
{
LOGGER.log(Level.SEVERE, null, ex);
}
catch (IOException ex)
{
LOGGER.log(Level.SEVERE, null, ex);
}
finally
{
ess.scheduleSyncDelayedTask(
new Runnable()
{
@Override
public void run()
{
server.dispatchCommand(cs, "save-on");
if (server.getOnlinePlayers().length == 0)
{
stopTask();
}
active = false;
LOGGER.log(Level.INFO, _("backupFinished"));
}
});
}
}
});
}
public CompletableFuture<Object> getTaskLock() {
return taskLock;
}
public void setPendingShutdown(final boolean shutdown) {
pendingShutdown.set(shutdown);
}
@Override
public void run() {
if (active) {
return;
}
final String command = ess.getSettings().getBackupCommand();
if (command == null || "".equals(command)) {
return;
}
active = true;
taskLock = new CompletableFuture<>();
if ("save-all".equalsIgnoreCase(command)) {
final CommandSender cs = server.getConsoleSender();
server.dispatchCommand(cs, "save-all");
active = false;
taskLock.complete(new Object());
return;
}
LOGGER.log(Level.INFO, tl("backupStarted"));
final CommandSender cs = server.getConsoleSender();
server.dispatchCommand(cs, "save-all");
server.dispatchCommand(cs, "save-off");
ess.runTaskAsynchronously(() -> {
try {
final ProcessBuilder childBuilder = new ProcessBuilder(command.split(" "));
childBuilder.redirectErrorStream(true);
childBuilder.directory(ess.getDataFolder().getParentFile().getParentFile());
final Process child = childBuilder.start();
ess.runTaskAsynchronously(() -> {
try {
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(child.getInputStream()))) {
String line;
do {
line = reader.readLine();
if (line != null) {
LOGGER.log(Level.INFO, line);
}
} while (line != null);
}
} catch (final IOException ex) {
LOGGER.log(Level.SEVERE, null, ex);
}
});
child.waitFor();
} catch (final InterruptedException | IOException ex) {
LOGGER.log(Level.SEVERE, null, ex);
} finally {
class BackupEnableSaveTask implements Runnable {
@Override
public void run() {
server.dispatchCommand(cs, "save-on");
if (!ess.getSettings().isAlwaysRunBackup() && ess.getOnlinePlayers().isEmpty()) {
stopTask();
}
active = false;
taskLock.complete(new Object());
LOGGER.log(Level.INFO, tl("backupFinished"));
}
}
if (!pendingShutdown.get()) {
ess.scheduleSyncDelayedTask(new BackupEnableSaveTask());
}
}
});
}
}
@@ -1,15 +1,11 @@
package com.earth2me.essentials;
public class ChargeException extends Exception {
public ChargeException(final String message) {
super(message);
}
public class ChargeException extends Exception
{
public ChargeException(final String message)
{
super(message);
}
public ChargeException(final String message, final Throwable throwable)
{
super(message, throwable);
}
public ChargeException(final String message, final Throwable throwable) {
super(message, throwable);
}
}
@@ -0,0 +1,56 @@
package com.earth2me.essentials;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class CommandSource {
protected CommandSender sender;
public CommandSource(final CommandSender base) {
this.sender = base;
}
public final CommandSender getSender() {
return sender;
}
public final Player getPlayer() {
if (sender instanceof Player) {
return (Player) sender;
}
return null;
}
public final net.ess3.api.IUser getUser(final IEssentials ess) {
if (sender instanceof Player) {
return ess.getUser((Player) sender);
}
return null;
}
public final boolean isPlayer() {
return sender instanceof Player;
}
public final CommandSender setSender(final CommandSender base) {
return this.sender = base;
}
public void sendMessage(final String message) {
if (!message.isEmpty()) {
sender.sendMessage(message);
}
}
public boolean isAuthorized(final String permission, final IEssentials ess) {
return !(sender instanceof Player) || getUser(ess).isAuthorized(permission);
}
public String getSelfSelector() {
return sender instanceof Player ? getPlayer().getName() : "*";
}
public String getDisplayName() {
return sender instanceof Player ? getPlayer().getDisplayName() : getSender().getName();
}
}
@@ -1,38 +1,89 @@
package com.earth2me.essentials;
import com.earth2me.essentials.messaging.IMessageRecipient;
import com.earth2me.essentials.messaging.SimpleMessageRecipient;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public final class Console implements IMessageRecipient {
public static final String NAME = "Console";
private static Console instance; // Set in essentials
public final class Console implements IReplyTo
{
private static Console instance = new Console();
private CommandSender replyTo;
public final static String NAME = "Console";
private final IEssentials ess;
private final IMessageRecipient messageRecipient;
private Console()
{
}
private Console(final IEssentials ess) {
this.ess = ess;
this.messageRecipient = new SimpleMessageRecipient(ess, this);
}
public static CommandSender getCommandSender(Server server) throws Exception
{
return server.getConsoleSender();
}
public static Console getInstance() {
return instance;
}
@Override
public void setReplyTo(CommandSender user)
{
replyTo = user;
}
static void setInstance(final IEssentials ess) { // Called in Essentials#onEnable()
instance = new Console(ess);
}
@Override
public CommandSender getReplyTo()
{
return replyTo;
}
/**
* @deprecated Use {@link Console#getCommandSender()}
*/
@Deprecated
public static CommandSender getCommandSender(final Server server) throws Exception {
return server.getConsoleSender();
}
public static Console getConsoleReplyTo()
{
return instance;
}
public CommandSender getCommandSender() {
return ess.getServer().getConsoleSender();
}
@Override
public String getName() {
return Console.NAME;
}
@Override
public String getDisplayName() {
return Console.NAME;
}
@Override
public void sendMessage(final String message) {
getCommandSender().sendMessage(message);
}
@Override
public boolean isReachable() {
return true;
}
/* ================================
* >> DELEGATE METHODS
* ================================ */
@Override
public MessageResponse sendMessage(final IMessageRecipient recipient, final String message) {
return this.messageRecipient.sendMessage(recipient, message);
}
@Override
public MessageResponse onReceiveMessage(final IMessageRecipient sender, final String message) {
return this.messageRecipient.onReceiveMessage(sender, message);
}
@Override
public IMessageRecipient getReplyRecipient() {
return this.messageRecipient.getReplyRecipient();
}
@Override
public void setReplyRecipient(final IMessageRecipient recipient) {
this.messageRecipient.setReplyRecipient(recipient);
}
@Override
public boolean isHiddenFrom(Player player) {
return false;
}
}
@@ -1,166 +1,304 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.enchantments.Enchantment;
public final class Enchantments {
private static final Map<String, Enchantment> ENCHANTMENTS = new HashMap<>();
private static final Map<String, Enchantment> ALIASENCHANTMENTS = new HashMap<>();
private static boolean isFlat;
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>();
static {
ENCHANTMENTS.put("alldamage", Enchantment.DAMAGE_ALL);
ALIASENCHANTMENTS.put("alldmg", Enchantment.DAMAGE_ALL);
ENCHANTMENTS.put("sharpness", Enchantment.DAMAGE_ALL);
ALIASENCHANTMENTS.put("sharp", Enchantment.DAMAGE_ALL);
ALIASENCHANTMENTS.put("dal", Enchantment.DAMAGE_ALL);
static
{
ENCHANTMENTS.put("alldamage", Enchantment.DAMAGE_ALL);
ALIASENCHANTMENTS.put("alldmg", Enchantment.DAMAGE_ALL);
ENCHANTMENTS.put("sharpness", Enchantment.DAMAGE_ALL);
ALIASENCHANTMENTS.put("sharp", Enchantment.DAMAGE_ALL);
ALIASENCHANTMENTS.put("dal", Enchantment.DAMAGE_ALL);
ENCHANTMENTS.put("ardmg", Enchantment.DAMAGE_ARTHROPODS);
ENCHANTMENTS.put("baneofarthropods", Enchantment.DAMAGE_ARTHROPODS);
ALIASENCHANTMENTS.put("baneofarthropod", Enchantment.DAMAGE_ARTHROPODS);
ALIASENCHANTMENTS.put("arthropod", Enchantment.DAMAGE_ARTHROPODS);
ALIASENCHANTMENTS.put("dar", Enchantment.DAMAGE_ARTHROPODS);
ENCHANTMENTS.put("ardmg", Enchantment.DAMAGE_ARTHROPODS);
ENCHANTMENTS.put("baneofarthropods", Enchantment.DAMAGE_ARTHROPODS);
ALIASENCHANTMENTS.put("baneofarthropod", Enchantment.DAMAGE_ARTHROPODS);
ALIASENCHANTMENTS.put("arthropod", Enchantment.DAMAGE_ARTHROPODS);
ALIASENCHANTMENTS.put("dar", Enchantment.DAMAGE_ARTHROPODS);
ENCHANTMENTS.put("undeaddamage", Enchantment.DAMAGE_UNDEAD);
ENCHANTMENTS.put("smite", Enchantment.DAMAGE_UNDEAD);
ALIASENCHANTMENTS.put("du", Enchantment.DAMAGE_UNDEAD);
ENCHANTMENTS.put("undeaddamage", Enchantment.DAMAGE_UNDEAD);
ENCHANTMENTS.put("smite", Enchantment.DAMAGE_UNDEAD);
ALIASENCHANTMENTS.put("du", Enchantment.DAMAGE_UNDEAD);
ENCHANTMENTS.put("digspeed", Enchantment.DIG_SPEED);
ENCHANTMENTS.put("efficiency", Enchantment.DIG_SPEED);
ALIASENCHANTMENTS.put("minespeed", Enchantment.DIG_SPEED);
ALIASENCHANTMENTS.put("cutspeed", Enchantment.DIG_SPEED);
ALIASENCHANTMENTS.put("ds", Enchantment.DIG_SPEED);
ALIASENCHANTMENTS.put("eff", Enchantment.DIG_SPEED);
ENCHANTMENTS.put("digspeed", Enchantment.DIG_SPEED);
ENCHANTMENTS.put("efficiency", Enchantment.DIG_SPEED);
ALIASENCHANTMENTS.put("minespeed", Enchantment.DIG_SPEED);
ALIASENCHANTMENTS.put("cutspeed", Enchantment.DIG_SPEED);
ALIASENCHANTMENTS.put("ds", Enchantment.DIG_SPEED);
ALIASENCHANTMENTS.put("eff", Enchantment.DIG_SPEED);
ENCHANTMENTS.put("durability", Enchantment.DURABILITY);
ALIASENCHANTMENTS.put("dura", Enchantment.DURABILITY);
ENCHANTMENTS.put("unbreaking", Enchantment.DURABILITY);
ALIASENCHANTMENTS.put("d", Enchantment.DURABILITY);
ENCHANTMENTS.put("durability", Enchantment.DURABILITY);
ALIASENCHANTMENTS.put("dura", Enchantment.DURABILITY);
ENCHANTMENTS.put("unbreaking", Enchantment.DURABILITY);
ALIASENCHANTMENTS.put("d", Enchantment.DURABILITY);
ENCHANTMENTS.put("thorns", Enchantment.THORNS);
ENCHANTMENTS.put("highcrit", Enchantment.THORNS);
ALIASENCHANTMENTS.put("thorn", Enchantment.THORNS);
ALIASENCHANTMENTS.put("highercrit", Enchantment.THORNS);
ALIASENCHANTMENTS.put("t", Enchantment.THORNS);
ENCHANTMENTS.put("thorns", Enchantment.THORNS);
ENCHANTMENTS.put("highcrit", Enchantment.THORNS);
ALIASENCHANTMENTS.put("thorn", Enchantment.THORNS);
ALIASENCHANTMENTS.put("highercrit", Enchantment.THORNS);
ALIASENCHANTMENTS.put("t", Enchantment.THORNS);
ENCHANTMENTS.put("fireaspect", Enchantment.FIRE_ASPECT);
ENCHANTMENTS.put("fire", Enchantment.FIRE_ASPECT);
ALIASENCHANTMENTS.put("meleefire", Enchantment.FIRE_ASPECT);
ALIASENCHANTMENTS.put("meleeflame", Enchantment.FIRE_ASPECT);
ALIASENCHANTMENTS.put("fa", Enchantment.FIRE_ASPECT);
ENCHANTMENTS.put("fireaspect", Enchantment.FIRE_ASPECT);
ENCHANTMENTS.put("fire", Enchantment.FIRE_ASPECT);
ALIASENCHANTMENTS.put("meleefire", Enchantment.FIRE_ASPECT);
ALIASENCHANTMENTS.put("meleeflame", Enchantment.FIRE_ASPECT);
ALIASENCHANTMENTS.put("fa", Enchantment.FIRE_ASPECT);
ENCHANTMENTS.put("knockback", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("kback", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("kb", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("k", Enchantment.KNOCKBACK);
ENCHANTMENTS.put("knockback", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("kback", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("kb", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("k", Enchantment.KNOCKBACK);
ALIASENCHANTMENTS.put("blockslootbonus", Enchantment.LOOT_BONUS_BLOCKS);
ENCHANTMENTS.put("fortune", Enchantment.LOOT_BONUS_BLOCKS);
ALIASENCHANTMENTS.put("fort", Enchantment.LOOT_BONUS_BLOCKS);
ALIASENCHANTMENTS.put("lbb", Enchantment.LOOT_BONUS_BLOCKS);
ALIASENCHANTMENTS.put("blockslootbonus", Enchantment.LOOT_BONUS_BLOCKS);
ENCHANTMENTS.put("fortune", Enchantment.LOOT_BONUS_BLOCKS);
ALIASENCHANTMENTS.put("fort", Enchantment.LOOT_BONUS_BLOCKS);
ALIASENCHANTMENTS.put("lbb", Enchantment.LOOT_BONUS_BLOCKS);
ALIASENCHANTMENTS.put("mobslootbonus", Enchantment.LOOT_BONUS_MOBS);
ENCHANTMENTS.put("mobloot", Enchantment.LOOT_BONUS_MOBS);
ENCHANTMENTS.put("looting", Enchantment.LOOT_BONUS_MOBS);
ALIASENCHANTMENTS.put("lbm", Enchantment.LOOT_BONUS_MOBS);
ALIASENCHANTMENTS.put("mobslootbonus", Enchantment.LOOT_BONUS_MOBS);
ENCHANTMENTS.put("mobloot", Enchantment.LOOT_BONUS_MOBS);
ENCHANTMENTS.put("looting", Enchantment.LOOT_BONUS_MOBS);
ALIASENCHANTMENTS.put("lbm", Enchantment.LOOT_BONUS_MOBS);
ALIASENCHANTMENTS.put("oxygen", Enchantment.OXYGEN);
ENCHANTMENTS.put("respiration", Enchantment.OXYGEN);
ALIASENCHANTMENTS.put("breathing", Enchantment.OXYGEN);
ENCHANTMENTS.put("breath", Enchantment.OXYGEN);
ALIASENCHANTMENTS.put("o", Enchantment.OXYGEN);
ALIASENCHANTMENTS.put("oxygen", Enchantment.OXYGEN);
ENCHANTMENTS.put("respiration", Enchantment.OXYGEN);
ALIASENCHANTMENTS.put("breathing", Enchantment.OXYGEN);
ENCHANTMENTS.put("breath", Enchantment.OXYGEN);
ALIASENCHANTMENTS.put("o", Enchantment.OXYGEN);
ENCHANTMENTS.put("protection", Enchantment.PROTECTION_ENVIRONMENTAL);
ALIASENCHANTMENTS.put("prot", Enchantment.PROTECTION_ENVIRONMENTAL);
ENCHANTMENTS.put("protect", Enchantment.PROTECTION_ENVIRONMENTAL);
ALIASENCHANTMENTS.put("p", Enchantment.PROTECTION_ENVIRONMENTAL);
ENCHANTMENTS.put("protection", Enchantment.PROTECTION_ENVIRONMENTAL);
ALIASENCHANTMENTS.put("prot", Enchantment.PROTECTION_ENVIRONMENTAL);
ENCHANTMENTS.put("protect", Enchantment.PROTECTION_ENVIRONMENTAL);
ALIASENCHANTMENTS.put("p", Enchantment.PROTECTION_ENVIRONMENTAL);
ALIASENCHANTMENTS.put("explosionsprotection", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("explosionprotection", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("expprot", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("blastprotection", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("bprotection", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("bprotect", Enchantment.PROTECTION_EXPLOSIONS);
ENCHANTMENTS.put("blastprotect", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("pe", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("explosionsprotection", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("explosionprotection", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("expprot", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("blastprotection", Enchantment.PROTECTION_EXPLOSIONS);
ENCHANTMENTS.put("blastprotect", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("pe", Enchantment.PROTECTION_EXPLOSIONS);
ALIASENCHANTMENTS.put("fallprotection", Enchantment.PROTECTION_FALL);
ENCHANTMENTS.put("fallprot", Enchantment.PROTECTION_FALL);
ENCHANTMENTS.put("featherfall", Enchantment.PROTECTION_FALL);
ALIASENCHANTMENTS.put("featherfalling", Enchantment.PROTECTION_FALL);
ALIASENCHANTMENTS.put("pfa", Enchantment.PROTECTION_FALL);
ALIASENCHANTMENTS.put("fallprotection", Enchantment.PROTECTION_FALL);
ENCHANTMENTS.put("fallprot", Enchantment.PROTECTION_FALL);
ENCHANTMENTS.put("featherfall", Enchantment.PROTECTION_FALL);
ALIASENCHANTMENTS.put("featherfalling", Enchantment.PROTECTION_FALL);
ALIASENCHANTMENTS.put("pfa", Enchantment.PROTECTION_FALL);
ALIASENCHANTMENTS.put("fireprotection", Enchantment.PROTECTION_FIRE);
ALIASENCHANTMENTS.put("flameprotection", Enchantment.PROTECTION_FIRE);
ENCHANTMENTS.put("fireprotect", Enchantment.PROTECTION_FIRE);
ALIASENCHANTMENTS.put("flameprotect", Enchantment.PROTECTION_FIRE);
ENCHANTMENTS.put("fireprot", Enchantment.PROTECTION_FIRE);
ALIASENCHANTMENTS.put("flameprot", Enchantment.PROTECTION_FIRE);
ALIASENCHANTMENTS.put("pf", Enchantment.PROTECTION_FIRE);
ALIASENCHANTMENTS.put("fireprotection", Enchantment.PROTECTION_FIRE);
ALIASENCHANTMENTS.put("flameprotection", Enchantment.PROTECTION_FIRE);
ENCHANTMENTS.put("fireprotect", Enchantment.PROTECTION_FIRE);
ALIASENCHANTMENTS.put("flameprotect", Enchantment.PROTECTION_FIRE);
ENCHANTMENTS.put("fireprot", Enchantment.PROTECTION_FIRE);
ALIASENCHANTMENTS.put("flameprot", Enchantment.PROTECTION_FIRE);
ALIASENCHANTMENTS.put("pf", Enchantment.PROTECTION_FIRE);
ENCHANTMENTS.put("projectileprotection", Enchantment.PROTECTION_PROJECTILE);
ENCHANTMENTS.put("projprot", Enchantment.PROTECTION_PROJECTILE);
ALIASENCHANTMENTS.put("pp", Enchantment.PROTECTION_PROJECTILE);
ENCHANTMENTS.put("projectileprotection", Enchantment.PROTECTION_PROJECTILE);
ENCHANTMENTS.put("projprot", Enchantment.PROTECTION_PROJECTILE);
ALIASENCHANTMENTS.put("pp", Enchantment.PROTECTION_PROJECTILE);
ENCHANTMENTS.put("silktouch", Enchantment.SILK_TOUCH);
ALIASENCHANTMENTS.put("softtouch", Enchantment.SILK_TOUCH);
ALIASENCHANTMENTS.put("st", Enchantment.SILK_TOUCH);
ENCHANTMENTS.put("silktouch", Enchantment.SILK_TOUCH);
ALIASENCHANTMENTS.put("softtouch", Enchantment.SILK_TOUCH);
ALIASENCHANTMENTS.put("st", Enchantment.SILK_TOUCH);
ENCHANTMENTS.put("waterworker", Enchantment.WATER_WORKER);
ENCHANTMENTS.put("aquaaffinity", Enchantment.WATER_WORKER);
ALIASENCHANTMENTS.put("watermine", Enchantment.WATER_WORKER);
ALIASENCHANTMENTS.put("ww", Enchantment.WATER_WORKER);
ENCHANTMENTS.put("waterworker", Enchantment.WATER_WORKER);
ENCHANTMENTS.put("aquaaffinity", Enchantment.WATER_WORKER);
ALIASENCHANTMENTS.put("watermine", Enchantment.WATER_WORKER);
ALIASENCHANTMENTS.put("ww", Enchantment.WATER_WORKER);
ALIASENCHANTMENTS.put("firearrow", Enchantment.ARROW_FIRE);
ENCHANTMENTS.put("flame", Enchantment.ARROW_FIRE);
ENCHANTMENTS.put("flamearrow", Enchantment.ARROW_FIRE);
ALIASENCHANTMENTS.put("af", Enchantment.ARROW_FIRE);
ALIASENCHANTMENTS.put("firearrow", Enchantment.ARROW_FIRE);
ENCHANTMENTS.put("flame", Enchantment.ARROW_FIRE);
ENCHANTMENTS.put("flamearrow", Enchantment.ARROW_FIRE);
ALIASENCHANTMENTS.put("af", Enchantment.ARROW_FIRE);
ENCHANTMENTS.put("arrowdamage", Enchantment.ARROW_DAMAGE);
ENCHANTMENTS.put("power", Enchantment.ARROW_DAMAGE);
ALIASENCHANTMENTS.put("arrowpower", Enchantment.ARROW_DAMAGE);
ALIASENCHANTMENTS.put("ad", Enchantment.ARROW_DAMAGE);
ENCHANTMENTS.put("arrowdamage", Enchantment.ARROW_DAMAGE);
ENCHANTMENTS.put("power", Enchantment.ARROW_DAMAGE);
ALIASENCHANTMENTS.put("arrowpower", Enchantment.ARROW_DAMAGE);
ALIASENCHANTMENTS.put("ad", Enchantment.ARROW_DAMAGE);
ENCHANTMENTS.put("arrowknockback", Enchantment.ARROW_KNOCKBACK);
ALIASENCHANTMENTS.put("arrowkb", Enchantment.ARROW_KNOCKBACK);
ENCHANTMENTS.put("punch", Enchantment.ARROW_KNOCKBACK);
ALIASENCHANTMENTS.put("arrowpunch", Enchantment.ARROW_KNOCKBACK);
ALIASENCHANTMENTS.put("ak", Enchantment.ARROW_KNOCKBACK);
ENCHANTMENTS.put("arrowknockback", Enchantment.ARROW_KNOCKBACK);
ALIASENCHANTMENTS.put("arrowkb", Enchantment.ARROW_KNOCKBACK);
ENCHANTMENTS.put("punch", Enchantment.ARROW_KNOCKBACK);
ALIASENCHANTMENTS.put("arrowpunch", Enchantment.ARROW_KNOCKBACK);
ALIASENCHANTMENTS.put("ak", Enchantment.ARROW_KNOCKBACK);
ALIASENCHANTMENTS.put("infinitearrows", Enchantment.ARROW_INFINITE);
ENCHANTMENTS.put("infarrows", Enchantment.ARROW_INFINITE);
ENCHANTMENTS.put("infinity", Enchantment.ARROW_INFINITE);
ALIASENCHANTMENTS.put("infinite", Enchantment.ARROW_INFINITE);
ALIASENCHANTMENTS.put("unlimited", Enchantment.ARROW_INFINITE);
ALIASENCHANTMENTS.put("unlimitedarrows", Enchantment.ARROW_INFINITE);
ALIASENCHANTMENTS.put("ai", Enchantment.ARROW_INFINITE);
ALIASENCHANTMENTS.put("infinitearrows", Enchantment.ARROW_INFINITE);
ENCHANTMENTS.put("infarrows", Enchantment.ARROW_INFINITE);
ENCHANTMENTS.put("infinity", Enchantment.ARROW_INFINITE);
ALIASENCHANTMENTS.put("infinite", Enchantment.ARROW_INFINITE);
ALIASENCHANTMENTS.put("unlimited", Enchantment.ARROW_INFINITE);
ALIASENCHANTMENTS.put("unlimitedarrows", Enchantment.ARROW_INFINITE);
ALIASENCHANTMENTS.put("ai", Enchantment.ARROW_INFINITE);
}
ENCHANTMENTS.put("luck", Enchantment.LUCK);
ALIASENCHANTMENTS.put("luckofsea", Enchantment.LUCK);
ALIASENCHANTMENTS.put("luckofseas", Enchantment.LUCK);
ALIASENCHANTMENTS.put("rodluck", Enchantment.LUCK);
public static Enchantment getByName(String name) {
Enchantment enchantment;
if (NumberUtil.isInt(name)) {
enchantment = Enchantment.getById(Integer.parseInt(name));
} else {
enchantment = Enchantment.getByName(name.toUpperCase(Locale.ENGLISH));
}
if (enchantment == null)
{
enchantment = ENCHANTMENTS.get(name.toLowerCase(Locale.ENGLISH));
}
if (enchantment == null)
{
enchantment = ALIASENCHANTMENTS.get(name.toLowerCase(Locale.ENGLISH));
}
return enchantment;
}
ENCHANTMENTS.put("lure", Enchantment.LURE);
ALIASENCHANTMENTS.put("rodlure", Enchantment.LURE);
public static Set<Entry<String, Enchantment>> entrySet()
{
return ENCHANTMENTS.entrySet();
}
// 1.8
try {
final Enchantment depthStrider = Enchantment.getByName("DEPTH_STRIDER");
if (depthStrider != null) {
ENCHANTMENTS.put("depthstrider", depthStrider);
ALIASENCHANTMENTS.put("depth", depthStrider);
ALIASENCHANTMENTS.put("strider", depthStrider);
}
} catch (final IllegalArgumentException ignored) {
}
// 1.9
try {
final Enchantment frostWalker = Enchantment.getByName("FROST_WALKER");
if (frostWalker != null) {
ENCHANTMENTS.put("frostwalker", frostWalker);
ALIASENCHANTMENTS.put("frost", frostWalker);
ALIASENCHANTMENTS.put("walker", frostWalker);
}
final Enchantment mending = Enchantment.getByName("MENDING");
if (mending != null) {
ENCHANTMENTS.put("mending", mending);
}
} catch (final IllegalArgumentException ignored) {
}
// 1.11
try {
final Enchantment bindingCurse = Enchantment.getByName("BINDING_CURSE");
if (bindingCurse != null) {
ENCHANTMENTS.put("bindingcurse", bindingCurse);
ALIASENCHANTMENTS.put("bindcurse", bindingCurse);
ALIASENCHANTMENTS.put("binding", bindingCurse);
ALIASENCHANTMENTS.put("bind", bindingCurse);
}
final Enchantment vanishingCurse = Enchantment.getByName("VANISHING_CURSE");
if (vanishingCurse != null) {
ENCHANTMENTS.put("vanishingcurse", vanishingCurse);
ALIASENCHANTMENTS.put("vanishcurse", vanishingCurse);
ALIASENCHANTMENTS.put("vanishing", vanishingCurse);
ALIASENCHANTMENTS.put("vanish", vanishingCurse);
}
final Enchantment sweeping = Enchantment.getByName("SWEEPING_EDGE");
if (sweeping != null) {
ENCHANTMENTS.put("sweepingedge", sweeping);
ALIASENCHANTMENTS.put("sweepedge", sweeping);
ALIASENCHANTMENTS.put("sweeping", sweeping);
}
} catch (final IllegalArgumentException ignored) {
}
try { // 1.13
final Enchantment loyalty = Enchantment.getByName("LOYALTY");
if (loyalty != null) {
ENCHANTMENTS.put("loyalty", loyalty);
ALIASENCHANTMENTS.put("loyal", loyalty);
ALIASENCHANTMENTS.put("return", loyalty);
}
final Enchantment impaling = Enchantment.getByName("IMPALING");
if (impaling != null) {
ENCHANTMENTS.put("impaling", impaling);
ALIASENCHANTMENTS.put("impale", impaling);
ALIASENCHANTMENTS.put("oceandamage", impaling);
ALIASENCHANTMENTS.put("oceandmg", impaling);
}
final Enchantment riptide = Enchantment.getByName("RIPTIDE");
if (riptide != null) {
ENCHANTMENTS.put("riptide", riptide);
ALIASENCHANTMENTS.put("rip", riptide);
ALIASENCHANTMENTS.put("tide", riptide);
ALIASENCHANTMENTS.put("launch", riptide);
}
final Enchantment channelling = Enchantment.getByName("CHANNELING");
if (channelling != null) {
ENCHANTMENTS.put("channelling", channelling);
ALIASENCHANTMENTS.put("chanelling", channelling);
ALIASENCHANTMENTS.put("channeling", channelling);
ALIASENCHANTMENTS.put("chaneling", channelling);
ALIASENCHANTMENTS.put("channel", channelling);
}
} catch (final IllegalArgumentException ignored) {
}
try { // 1.14
final Enchantment multishot = Enchantment.getByName("MULTISHOT");
if (multishot != null) {
ENCHANTMENTS.put("multishot", multishot);
ALIASENCHANTMENTS.put("tripleshot", multishot);
}
final 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);
}
final Enchantment piercing = Enchantment.getByName("PIERCING");
if (piercing != null) {
ENCHANTMENTS.put("piercing", piercing);
}
} catch (final IllegalArgumentException ignored) {
}
try { // 1.16
final Enchantment soulspeed = Enchantment.getByName("SOUL_SPEED");
if (soulspeed != null) {
ENCHANTMENTS.put("soulspeed", soulspeed);
ALIASENCHANTMENTS.put("soilspeed", soulspeed);
ALIASENCHANTMENTS.put("sandspeed", soulspeed);
}
} catch (final IllegalArgumentException ignored) {
}
try {
final Class<?> namespacedKeyClass = Class.forName("org.bukkit.NamespacedKey");
final Class<?> enchantmentClass = Class.forName("org.bukkit.enchantments.Enchantment");
enchantmentClass.getDeclaredMethod("getByKey", namespacedKeyClass);
isFlat = true;
} catch (final ClassNotFoundException | NoSuchMethodException e) {
isFlat = false;
}
}
private Enchantments() {
}
public static Enchantment getByName(final String name) {
Enchantment enchantment = null;
if (isFlat) { // 1.13+ only
enchantment = Enchantment.getByKey(NamespacedKey.minecraft(name.toLowerCase()));
}
if (enchantment == null) {
enchantment = Enchantment.getByName(name.toUpperCase());
}
if (enchantment == null) {
enchantment = ENCHANTMENTS.get(name.toLowerCase(Locale.ENGLISH));
}
if (enchantment == null) {
enchantment = ALIASENCHANTMENTS.get(name.toLowerCase(Locale.ENGLISH));
}
return enchantment;
}
public static Set<Entry<String, Enchantment>> entrySet() {
return ENCHANTMENTS.entrySet();
}
public static Set<String> keySet() {
return ENCHANTMENTS.keySet();
}
}
File diff suppressed because it is too large. Load diff
@@ -1,46 +1,62 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.MaterialUtil;
import net.ess3.api.IEssentials;
import org.bukkit.GameMode;
import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import java.util.Locale;
public class EssentialsBlockListener implements Listener
{
private final transient IEssentials ess;
public class EssentialsBlockListener implements Listener {
private final transient IEssentials ess;
public EssentialsBlockListener(final IEssentials ess)
{
this.ess = ess;
}
public EssentialsBlockListener(final IEssentials ess) {
this.ess = ess;
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockPlace(final BlockPlaceEvent event)
{
// Do not rely on getItemInHand();
// http://leaky.bukkit.org/issues/663
final ItemStack is = LocationUtil.convertBlockToItem(event.getBlockPlaced());
if (is == null)
{
return;
}
final User user = ess.getUser(event.getPlayer());
if (user.hasUnlimited(is) && user.getGameMode() == GameMode.SURVIVAL)
{
ess.scheduleSyncDelayedTask(
new Runnable()
{
@Override
public void run()
{
user.getInventory().addItem(is);
user.updateInventory();
}
});
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockPlace(final BlockPlaceEvent event) {
// Do not rely on getItemInHand();
// http://leaky.bukkit.org/issues/663
final ItemStack is = LocationUtil.convertBlockToItem(event.getBlockPlaced());
if (is == null) {
return;
}
if (is.getType() == MaterialUtil.SPAWNER && event.getItemInHand() != null && event.getPlayer() != null && event.getItemInHand().getType() == MaterialUtil.SPAWNER) {
final BlockState blockState = event.getBlockPlaced().getState();
if (blockState instanceof CreatureSpawner) {
final CreatureSpawner spawner = (CreatureSpawner) blockState;
final EntityType type = ess.getSpawnerItemProvider().getEntityType(event.getItemInHand());
if (type != null && Mob.fromBukkitType(type) != null) {
if (ess.getUser(event.getPlayer()).isAuthorized("essentials.spawnerconvert." + Mob.fromBukkitType(type).name().toLowerCase(Locale.ENGLISH))) {
spawner.setSpawnedType(type);
spawner.update();
}
}
}
}
final User user = ess.getUser(event.getPlayer());
if (user.hasUnlimited(is) && user.getBase().getGameMode() == GameMode.SURVIVAL) {
class UnlimitedItemSpawnTask implements Runnable {
@Override
public void run() {
user.getBase().getInventory().addItem(is);
user.getBase().updateInventory();
}
}
ess.scheduleSyncDelayedTask(new UnlimitedItemSpawnTask());
}
}
}
File diff suppressed because it is too large. Load diff
@@ -1,222 +1,300 @@
package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.api.IEssentials;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.entity.PotionSplashEvent;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import org.bukkit.Material;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.*;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.inventory.ItemStack;
import static com.earth2me.essentials.I18n.tl;
public class EssentialsEntityListener implements Listener
{
private static final Logger LOGGER = Logger.getLogger("Minecraft");
private final IEssentials ess;
private static final transient Pattern powertoolPlayer = Pattern.compile("\\{player\\}");
public class EssentialsEntityListener implements Listener {
private static final Logger LOGGER = Logger.getLogger("Essentials");
private static final transient Pattern powertoolPlayer = Pattern.compile("\\{player\\}");
private final IEssentials ess;
public EssentialsEntityListener(IEssentials ess)
{
this.ess = ess;
}
public EssentialsEntityListener(final IEssentials ess) {
this.ess = ess;
}
// This method does something undocumented reguarding certain bucket types #EasterEgg
@EventHandler(priority = EventPriority.LOW)
public void onEntityDamage(final EntityDamageByEntityEvent event)
{
final Entity eAttack = event.getDamager();
final Entity eDefend = event.getEntity();
if (eAttack instanceof Player)
{
final User attacker = ess.getUser(eAttack);
if (eDefend instanceof Player)
{
onPlayerVsPlayerDamage(event, (Player)eDefend, attacker);
}
else if (eDefend instanceof Ageable)
{
final ItemStack hand = attacker.getItemInHand();
if (hand != null && hand.getType() == Material.MILK_BUCKET)
{
((Ageable)eDefend).setBaby();
hand.setType(Material.BUCKET);
attacker.setItemInHand(hand);
attacker.updateInventory();
event.setCancelled(true);
}
}
attacker.updateActivity(true);
}
else if (eAttack instanceof Projectile && eDefend instanceof Player)
{
Entity shooter = ((Projectile)event.getDamager()).getShooter();
if (shooter instanceof Player)
{
final User attacker = ess.getUser(shooter);
onPlayerVsPlayerDamage(event, (Player)eDefend, attacker);
attacker.updateActivity(true);
}
}
}
// This method does something undocumented reguarding certain bucket types #EasterEgg
@EventHandler(priority = EventPriority.LOW)
public void onEntityDamage(final EntityDamageByEntityEvent event) {
final Entity eAttack = event.getDamager();
final Entity eDefend = event.getEntity();
if (eAttack instanceof Player) {
final User attacker = ess.getUser((Player) eAttack);
if (eDefend instanceof Player) {
onPlayerVsPlayerDamage(event, (Player) eDefend, attacker);
} else if (eDefend instanceof Ageable) {
final ItemStack hand = attacker.getBase().getItemInHand();
if (ess.getSettings().isMilkBucketEasterEggEnabled()
&& hand != null && hand.getType() == Material.MILK_BUCKET) {
((Ageable) eDefend).setBaby();
hand.setType(Material.BUCKET);
attacker.getBase().setItemInHand(hand);
attacker.getBase().updateInventory();
event.setCancelled(true);
}
}
attacker.updateActivityOnInteract(true);
} else if (eAttack instanceof Projectile && eDefend instanceof Player) {
final Projectile projectile = (Projectile) event.getDamager();
//This should return a ProjectileSource on 1.7.3 beta +
final Object shooter = projectile.getShooter();
if (shooter instanceof Player) {
final User attacker = ess.getUser((Player) shooter);
onPlayerVsPlayerDamage(event, (Player) eDefend, attacker);
attacker.updateActivityOnInteract(true);
}
}
}
private void onPlayerVsPlayerDamage(final EntityDamageByEntityEvent event, final Player defender, final User attacker)
{
if (ess.getSettings().getLoginAttackDelay() > 0
&& (System.currentTimeMillis() < (attacker.getLastLogin() + ess.getSettings().getLoginAttackDelay()))
&& !attacker.isAuthorized("essentials.pvpdelay.exempt"))
{
event.setCancelled(true);
}
private void onPlayerVsPlayerDamage(final EntityDamageByEntityEvent event, final Player defender, final User attacker) {
if (ess.getSettings().getLoginAttackDelay() > 0 && (System.currentTimeMillis() < (attacker.getLastLogin() + ess.getSettings().getLoginAttackDelay())) && !attacker.isAuthorized("essentials.pvpdelay.exempt")) {
event.setCancelled(true);
}
if (!defender.equals(attacker.getBase()) && (attacker.hasInvulnerabilityAfterTeleport() || ess.getUser(defender).hasInvulnerabilityAfterTeleport()))
{
event.setCancelled(true);
}
if (!defender.equals(attacker.getBase()) && (attacker.hasInvulnerabilityAfterTeleport() || ess.getUser(defender).hasInvulnerabilityAfterTeleport())) {
event.setCancelled(true);
}
if (attacker.isGodModeEnabled() && !attacker.isAuthorized("essentials.god.pvp"))
{
event.setCancelled(true);
}
if (attacker.isGodModeEnabled() && !attacker.isAuthorized("essentials.god.pvp")) {
event.setCancelled(true);
}
if (attacker.isHidden() && !attacker.isAuthorized("essentials.vanish.pvp"))
{
event.setCancelled(true);
}
if (attacker.isHidden() && !attacker.isAuthorized("essentials.vanish.pvp")) {
event.setCancelled(true);
}
onPlayerVsPlayerPowertool(event, defender, attacker);
}
if (attacker.arePowerToolsEnabled()) {
onPlayerVsPlayerPowertool(event, defender, attacker);
}
}
private void onPlayerVsPlayerPowertool(final EntityDamageByEntityEvent event, final Player defender, final User attacker)
{
final List<String> commandList = attacker.getPowertool(attacker.getItemInHand());
if (commandList != null && !commandList.isEmpty())
{
for (final String tempCommand : commandList)
{
final String command = powertoolPlayer.matcher(tempCommand).replaceAll(defender.getName());
if (command != null && !command.isEmpty() && !command.equals(tempCommand))
{
ess.scheduleSyncDelayedTask(
new Runnable()
{
@Override
public void run()
{
attacker.getServer().dispatchCommand(attacker.getBase(), command);
LOGGER.log(Level.INFO, String.format("[PT] %s issued server command: /%s", attacker.getName(), command));
}
});
private void onPlayerVsPlayerPowertool(final EntityDamageByEntityEvent event, final Player defender, final User attacker) {
final List<String> commandList = attacker.getPowertool(attacker.getBase().getItemInHand());
if (commandList != null && !commandList.isEmpty()) {
for (final String tempCommand : commandList) {
final String command = powertoolPlayer.matcher(tempCommand).replaceAll(defender.getName());
if (command != null && !command.isEmpty() && !command.equals(tempCommand)) {
event.setCancelled(true);
return;
}
}
}
}
class PowerToolInteractTask implements Runnable {
@Override
public void run() {
attacker.getBase().chat("/" + command);
LOGGER.log(Level.INFO, String.format("[PT] %s issued server command: /%s", attacker.getName(), command));
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityDamage(final EntityDamageEvent event)
{
if (event.getEntity() instanceof Player && ess.getUser(event.getEntity()).isGodModeEnabled())
{
final Player player = (Player)event.getEntity();
player.setFireTicks(0);
player.setRemainingAir(player.getMaximumAir());
event.setCancelled(true);
}
}
ess.scheduleSyncDelayedTask(new PowerToolInteractTask());
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityCombust(final EntityCombustEvent event)
{
if (event.getEntity() instanceof Player && ess.getUser(event.getEntity()).isGodModeEnabled())
{
event.setCancelled(true);
}
}
event.setCancelled(true);
return;
}
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerDeathEvent(final PlayerDeathEvent event)
{
final User user = ess.getUser(event.getEntity());
if (user.isAuthorized("essentials.back.ondeath") && !ess.getSettings().isCommandDisabled("back"))
{
user.setLastLocation();
user.sendMessage(_("backAfterDeath"));
}
if (!ess.getSettings().areDeathMessagesEnabled())
{
event.setDeathMessage("");
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityDamage(final EntityDamageEvent event) {
if (event.getEntity() instanceof Player && ess.getUser((Player) event.getEntity()).isGodModeEnabled()) {
final Player player = (Player) event.getEntity();
player.setFireTicks(0);
player.setRemainingAir(player.getMaximumAir());
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerDeathExpEvent(final PlayerDeathEvent event)
{
final User user = ess.getUser(event.getEntity());
if (user.isAuthorized("essentials.keepxp"))
{
event.setKeepLevel(true);
event.setDroppedExp(0);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityCombust(final EntityCombustEvent event) {
if (event.getEntity() instanceof Player && ess.getUser((Player) event.getEntity()).isGodModeEnabled()) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onFoodLevelChange(final FoodLevelChangeEvent event)
{
if (event.getEntity() instanceof Player)
{
final User user = ess.getUser(event.getEntity());
if (user.isGodModeEnabled())
{
if (user.isGodModeEnabledRaw())
{
user.setFoodLevel(20);
user.setSaturation(10);
}
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onEntityCombustByEntity(final EntityCombustByEntityEvent event) {
if (event.getCombuster() instanceof Arrow && event.getEntity() instanceof Player) {
final Arrow combuster = (Arrow) event.getCombuster();
if (combuster.getShooter() instanceof Player) {
final Player shooter = (Player) combuster.getShooter();
if (shooter.hasMetadata("NPC")) {
return;
}
final User srcCombuster = ess.getUser(shooter.getUniqueId());
if (srcCombuster.isGodModeEnabled() && !srcCombuster.isAuthorized("essentials.god.pvp")) {
event.setCancelled(true);
}
if (srcCombuster.isHidden() && !srcCombuster.isAuthorized("essentials.vanish.pvp")) {
event.setCancelled(true);
}
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityRegainHealth(final EntityRegainHealthEvent event)
{
if (event.getRegainReason() == RegainReason.SATIATED && event.getEntity() instanceof Player
&& ess.getUser(event.getEntity()).isAfk() && ess.getSettings().getFreezeAfkPlayers())
{
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerDeathEvent(final PlayerDeathEvent event) {
final Entity entity = event.getEntity();
if (entity.hasMetadata("NPC")) {
return;
}
final User user = ess.getUser(event.getEntity());
if (ess.getSettings().infoAfterDeath()) {
final Location loc = user.getLocation();
user.sendMessage(tl("infoAfterDeath", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
}
if (user.isAuthorized("essentials.back.ondeath") && !ess.getSettings().isCommandDisabled("back")) {
user.setLastLocation();
user.sendMessage(tl("backAfterDeath"));
}
if (!ess.getSettings().areDeathMessagesEnabled()) {
event.setDeathMessage("");
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPotionSplashEvent(final PotionSplashEvent event)
{
for (LivingEntity entity : event.getAffectedEntities())
{
if (entity instanceof Player && ess.getUser(entity).isGodModeEnabled())
{
event.setIntensity(entity, 0d);
}
}
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerDeathExpEvent(final PlayerDeathEvent event) {
final User user = ess.getUser(event.getEntity());
if (user.isAuthorized("essentials.keepxp")) {
event.setKeepLevel(true);
event.setDroppedExp(0);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityShootBow(EntityShootBowEvent event)
{
if (event.getEntity() instanceof Player)
{
final User user = ess.getUser(event.getEntity());
if (user.isAfk())
{
user.updateActivity(true);
}
}
}
@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);
event.getDrops().clear();
final ISettings.KeepInvPolicy vanish = ess.getSettings().getVanishingItemsPolicy();
final ISettings.KeepInvPolicy bind = ess.getSettings().getBindingItemsPolicy();
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01) && (vanish != ISettings.KeepInvPolicy.KEEP || bind != ISettings.KeepInvPolicy.KEEP)) {
for (final ItemStack stack : event.getEntity().getInventory()) {
if (stack != null) {
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
if (vanish == ISettings.KeepInvPolicy.DELETE) {
event.getEntity().getInventory().remove(stack);
} else if (vanish == ISettings.KeepInvPolicy.DROP) {
event.getDrops().add(stack);
event.getEntity().getInventory().remove(stack);
}
}
if (stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE)) {
if (bind == ISettings.KeepInvPolicy.DELETE) {
event.getEntity().getInventory().remove(stack);
} else if (bind == ISettings.KeepInvPolicy.DROP) {
event.getEntity().getInventory().remove(stack);
event.getDrops().add(stack);
}
}
}
}
final ItemStack[] armor = event.getEntity().getInventory().getArmorContents();
for (int i = 0; i < armor.length; i++) {
final ItemStack stack = armor[i];
if (stack != null) {
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
if (vanish == ISettings.KeepInvPolicy.DELETE) {
armor[i] = null;
} else if (vanish == ISettings.KeepInvPolicy.DROP) {
if (!event.getDrops().contains(stack)) {
event.getDrops().add(stack);
}
armor[i] = null;
}
}
if (stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE)) {
if (bind == ISettings.KeepInvPolicy.DELETE) {
armor[i] = null;
} else if (bind == ISettings.KeepInvPolicy.DROP) {
if (!event.getDrops().contains(stack)) {
event.getDrops().add(stack);
}
armor[i] = null;
}
}
}
}
event.getEntity().getInventory().setArmorContents(armor);
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onFoodLevelChange(final FoodLevelChangeEvent event) {
if (event.getEntity() instanceof Player) {
final User user = ess.getUser((Player) event.getEntity());
if (user.isGodModeEnabled()) {
if (user.isGodModeEnabledRaw()) {
user.getBase().setFoodLevel(20);
user.getBase().setSaturation(10);
}
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityRegainHealth(final EntityRegainHealthEvent event) {
if (event.getRegainReason() == RegainReason.SATIATED && event.getEntity() instanceof Player && ess.getUser((Player) event.getEntity()).isAfk() && ess.getSettings().getFreezeAfkPlayers()) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPotionSplashEvent(final PotionSplashEvent event) {
for (final LivingEntity entity : event.getAffectedEntities()) {
if (entity instanceof Player && ess.getUser((Player) entity).isGodModeEnabled()) {
event.setIntensity(entity, 0d);
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityShootBow(final EntityShootBowEvent event) {
if (event.getEntity() instanceof Player) {
final User user = ess.getUser((Player) event.getEntity());
if (user.isAfk()) {
user.updateActivityOnInteract(true);
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityTarget(final EntityTargetEvent event) {
if (event.getTarget() instanceof Player) {
final User user = ess.getUser((Player) event.getTarget());
if (user.isVanished()) {
event.setCancelled(true);
}
}
}
}
File diff suppressed because it is too large. Load diff
@@ -1,58 +1,50 @@
package com.earth2me.essentials;
import java.util.logging.Level;
import com.earth2me.essentials.register.payment.Methods;
import net.ess3.api.IEssentials;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.PluginEnableEvent;
import java.util.logging.Level;
public class EssentialsPluginListener implements Listener, IConf
{
private final transient IEssentials ess;
public class EssentialsPluginListener implements Listener, IConf {
private final transient IEssentials ess;
public EssentialsPluginListener(final IEssentials ess)
{
this.ess = ess;
}
public EssentialsPluginListener(final IEssentials ess) {
this.ess = ess;
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPluginEnable(final PluginEnableEvent event)
{
if (event.getPlugin().getName().equals("EssentialsChat"))
{
ess.getSettings().setEssentialsChatActive(true);
}
ess.getPermissionsHandler().checkPermissions();
ess.getAlternativeCommandsHandler().addPlugin(event.getPlugin());
if (!ess.getPaymentMethod().hasMethod() && ess.getPaymentMethod().setMethod(ess.getServer().getPluginManager()))
{
ess.getLogger().log(Level.INFO, "Payment method found (" + ess.getPaymentMethod().getMethod().getLongName() + " version: " + ess.getPaymentMethod().getMethod().getVersion() + ")");
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPluginEnable(final PluginEnableEvent event) {
if (event.getPlugin().getName().equals("EssentialsChat")) {
ess.getSettings().setEssentialsChatActive(true);
}
ess.getPermissionsHandler().setUseSuperperms(ess.getSettings().useBukkitPermissions());
ess.getPermissionsHandler().checkPermissions();
ess.getAlternativeCommandsHandler().addPlugin(event.getPlugin());
if (!Methods.hasMethod() && Methods.setMethod(ess.getServer().getPluginManager())) {
ess.getLogger().log(Level.INFO, "Payment method found (" + Methods.getMethod().getLongName() + " version: " + Methods.getMethod().getVersion() + ")");
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPluginDisable(final PluginDisableEvent event)
{
if (event.getPlugin().getName().equals("EssentialsChat"))
{
ess.getSettings().setEssentialsChatActive(false);
}
ess.getPermissionsHandler().checkPermissions();
ess.getAlternativeCommandsHandler().removePlugin(event.getPlugin());
// Check to see if the plugin thats being disabled is the one we are using
if (ess.getPaymentMethod() != null && ess.getPaymentMethod().hasMethod() && ess.getPaymentMethod().checkDisabled(event.getPlugin()))
{
ess.getPaymentMethod().reset();
ess.getLogger().log(Level.INFO, "Payment method was disabled. No longer accepting payments.");
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPluginDisable(final PluginDisableEvent event) {
if (event.getPlugin().getName().equals("EssentialsChat")) {
ess.getSettings().setEssentialsChatActive(false);
}
ess.getPermissionsHandler().checkPermissions();
ess.getAlternativeCommandsHandler().removePlugin(event.getPlugin());
// Check to see if the plugin thats being disabled is the one we are using
if (Methods.hasMethod() && Methods.checkDisabled(event.getPlugin())) {
Methods.reset();
ess.getLogger().log(Level.INFO, "Payment method was disabled. No longer accepting payments.");
}
}
@Override
public void reloadConfig()
{
ess.getPermissionsHandler().setUseSuperperms(ess.getSettings().useBukkitPermissions());
ess.getPermissionsHandler().checkPermissions();
}
@Override
public void reloadConfig() {
}
}
@@ -0,0 +1,116 @@
package com.earth2me.essentials;
import net.ess3.api.IEssentials;
import net.ess3.nms.refl.ReflUtil;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
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 final List<String> ignoredSLPECallers = Arrays.asList(
".LegacyPingHandler.channelRead(", // CB responding to pings from pre-Netty clients
"de.dytanic.cloudnet.bridge.BukkitBootstrap", // CloudNet v2 doing... something
"de.dytanic.cloudnet.ext.bridge.bukkit.BukkitCloudNetBridgePlugin" // CloudNet v3 doing... something else
);
private final transient IEssentials ess;
private final boolean isPaperSample;
private boolean unsupportedLogged = false;
private boolean npeWarned = false;
private Method setSampleText;
private Method getSampleText;
public EssentialsServerListener(final IEssentials ess) {
this.ess = ess;
if (ReflUtil.getClassCached("com.destroystokyo.paper.event.server.PaperServerListPingEvent") == null) {
// This workaround is only necessary for older Paper builds
setSampleText = ReflUtil.getMethodCached(ServerListPingEvent.class, "setSampleText", List.class);
getSampleText = ReflUtil.getMethodCached(ServerListPingEvent.class, "getSampleText");
if (setSampleText != null && getSampleText != null) {
ess.getLogger().info("ServerListPingEvent: Paper 1.12.2 setSampleText API");
isPaperSample = true;
return;
}
}
ess.getLogger().info("ServerListPingEvent: Spigot iterator API");
isPaperSample = false;
}
@EventHandler(priority = EventPriority.LOWEST)
public void onServerListPing(final ServerListPingEvent event) throws Exception {
if (isPaperSample) {
try {
final List<String> playerNames = (List<String>) getSampleText.invoke(event, null);
playerNames.removeIf(player -> ess.getUser(player).isVanished());
setSampleText.invoke(event, playerNames);
} catch (final IllegalAccessException | InvocationTargetException | ClassCastException e) {
if (!unsupportedLogged && shouldWarnSLPECaller(e)) {
ess.getLogger().log(Level.WARNING, "Unable to hide players from server list ping "
+ "using Paper 1.12 method!", e);
unsupportedLogged = true;
}
} catch (final NullPointerException e) {
if (!npeWarned && shouldWarnSLPECaller(e)) {
npeWarned = true;
final Exception ex = new Exception("A plugin has fired a ServerListPingEvent "
+ "without implementing Paper's methods. Point the author to https://git.io/v7Xzl.");
ex.setStackTrace(e.getStackTrace());
throw ex;
}
}
} else {
try {
final Iterator<Player> iterator = event.iterator();
while (iterator.hasNext()) {
final Player player = iterator.next();
if (ess.getUser(player).isVanished()) {
iterator.remove();
}
}
} catch (final UnsupportedOperationException e) {
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(final Throwable throwable) {
final int maxStackDepth = 20; // Limit the depth when searching through the stack trace
int depth = 0;
for (final StackTraceElement element : throwable.getStackTrace()) {
depth++;
if (depth > maxStackDepth) {
break;
}
for (final 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
}
}
@@ -1,123 +1,111 @@
package com.earth2me.essentials;
import net.ess3.api.IEssentials;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import org.bukkit.entity.Player;
public class EssentialsTimer implements Runnable {
private final transient IEssentials ess;
private final transient Set<UUID> onlineUsers = new HashSet<>(); // Field is necessary for hidden users
private final LinkedList<Double> history = new LinkedList<>();
@SuppressWarnings("FieldCanBeLocal")
private final long maxTime = 10 * 1000000;
@SuppressWarnings("FieldCanBeLocal")
private final long tickInterval = 50;
private transient long lastPoll = System.nanoTime();
private int skip1 = 0;
private int skip2 = 0;
public class EssentialsTimer implements Runnable
{
private final transient IEssentials ess;
private final transient Set<String> onlineUsers = new HashSet<String>();
private transient long lastPoll = System.nanoTime();
private final LinkedList<Double> history = new LinkedList<Double>();
private int skip1 = 0;
private int skip2 = 0;
private final long maxTime = 10 * 1000000;
private final long tickInterval = 50;
EssentialsTimer(final IEssentials ess)
{
this.ess = ess;
history.add(20d);
}
@Override
public void run()
{
final long startTime = System.nanoTime();
final long currentTime = System.currentTimeMillis();
long timeSpent = (startTime - lastPoll) / 1000;
if (timeSpent == 0)
{
timeSpent = 1;
}
if (history.size() > 10)
{
history.remove();
}
double tps = tickInterval * 1000000.0 / timeSpent;
if (tps <= 21)
{
history.add(tps);
}
lastPoll = startTime;
int count = 0;
for (Player player : ess.getServer().getOnlinePlayers())
{
count++;
if (skip1 > 0)
{
skip1--;
continue;
}
if (count % 10 == 0)
{
if (System.nanoTime() - startTime > maxTime / 2)
{
skip1 = count - 1;
break;
}
}
try
{
final User user = ess.getUser(player);
onlineUsers.add(user.getName());
user.setLastOnlineActivity(currentTime);
user.checkActivity();
}
catch (Exception e)
{
ess.getLogger().log(Level.WARNING, "EssentialsTimer Error:", e);
}
}
count = 0;
final Iterator<String> iterator = onlineUsers.iterator();
while (iterator.hasNext())
{
count++;
if (skip2 > 0)
{
skip2--;
continue;
}
if (count % 10 == 0)
{
if (System.nanoTime() - startTime > maxTime)
{
skip2 = count - 1;
break;
}
}
final User user = ess.getUser(iterator.next());
if (user.getLastOnlineActivity() < currentTime && user.getLastOnlineActivity() > user.getLastLogout())
{
if (!user.isHidden()) {
user.setLastLogout(user.getLastOnlineActivity());
}
iterator.remove();
continue;
}
user.checkMuteTimeout(currentTime);
user.checkJailTimeout(currentTime);
user.resetInvulnerabilityAfterTeleport();
}
}
public double getAverageTPS()
{
double avg = 0;
for (Double f : history)
{
if (f != null)
{
avg += f;
}
}
return avg / history.size();
}
EssentialsTimer(final IEssentials ess) {
this.ess = ess;
history.add(20d);
}
@Override
public void run() {
final long startTime = System.nanoTime();
final long currentTime = System.currentTimeMillis();
long timeSpent = (startTime - lastPoll) / 1000;
if (timeSpent == 0) {
timeSpent = 1;
}
if (history.size() > 10) {
history.remove();
}
final double tps = tickInterval * 1000000.0 / timeSpent;
if (tps <= 21) {
history.add(tps);
}
lastPoll = startTime;
int count = 0;
for (final Player player : ess.getOnlinePlayers()) {
count++;
if (skip1 > 0) {
skip1--;
continue;
}
if (count % 10 == 0) {
if (System.nanoTime() - startTime > maxTime / 2) {
skip1 = count - 1;
break;
}
}
try {
final User user = ess.getUser(player);
onlineUsers.add(user.getBase().getUniqueId());
user.setLastOnlineActivity(currentTime);
user.checkActivity();
} catch (final Exception e) {
ess.getLogger().log(Level.WARNING, "EssentialsTimer Error:", e);
}
}
count = 0;
final Iterator<UUID> iterator = onlineUsers.iterator();
while (iterator.hasNext()) {
count++;
if (skip2 > 0) {
skip2--;
continue;
}
if (count % 10 == 0) {
if (System.nanoTime() - startTime > maxTime) {
skip2 = count - 1;
break;
}
}
final User user = ess.getUser(iterator.next());
// Not sure why this would happen, but it does
if (user == null) {
iterator.remove();
continue;
}
if (user.getLastOnlineActivity() < currentTime && user.getLastOnlineActivity() > user.getLastLogout()) {
if (!user.isHidden()) {
user.setLastLogout(user.getLastOnlineActivity());
}
iterator.remove();
continue;
}
user.checkMuteTimeout(currentTime);
user.checkJailTimeout(currentTime);
user.resetInvulnerabilityAfterTeleport();
}
}
public double getAverageTPS() {
double avg = 0;
for (final Double f : history) {
if (f != null) {
avg += f;
}
}
return avg / history.size();
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,62 @@
package com.earth2me.essentials;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import org.bukkit.Bukkit;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.UUID;
import java.util.logging.Level;
public class EssentialsUserConf extends EssentialsConf {
public final String username;
public final UUID uuid;
public EssentialsUserConf(final String username, final UUID uuid, final File configFile) {
super(configFile);
this.username = username;
this.uuid = uuid;
}
@Override
public boolean legacyFileExists() {
final File file = new File(configFile.getParentFile(), username + ".yml");
return file.exists();
}
@Override
public void convertLegacyFile() {
final File file = new File(configFile.getParentFile(), username + ".yml");
try {
Files.move(file, new File(configFile.getParentFile(), uuid + ".yml"));
} catch (final IOException ex) {
Bukkit.getLogger().log(Level.WARNING, "Failed to migrate user: " + username, ex);
}
setProperty("lastAccountName", username);
}
private File getAltFile() {
final UUID fn = UUID.nameUUIDFromBytes(("OfflinePlayer:" + username.toLowerCase(Locale.ENGLISH)).getBytes(Charsets.UTF_8));
return new File(configFile.getParentFile(), fn.toString() + ".yml");
}
@Override
public boolean altFileExists() {
if (username.equals(username.toLowerCase())) {
return false;
}
return getAltFile().exists();
}
@Override
public void convertAltFile() {
try {
Files.move(getAltFile(), new File(configFile.getParentFile(), uuid + ".yml"));
} catch (final IOException ex) {
Bukkit.getLogger().log(Level.WARNING, "Failed to migrate user: " + username, ex);
}
}
}
@@ -6,84 +6,67 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class ExecuteTimer {
private final transient List<ExecuteRecord> times;
private final transient DecimalFormat decimalFormat = new DecimalFormat("#0.000", DecimalFormatSymbols.getInstance(Locale.US));
public class ExecuteTimer
{
private final transient List<ExecuteRecord> times;
private final transient DecimalFormat decimalFormat = new DecimalFormat("#0.000", DecimalFormatSymbols.getInstance(Locale.US));
public ExecuteTimer() {
times = new ArrayList<>();
}
public void start() {
times.clear();
mark("start");
public ExecuteTimer()
{
times = new ArrayList<ExecuteRecord>();
}
}
public void start()
{
times.clear();
mark("start");
public void mark(final String label) {
if (!times.isEmpty() || "start".equals(label)) {
times.add(new ExecuteRecord(label, System.nanoTime()));
}
}
}
public String end() {
final StringBuilder output = new StringBuilder();
output.append("execution time: ");
String mark;
long time0 = 0;
long time1 = 0;
long time2 = 0;
double duration;
public void mark(final String label)
{
if (!times.isEmpty() || "start".equals(label))
{
times.add(new ExecuteRecord(label, System.nanoTime()));
}
}
for (final ExecuteRecord pair : times) {
mark = pair.getMark();
time2 = pair.getTime();
if (time1 > 0) {
duration = (time2 - time1) / 1000000.0;
output.append(mark).append(": ").append(decimalFormat.format(duration)).append("ms - ");
} else {
time0 = time2;
}
time1 = time2;
}
duration = (time1 - time0) / 1000000.0;
output.append("Total: ").append(decimalFormat.format(duration)).append("ms");
times.clear();
return output.toString();
}
public String end()
{
final StringBuilder output = new StringBuilder();
output.append("execution time: ");
String mark;
long time0 = 0;
long time1 = 0;
long time2 = 0;
double duration;
private static class ExecuteRecord {
private final String mark;
private final long time;
for (ExecuteRecord pair : times)
{
mark = (String)pair.getMark();
time2 = (Long)pair.getTime();
if (time1 > 0)
{
duration = (time2 - time1)/1000000.0;
output.append(mark).append(": ").append(decimalFormat.format(duration)).append("ms - ");
}
else
{
time0 = time2;
}
time1 = time2;
}
duration = (time1 - time0)/1000000.0;
output.append("Total: ").append(decimalFormat.format(duration)).append("ms");
times.clear();
return output.toString();
}
ExecuteRecord(final String mark, final long time) {
this.mark = mark;
this.time = time;
}
public String getMark() {
return mark;
}
static private class ExecuteRecord
{
private final String mark;
private final long time;
public ExecuteRecord(final String mark, final long time)
{
this.mark = mark;
this.time = time;
}
public String getMark()
{
return mark;
}
public long getTime()
{
return time;
}
}
}
public long getTime() {
return time;
}
}
}
+182 -159
View File
@@ -1,187 +1,210 @@
package com.earth2me.essentials;
import com.earth2me.essentials.api.II18n;
import net.ess3.api.IEssentials;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
public class I18n implements net.ess3.api.II18n {
private static final String MESSAGES = "messages";
private static final Pattern NODOUBLEMARK = Pattern.compile("''");
private static final ResourceBundle NULL_BUNDLE = new ResourceBundle() {
public Enumeration<String> getKeys() {
return null;
}
public class I18n implements II18n
{
private static I18n instance;
private static final String MESSAGES = "messages";
private final transient Locale defaultLocale = Locale.getDefault();
private transient Locale currentLocale = defaultLocale;
private transient ResourceBundle customBundle;
private transient ResourceBundle localeBundle;
private final transient ResourceBundle defaultBundle;
private final transient Map<String, MessageFormat> messageFormatCache = new HashMap<String, MessageFormat>();
private final transient IEssentials ess;
protected Object handleGetObject(final String key) {
return null;
}
};
private static I18n instance;
private final transient Locale defaultLocale = Locale.getDefault();
private final transient ResourceBundle defaultBundle;
private final transient IEssentials ess;
private transient Locale currentLocale = defaultLocale;
private transient ResourceBundle customBundle;
private transient ResourceBundle localeBundle;
private transient Map<String, MessageFormat> messageFormatCache = new HashMap<>();
public I18n(final IEssentials ess)
{
this.ess = ess;
customBundle = ResourceBundle.getBundle(MESSAGES, defaultLocale, new FileResClassLoader(I18n.class.getClassLoader(), ess));
localeBundle = ResourceBundle.getBundle(MESSAGES, defaultLocale);
defaultBundle = ResourceBundle.getBundle(MESSAGES, Locale.ENGLISH);
}
public I18n(final IEssentials ess) {
this.ess = ess;
defaultBundle = ResourceBundle.getBundle(MESSAGES, Locale.ENGLISH, new UTF8PropertiesControl());
localeBundle = defaultBundle;
customBundle = NULL_BUNDLE;
}
public void onEnable()
{
instance = this;
}
public static String tl(final String string, final Object... objects) {
if (instance == null) {
return "";
}
if (objects.length == 0) {
return NODOUBLEMARK.matcher(instance.translate(string)).replaceAll("'");
} else {
return instance.format(string, objects);
}
}
public void onDisable()
{
instance = null;
}
public static String capitalCase(final String input) {
return input == null || input.length() == 0 ? input : input.toUpperCase(Locale.ENGLISH).charAt(0) + input.toLowerCase(Locale.ENGLISH).substring(1);
}
@Override
public Locale getCurrentLocale()
{
return currentLocale;
}
public void onEnable() {
instance = this;
}
public String translate(final String string)
{
try
{
try
{
return customBundle.getString(string);
}
catch (MissingResourceException ex)
{
return localeBundle.getString(string);
}
}
catch (MissingResourceException ex)
{
Logger.getLogger("Minecraft").log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), localeBundle.getLocale().toString()), ex);
return defaultBundle.getString(string);
}
}
public void onDisable() {
instance = null;
}
public static String _(final String string, final Object... objects)
{
if (instance == null)
{
return "";
}
if (objects.length == 0)
{
return instance.translate(string);
}
else
{
return instance.format(string, objects);
}
}
@Override
public Locale getCurrentLocale() {
return currentLocale;
}
public String format(final String string, final Object... objects)
{
String format = translate(string);
MessageFormat messageFormat = messageFormatCache.get(format);
if (messageFormat == null)
{
try
{
messageFormat = new MessageFormat(format);
}
catch (IllegalArgumentException e)
{
ess.getLogger().log(Level.SEVERE, "Invalid Translation key for '" + string + "': " + e.getMessage());
format = format.replaceAll("\\{(\\D*?)\\}", "\\[$1\\]");
messageFormat = new MessageFormat(format);
}
messageFormatCache.put(format, messageFormat);
}
return messageFormat.format(objects);
}
private String translate(final String string) {
try {
try {
return customBundle.getString(string);
} catch (final MissingResourceException ex) {
return localeBundle.getString(string);
}
} catch (final MissingResourceException ex) {
Logger.getLogger("Essentials").log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), localeBundle.getLocale().toString()), ex);
return defaultBundle.getString(string);
}
}
public void updateLocale(final String loc)
{
if (loc == null || loc.isEmpty())
{
return;
}
final String[] parts = loc.split("[_\\.]");
if (parts.length == 1)
{
currentLocale = new Locale(parts[0]);
}
if (parts.length == 2)
{
currentLocale = new Locale(parts[0], parts[1]);
}
if (parts.length == 3)
{
currentLocale = new Locale(parts[0], parts[1], parts[2]);
}
ResourceBundle.clearCache();
Logger.getLogger("Minecraft").log(Level.INFO, String.format("Using locale %s", currentLocale.toString()));
customBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new FileResClassLoader(I18n.class.getClassLoader(), ess));
localeBundle = ResourceBundle.getBundle(MESSAGES, currentLocale);
}
public String format(final String string, final Object... objects) {
String format = translate(string);
MessageFormat messageFormat = messageFormatCache.get(format);
if (messageFormat == null) {
try {
messageFormat = new MessageFormat(format);
} catch (final IllegalArgumentException e) {
ess.getLogger().log(Level.SEVERE, "Invalid Translation key for '" + string + "': " + e.getMessage());
format = format.replaceAll("\\{(\\D*?)\\}", "\\[$1\\]");
messageFormat = new MessageFormat(format);
}
messageFormatCache.put(format, messageFormat);
}
return messageFormat.format(objects).replace(' ', ' '); // replace nbsp with a space
}
public static String capitalCase(final String input)
{
return input == null || input.length() == 0
? input
: input.toUpperCase(Locale.ENGLISH).charAt(0)
+ input.toLowerCase(Locale.ENGLISH).substring(1);
}
public void updateLocale(final String loc) {
if (loc != null && !loc.isEmpty()) {
final String[] parts = loc.split("[_\\.]");
if (parts.length == 1) {
currentLocale = new Locale(parts[0]);
}
if (parts.length == 2) {
currentLocale = new Locale(parts[0], parts[1]);
}
if (parts.length == 3) {
currentLocale = new Locale(parts[0], parts[1], parts[2]);
}
}
ResourceBundle.clearCache();
messageFormatCache = new HashMap<>();
Logger.getLogger("Essentials").log(Level.INFO, String.format("Using locale %s", currentLocale.toString()));
try {
localeBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new UTF8PropertiesControl());
} catch (final MissingResourceException ex) {
localeBundle = NULL_BUNDLE;
}
private static class FileResClassLoader extends ClassLoader
{
private final transient File dataFolder;
try {
customBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new FileResClassLoader(I18n.class.getClassLoader(), ess), new UTF8PropertiesControl());
} catch (final MissingResourceException ex) {
customBundle = NULL_BUNDLE;
}
}
FileResClassLoader(final ClassLoader classLoader, final IEssentials ess)
{
super(classLoader);
this.dataFolder = ess.getDataFolder();
}
/**
* Attempts to load properties files from the plugin directory before falling back to the jar.
*/
private static class FileResClassLoader extends ClassLoader {
private final transient File dataFolder;
@Override
public URL getResource(final String string)
{
final File file = new File(dataFolder, string);
if (file.exists())
{
try
{
return file.toURI().toURL();
}
catch (MalformedURLException ex)
{
}
}
return super.getResource(string);
}
FileResClassLoader(final ClassLoader classLoader, final IEssentials ess) {
super(classLoader);
this.dataFolder = ess.getDataFolder();
}
@Override
public InputStream getResourceAsStream(final String string)
{
final File file = new File(dataFolder, string);
if (file.exists())
{
try
{
return new FileInputStream(file);
}
catch (FileNotFoundException ex)
{
}
}
return super.getResourceAsStream(string);
}
}
@Override
public URL getResource(final String string) {
final File file = new File(dataFolder, string);
if (file.exists()) {
try {
return file.toURI().toURL();
} catch (final MalformedURLException ignored) {
}
}
return null;
}
@Override
public InputStream getResourceAsStream(final String string) {
final File file = new File(dataFolder, string);
if (file.exists()) {
try {
return new FileInputStream(file);
} catch (final FileNotFoundException ignored) {
}
}
return null;
}
}
/**
* Reads .properties files as UTF-8 instead of ISO-8859-1, which is the default on Java 8/below.
* Java 9 fixes this by defaulting to UTF-8 for .properties files.
*/
private static class UTF8PropertiesControl extends ResourceBundle.Control {
public ResourceBundle newBundle(final String baseName, final Locale locale, final String format, final ClassLoader loader, final boolean reload) throws IOException {
final String resourceName = toResourceName(toBundleName(baseName, locale), "properties");
ResourceBundle bundle = null;
InputStream stream = null;
if (reload) {
final URL url = loader.getResource(resourceName);
if (url != null) {
final URLConnection connection = url.openConnection();
if (connection != null) {
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
} else {
stream = loader.getResourceAsStream(resourceName);
}
if (stream != null) {
try {
// use UTF-8 here, this is the important bit
bundle = new PropertyResourceBundle(new InputStreamReader(stream, StandardCharsets.UTF_8));
} finally {
stream.close();
}
}
return bundle;
}
}
}
@@ -1,6 +1,5 @@
package com.earth2me.essentials;
public interface IConf
{
public void reloadConfig();
public interface IConf {
void reloadConfig();
}
@@ -1,82 +1,121 @@
package com.earth2me.essentials;
import com.earth2me.essentials.api.IItemDb;
import com.earth2me.essentials.api.IJails;
import com.earth2me.essentials.api.IWarps;
import com.earth2me.essentials.metrics.Metrics;
import com.earth2me.essentials.perm.PermissionsHandler;
import com.earth2me.essentials.register.payment.Methods;
import java.util.List;
import net.ess3.provider.ContainerProvider;
import net.ess3.provider.KnownCommandsProvider;
import net.ess3.provider.ServerStateProvider;
import net.ess3.provider.SpawnerBlockProvider;
import net.ess3.provider.SpawnerItemProvider;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.function.Predicate;
public interface IEssentials extends Plugin
{
void addReloadListener(IConf listener);
public interface IEssentials extends Plugin {
void addReloadListener(IConf listener);
void reload();
void reload();
boolean onCommandEssentials(CommandSender sender, Command command, String commandLabel, String[] args, ClassLoader classLoader, String commandPath, String permissionPrefix, IEssentialsModule module);
List<String> onTabCompleteEssentials(CommandSender sender, Command command, String commandLabel, String[] args, ClassLoader classLoader, String commandPath, String permissionPrefix, IEssentialsModule module);
User getUser(Object base);
boolean onCommandEssentials(CommandSender sender, Command command, String commandLabel, String[] args, ClassLoader classLoader, String commandPath, String permissionPrefix, IEssentialsModule module);
I18n getI18n();
@Deprecated
User getUser(Object base);
User getOfflineUser(String name);
User getUser(UUID base);
World getWorld(String name);
User getUser(String base);
int broadcastMessage(String message);
User getUser(Player base);
int broadcastMessage(IUser sender, String message);
I18n getI18n();
int broadcastMessage(String permission, String message);
User getOfflineUser(String name);
ISettings getSettings();
World getWorld(String name);
BukkitScheduler getScheduler();
int broadcastMessage(String message);
IJails getJails();
int broadcastMessage(IUser sender, String message);
IWarps getWarps();
int broadcastMessage(IUser sender, String message, Predicate<IUser> shouldExclude);
Worth getWorth();
int broadcastMessage(String permission, String message);
Backup getBackup();
ISettings getSettings();
Methods getPaymentMethod();
BukkitScheduler getScheduler();
BukkitTask runTaskAsynchronously(Runnable run);
IJails getJails();
BukkitTask runTaskLaterAsynchronously(Runnable run, long delay);
IWarps getWarps();
int scheduleSyncDelayedTask(Runnable run);
Worth getWorth();
int scheduleSyncDelayedTask(Runnable run, long delay);
Backup getBackup();
int scheduleSyncRepeatingTask(final Runnable run, long delay, long period);
Kits getKits();
TNTExplodeListener getTNTListener();
RandomTeleport getRandomTeleport();
PermissionsHandler getPermissionsHandler();
BukkitTask runTaskAsynchronously(Runnable run);
AlternativeCommandsHandler getAlternativeCommandsHandler();
BukkitTask runTaskLaterAsynchronously(Runnable run, long delay);
void showError(final CommandSender sender, final Throwable exception, final String commandLabel);
BukkitTask runTaskTimerAsynchronously(Runnable run, long delay, long period);
ItemDb getItemDb();
int scheduleSyncDelayedTask(Runnable run);
UserMap getUserMap();
int scheduleSyncDelayedTask(Runnable run, long delay);
Metrics getMetrics();
int scheduleSyncRepeatingTask(Runnable run, long delay, long period);
void setMetrics(Metrics metrics);
TNTExplodeListener getTNTListener();
EssentialsTimer getTimer();
PermissionsHandler getPermissionsHandler();
List<String> getVanishedPlayers();
AlternativeCommandsHandler getAlternativeCommandsHandler();
void showError(CommandSource sender, Throwable exception, String commandLabel);
IItemDb getItemDb();
UserMap getUserMap();
EssentialsTimer getTimer();
/**
* Get a list of players who are vanished.
*
* @return A list of players who are vanished
* @deprecated Use {@link net.ess3.api.IEssentials#getVanishedPlayersNew()} where possible.
*/
@Deprecated
List<String> getVanishedPlayers();
Collection<Player> getOnlinePlayers();
Iterable<User> getOnlineUsers();
SpawnerItemProvider getSpawnerItemProvider();
SpawnerBlockProvider getSpawnerBlockProvider();
ServerStateProvider getServerStateProvider();
ContainerProvider getContainerProvider();
KnownCommandsProvider getKnownCommandsProvider();
}
@@ -1,6 +1,4 @@
package com.earth2me.essentials;
public interface IEssentialsModule
{
public interface IEssentialsModule {
}
@@ -1,18 +0,0 @@
package com.earth2me.essentials;
import org.bukkit.command.CommandSender;
public interface IReplyTo
{
/**
* Sets the user to reply to
* @param user
*/
public void setReplyTo(CommandSender user);
/**
* Gets the user the sender should reply to
* @return
*/
public CommandSender getReplyTo();
}
@@ -3,195 +3,384 @@ package com.earth2me.essentials;
import com.earth2me.essentials.commands.IEssentialsCommand;
import com.earth2me.essentials.signs.EssentialsSign;
import com.earth2me.essentials.textreader.IText;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.EventPriority;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
public interface ISettings extends IConf
{
boolean areSignsDisabled();
public interface ISettings extends IConf {
boolean areSignsDisabled();
IText getAnnounceNewPlayerFormat();
IText getAnnounceNewPlayerFormat();
boolean getAnnounceNewPlayers();
boolean getAnnounceNewPlayers();
String getNewPlayerKit();
String getNewPlayerKit();
String getBackupCommand();
String getBackupCommand();
long getBackupInterval();
long getBackupInterval();
MessageFormat getChatFormat(String group);
boolean isAlwaysRunBackup();
int getChatRadius();
String getChatFormat(String group);
BigDecimal getCommandCost(IEssentialsCommand cmd);
int getChatRadius();
BigDecimal getCommandCost(String label);
int getNearRadius();
String getCurrencySymbol();
char getChatShout();
int getOversizedStackSize();
char getChatQuestion();
int getDefaultStackSize();
BigDecimal getCommandCost(IEssentialsCommand cmd);
double getHealCooldown();
BigDecimal getCommandCost(String label);
Set<String> getSocialSpyCommands();
String getCurrencySymbol();
Map<String, Object> getKit(String name);
boolean isCurrencySymbolSuffixed();
ConfigurationSection getKits();
int getOversizedStackSize();
String getLocale();
int getDefaultStackSize();
String getNewbieSpawn();
double getHealCooldown();
String getNicknamePrefix();
Set<String> getSocialSpyCommands();
ChatColor getOperatorColor() throws Exception;
boolean getSocialSpyListenMutedPlayers();
boolean getPerWarpPermission();
Set<String> getMuteCommands();
boolean getProtectBoolean(final String configName, boolean def);
/**
* @Deprecated in favor of {@link Kits#getKits()}
*/
@Deprecated
ConfigurationSection getKits();
int getProtectCreeperMaxHeight();
/**
* @Deprecated in favor of {@link Kits#getKit(String)}
*/
@Deprecated
Map<String, Object> getKit(String kit);
List<Integer> getProtectList(final String configName);
/**
* @Deprecated in favor of {@link Kits#addKit(String, List, long)}}
*/
@Deprecated
void addKit(String name, List<String> lines, long delay);
boolean getProtectPreventSpawn(final String creatureName);
@Deprecated
ConfigurationSection getKitSection();
String getProtectString(final String configName);
boolean isSkippingUsedOneTimeKitsFromKitList();
boolean getRespawnAtHome();
String getLocale();
Set getMultipleHomes();
String getNewbieSpawn();
int getHomeLimit(String set);
String getNicknamePrefix();
int getHomeLimit(User user);
String getOperatorColor() throws Exception;
int getSpawnMobLimit();
boolean getPerWarpPermission();
BigDecimal getStartingBalance();
boolean getProtectBoolean(final String configName, boolean def);
double getTeleportCooldown();
int getProtectCreeperMaxHeight();
double getTeleportDelay();
List<Material> getProtectList(final String configName);
boolean hidePermissionlessHelp();
boolean getProtectPreventSpawn(final String creatureName);
boolean isCommandDisabled(final IEssentialsCommand cmd);
String getProtectString(final String configName);
boolean isCommandDisabled(String label);
boolean getRespawnAtHome();
boolean isCommandOverridden(String name);
boolean isRespawnAtAnchor();
boolean isDebug();
Set getMultipleHomes();
boolean isEcoDisabled();
int getHomeLimit(String set);
boolean isTradeInStacks(int id);
int getHomeLimit(User user);
List<Integer> itemSpawnBlacklist();
int getSpawnMobLimit();
List<EssentialsSign> enabledSigns();
BigDecimal getStartingBalance();
boolean permissionBasedItemSpawn();
boolean isTeleportSafetyEnabled();
boolean showNonEssCommandsInHelp();
boolean isForceDisableTeleportSafety();
boolean warnOnBuildDisallow();
boolean isAlwaysTeleportSafety();
boolean warnOnSmite();
boolean isTeleportPassengerDismount();
BigDecimal getMaxMoney();
boolean isForcePassengerTeleport();
BigDecimal getMinMoney();
double getTeleportCooldown();
boolean isEcoLogEnabled();
double getTeleportDelay();
boolean isEcoLogUpdateEnabled();
boolean hidePermissionlessHelp();
boolean removeGodOnDisconnect();
boolean isCommandDisabled(final IEssentialsCommand cmd);
boolean changeDisplayName();
boolean isCommandDisabled(String label);
boolean changePlayerListName();
boolean isCommandOverridden(String name);
boolean isPlayerCommand(String string);
boolean isDebug();
boolean useBukkitPermissions();
void setDebug(boolean debug);
boolean addPrefixSuffix();
boolean isEcoDisabled();
boolean disablePrefix();
@Deprecated
boolean isTradeInStacks(int id);
boolean disableSuffix();
boolean isTradeInStacks(Material type);
long getAutoAfk();
List<Material> itemSpawnBlacklist();
long getAutoAfkKick();
List<EssentialsSign> enabledSigns();
boolean getFreezeAfkPlayers();
boolean permissionBasedItemSpawn();
boolean cancelAfkOnMove();
boolean showNonEssCommandsInHelp();
boolean cancelAfkOnInteract();
boolean warnOnBuildDisallow();
boolean areDeathMessagesEnabled();
boolean warnOnSmite();
public void setDebug(boolean debug);
BigDecimal getMaxMoney();
Set<String> getNoGodWorlds();
BigDecimal getMinMoney();
boolean getUpdateBedAtDaytime();
boolean isEcoLogEnabled();
boolean allowUnsafeEnchantments();
boolean isEcoLogUpdateEnabled();
boolean getRepairEnchanted();
boolean realNamesOnList();
boolean isWorldTeleportPermissions();
boolean removeGodOnDisconnect();
boolean isWorldHomePermissions();
boolean changeDisplayName();
boolean registerBackInListener();
boolean changePlayerListName();
boolean getDisableItemPickupWhileAfk();
boolean isPlayerCommand(String string);
EventPriority getRespawnPriority();
boolean useBukkitPermissions();
long getTpaAcceptCancellation();
boolean addPrefixSuffix();
boolean isMetricsEnabled();
boolean disablePrefix();
void setMetricsEnabled(boolean metricsEnabled);
boolean disableSuffix();
long getTeleportInvulnerability();
long getAutoAfk();
boolean isTeleportInvulnerability();
long getAutoAfkKick();
long getLoginAttackDelay();
boolean getFreezeAfkPlayers();
int getSignUsePerSecond();
boolean cancelAfkOnMove();
double getMaxFlySpeed();
boolean cancelAfkOnInteract();
double getMaxWalkSpeed();
boolean sleepIgnoresAfkPlayers();
public int getMailsPerMinute();
boolean isAfkListName();
public long getEconomyLagWarning();
String getAfkListName();
public void setEssentialsChatActive(boolean b);
boolean broadcastAfkMessage();
long getMaxTempban();
boolean areDeathMessagesEnabled();
KeepInvPolicy getVanishingItemsPolicy();
KeepInvPolicy getBindingItemsPolicy();
int getJoinQuitMessagePlayerCount();
boolean hasJoinQuitMessagePlayerCount();
Set<String> getNoGodWorlds();
boolean getUpdateBedAtDaytime();
boolean allowUnsafeEnchantments();
boolean getRepairEnchanted();
boolean isWorldTeleportPermissions();
boolean isWorldHomePermissions();
boolean registerBackInListener();
boolean getDisableItemPickupWhileAfk();
EventPriority getRespawnPriority();
EventPriority getSpawnJoinPriority();
long getTpaAcceptCancellation();
long getTeleportInvulnerability();
boolean isTeleportInvulnerability();
long getLoginAttackDelay();
int getSignUsePerSecond();
double getMaxFlySpeed();
double getMaxWalkSpeed();
int getMailsPerMinute();
long getEconomyLagWarning();
long getPermissionsLagWarning();
void setEssentialsChatActive(boolean b);
long getMaxMute();
long getMaxTempban();
Map<String, Object> getListGroupConfig();
int getMaxNickLength();
boolean ignoreColorsInMaxLength();
boolean hideDisplayNameInVanish();
int getMaxUserCacheCount();
boolean allowSilentJoinQuit();
boolean isCustomJoinMessage();
String getCustomJoinMessage();
boolean isCustomQuitMessage();
String getCustomQuitMessage();
boolean isNotifyNoNewMail();
boolean isDropItemsIfFull();
boolean isLastMessageReplyRecipient();
boolean isReplyToVanished();
BigDecimal getMinimumPayAmount();
boolean isPayExcludesIgnoreList();
long getLastMessageReplyRecipientTimeout();
boolean isMilkBucketEasterEggEnabled();
boolean isSendFlyEnableOnJoin();
boolean isWorldTimePermissions();
boolean isSpawnOnJoin();
List<String> getSpawnOnJoinGroups();
boolean isUserInSpawnOnJoinGroup(IUser user);
boolean isTeleportToCenterLocation();
boolean isCommandCooldownsEnabled();
boolean isWorldChangeFlyResetEnabled();
boolean isWorldChangeSpeedResetEnabled();
long getCommandCooldownMs(String label);
Entry<Pattern, Long> getCommandCooldownEntry(String label);
boolean isCommandCooldownPersistent(String label);
boolean isNpcsInBalanceRanking();
NumberFormat getCurrencyFormat();
List<EssentialsSign> getUnprotectedSignNames();
boolean isPastebinCreateKit();
boolean isAllowBulkBuySell();
boolean isAllowSellNamedItems();
boolean isAddingPrefixInPlayerlist();
boolean isAddingSuffixInPlayerlist();
int getNotifyPlayerOfMailCooldown();
int getMotdDelay();
boolean isDirectHatAllowed();
List<String> getDefaultEnabledConfirmCommands();
boolean isConfirmCommandEnabledByDefault(String commandName);
boolean isTeleportBackWhenFreedFromJail();
boolean isCompassTowardsHomePerm();
boolean isAllowWorldInBroadcastworld();
String getItemDbType();
boolean allowOldIdSigns();
boolean isWaterSafe();
boolean isSafeUsermap();
boolean logCommandBlockCommands();
Set<Predicate<String>> getNickBlacklist();
double getMaxProjectileSpeed();
boolean isRemovingEffectsOnHeal();
boolean isSpawnIfNoHome();
boolean isConfirmHomeOverwrite();
boolean infoAfterDeath();
enum KeepInvPolicy {
KEEP,
DELETE,
DROP
}
public Map<String, Object> getListGroupConfig();
}
@@ -2,8 +2,6 @@ package com.earth2me.essentials;
import org.bukkit.Location;
public interface ITarget
{
public Location getLocation();
}
public interface ITarget {
Location getLocation();
}
+176 -51
View File
@@ -1,88 +1,213 @@
package com.earth2me.essentials;
import com.earth2me.essentials.api.ITeleport;
import com.earth2me.essentials.api.IAsyncTeleport;
import com.earth2me.essentials.commands.IEssentialsCommand;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Set;
import net.ess3.api.ITeleport;
import net.ess3.api.MaxMoneyException;
import net.ess3.api.events.AfkStatusChangeEvent;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
public interface IUser extends Player
{
long getLastTeleportTimestamp();
/**
* Provides access to the user abstraction and stored data. Maintainers should add methods to <i>this interface</i>.
*
* @deprecated External plugins should use {@link net.ess3.api.IUser} instead of this interface, in case future APIs are added.
*/
@Deprecated
public interface IUser {
boolean isAuthorized(String node);
boolean isAuthorized(String node);
boolean isAuthorized(IEssentialsCommand cmd);
boolean isAuthorized(IEssentialsCommand cmd);
boolean isAuthorized(IEssentialsCommand cmd, String permissionPrefix);
boolean isAuthorized(IEssentialsCommand cmd, String permissionPrefix);
boolean isPermissionSet(String node);
void setLastTeleportTimestamp(long time);
void healCooldown() throws Exception;
Location getLastLocation();
void giveMoney(BigDecimal value) throws MaxMoneyException;
Player getBase();
void giveMoney(final BigDecimal value, final CommandSource initiator) throws MaxMoneyException;
BigDecimal getMoney();
void payUser(final User reciever, final BigDecimal value) throws Exception;
void takeMoney(BigDecimal value);
void takeMoney(BigDecimal value);
void giveMoney(BigDecimal value);
void takeMoney(final BigDecimal value, final CommandSource initiator);
boolean canAfford(BigDecimal value);
boolean canAfford(BigDecimal value);
String getGroup();
Boolean canSpawnItem(final Material material);
void setLastLocation();
void setLastLocation();
Location getHome(String name) throws Exception;
void setLogoutLocation();
Location getHome(Location loc) throws Exception;
void requestTeleport(final User player, final boolean here);
/**
* 'Hidden' Represents when a player is hidden from others. This status includes when the player is hidden via other
* supported plugins. Use isVanished() if you want to check if a user is vanished by Essentials.
*
* @return If the user is hidden or not
* @see isVanished
*/
boolean isHidden();
/**
* Returns whether this user has an outstanding teleport request to deal with.
*
* @return whether there is a teleport request
*/
boolean hasOutstandingTeleportRequest();
void setHidden(boolean vanish);
/**
* @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.api.IAsyncTeleport IAsyncTeleport} with {@link IUser#getAsyncTeleport()}
*/
@Deprecated
ITeleport getTeleport();
/**
* 'Vanished' Represents when a player is hidden from others by Essentials. This status does NOT include when the
* player is hidden via other plugins. Use isHidden() if you want to check if a user is vanished by any supported
* plugin.
*
* @return If the user is vanished or not
* @see isHidden
*/
boolean isVanished();
IAsyncTeleport getAsyncTeleport();
void setVanished(boolean vanish);
BigDecimal getMoney();
ITeleport getTeleport();
void setMoney(final BigDecimal value) throws MaxMoneyException;
void setJail(String jail);
void setAfk(final boolean set, final AfkStatusChangeEvent.Cause cause);
boolean isIgnoreExempt();
/**
* 'Hidden' Represents when a player is hidden from others. This status includes when the player is hidden via other
* supported plugins. Use isVanished() if you want to check if a user is vanished by Essentials.
*
* @return If the user is hidden or not
* @see IUser#isVanished()
*/
boolean isHidden();
boolean isAfk();
void setHidden(boolean vanish);
void setAfk(final boolean set);
boolean isGodModeEnabled();
void setLogoutLocation();
String getGroup();
Location getLogoutLocation();
boolean inGroup(final String group);
void setConfigProperty(String node, Object object);
boolean canBuild();
Set<String> getConfigKeys();
long getTeleportRequestTime();
Map<String, Object> getConfigMap();
void enableInvulnerabilityAfterTeleport();
Map<String, Object> getConfigMap(String node);
void resetInvulnerabilityAfterTeleport();
boolean hasInvulnerabilityAfterTeleport();
/**
* 'Vanished' Represents when a player is hidden from others by Essentials. This status does NOT include when the
* player is hidden via other plugins. Use isHidden() if you want to check if a user is vanished by any supported
* plugin.
*
* @return If the user is vanished or not
* @see IUser#isHidden()
*/
boolean isVanished();
void setVanished(boolean vanish);
boolean isIgnoreExempt();
void sendMessage(String message);
/*
* UserData
*/
Location getHome(String name) throws Exception;
Location getHome(Location loc) throws Exception;
List<String> getHomes();
void setHome(String name, Location loc);
void delHome(String name) throws Exception;
boolean hasHome();
Location getLastLocation();
Location getLogoutLocation();
long getLastTeleportTimestamp();
void setLastTeleportTimestamp(long time);
String getJail();
void setJail(String jail);
List<String> getMails();
void addMail(String mail);
boolean isAfk();
@Deprecated
void setAfk(final boolean set);
boolean isIgnoreMsg();
void setIgnoreMsg(boolean ignoreMsg);
void setConfigProperty(String node, Object object);
Set<String> getConfigKeys();
Map<String, Object> getConfigMap();
Map<String, Object> getConfigMap(String node);
Map<Pattern, Long> getCommandCooldowns();
Date getCommandCooldownExpiry(String label);
void addCommandCooldown(Pattern pattern, Date expiresAt, boolean save);
boolean clearCommandCooldown(Pattern pattern);
/*
* PlayerExtension
*/
Player getBase();
CommandSource getSource();
String getName();
String getDisplayName();
String getAfkMessage();
void setAfkMessage(final String message);
long getAfkSince();
boolean isAcceptingPay();
void setAcceptingPay(boolean acceptingPay);
boolean isPromptingPayConfirm();
void setPromptingPayConfirm(boolean prompt);
boolean isPromptingClearConfirm();
void setPromptingClearConfirm(boolean prompt);
boolean isLastMessageReplyRecipient();
void setLastMessageReplyRecipient(boolean enabled);
Map<User, BigDecimal> getConfirmingPayments();
Block getTargetBlock(int maxDistance);
}
@@ -1,225 +0,0 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.StringUtil;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.api.IItemDb;
import com.earth2me.essentials.utils.NumberUtil;
import java.util.*;
import java.util.regex.Pattern;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
public class ItemDb implements IConf, IItemDb
{
private final transient IEssentials ess;
public ItemDb(final IEssentials ess)
{
this.ess = ess;
file = new ManagedFile("items.csv", ess);
}
private final transient Map<String, Integer> items = new HashMap<String, Integer>();
private final transient Map<ItemData, List<String>> names = new HashMap<ItemData, List<String>>();
private final transient Map<String, Short> durabilities = new HashMap<String, Short>();
private final transient ManagedFile file;
private final transient Pattern splitPattern = Pattern.compile("[:+',;.]");
@Override
public void reloadConfig()
{
final List<String> lines = file.getLines();
if (lines.isEmpty())
{
return;
}
durabilities.clear();
items.clear();
names.clear();
for (String line : lines)
{
line = line.trim().toLowerCase(Locale.ENGLISH);
if (line.length() > 0 && line.charAt(0) == '#')
{
continue;
}
final String[] parts = line.split("[^a-z0-9]");
if (parts.length < 2)
{
continue;
}
final int numeric = Integer.parseInt(parts[1]);
final short data = parts.length > 2 && !parts[2].equals("0") ? Short.parseShort(parts[2]) : 0;
String itemName = parts[0].toLowerCase(Locale.ENGLISH);
durabilities.put(itemName, data);
items.put(itemName, numeric);
ItemData itemData = new ItemData(numeric, data);
if (names.containsKey(itemData))
{
List<String> nameList = names.get(itemData);
nameList.add(itemName);
Collections.sort(nameList, new LengthCompare());
}
else
{
List<String> nameList = new ArrayList<String>();
nameList.add(itemName);
names.put(itemData, nameList);
}
}
}
@Override
public ItemStack get(final String id, final int quantity) throws Exception
{
final ItemStack retval = get(id.toLowerCase(Locale.ENGLISH));
retval.setAmount(quantity);
return retval;
}
@Override
public ItemStack get(final String id) throws Exception
{
int itemid = 0;
String itemname = null;
short metaData = 0;
String[] parts = splitPattern.split(id);
if (id.matches("^\\d+[:+',;.]\\d+$"))
{
itemid = Integer.parseInt(parts[0]);
metaData = Short.parseShort(parts[1]);
}
else if (NumberUtil.isInt(id))
{
itemid = Integer.parseInt(id);
}
else if (id.matches("^[^:+',;.]+[:+',;.]\\d+$"))
{
itemname = parts[0].toLowerCase(Locale.ENGLISH);
metaData = Short.parseShort(parts[1]);
}
else
{
itemname = id.toLowerCase(Locale.ENGLISH);
}
if (itemname != null)
{
if (items.containsKey(itemname))
{
itemid = items.get(itemname);
if (durabilities.containsKey(itemname) && metaData == 0)
{
metaData = durabilities.get(itemname);
}
}
else if (Material.getMaterial(itemname.toUpperCase(Locale.ENGLISH)) != null)
{
itemid = Material.getMaterial(itemname.toUpperCase(Locale.ENGLISH)).getId();
metaData = 0;
}
else
{
throw new Exception(_("unknownItemName", id));
}
}
final Material mat = Material.getMaterial(itemid);
if (mat == null)
{
throw new Exception(_("unknownItemId", itemid));
}
final ItemStack retval = new ItemStack(mat);
retval.setAmount(mat.getMaxStackSize());
retval.setDurability(metaData);
return retval;
}
public String names(ItemStack item)
{
ItemData itemData = new ItemData(item.getTypeId(), item.getDurability());
List<String> nameList = names.get(itemData);
if (nameList == null)
{
itemData = new ItemData(item.getTypeId(), (short)0);
nameList = names.get(itemData);
if (nameList == null)
{
return null;
}
}
if (nameList.size() > 15)
{
nameList = nameList.subList(0, 14);
}
return StringUtil.joinList(", ", nameList);
}
static class ItemData
{
final private int itemNo;
final private short itemData;
ItemData(final int itemNo, final short itemData)
{
this.itemNo = itemNo;
this.itemData = itemData;
}
public int getItemNo()
{
return itemNo;
}
public short getItemData()
{
return itemData;
}
@Override
public int hashCode()
{
return (31 * itemNo) ^ itemData;
}
@Override
public boolean equals(Object o)
{
if (o == null)
{
return false;
}
if (!(o instanceof ItemData))
{
return false;
}
ItemData pairo = (ItemData)o;
return this.itemNo == pairo.getItemNo()
&& this.itemData == pairo.getItemData();
}
}
class LengthCompare implements java.util.Comparator<String>
{
public LengthCompare()
{
super();
}
@Override
public int compare(String s1, String s2)
{
return s1.length() - s2.length();
}
}
}
+253 -289
View File
@@ -1,16 +1,13 @@
package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.api.IJails;
import com.earth2me.essentials.storage.AsyncStorageObjectHolder;
import java.io.File;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@@ -19,6 +16,7 @@ import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
@@ -26,313 +24,279 @@ import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.plugin.PluginManager;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.settings.Jails> implements IJails
{
private static final transient Logger LOGGER = Bukkit.getLogger();
private static transient boolean enabled = false;
import static com.earth2me.essentials.I18n.tl;
public Jails(final IEssentials ess)
{
super(ess, com.earth2me.essentials.settings.Jails.class);
reloadConfig();
}
public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.settings.Jails> implements net.ess3.api.IJails {
private static final transient Logger LOGGER = Bukkit.getLogger();
private static transient boolean enabled = false;
private void registerListeners()
{
enabled = true;
final PluginManager pluginManager = ess.getServer().getPluginManager();
final JailListener blockListener = new JailListener();
pluginManager.registerEvents(blockListener, ess);
if (ess.getSettings().isDebug())
{
LOGGER.log(Level.INFO, "Registering Jail listener");
}
}
public Jails(final IEssentials ess) {
super(ess, com.earth2me.essentials.settings.Jails.class);
reloadConfig();
}
@Override
public File getStorageFile()
{
return new File(ess.getDataFolder(), "jail.yml");
}
private void registerListeners() {
enabled = true;
final PluginManager pluginManager = ess.getServer().getPluginManager();
final JailListener blockListener = new JailListener();
pluginManager.registerEvents(blockListener, ess);
if (ess.getSettings().isDebug()) {
LOGGER.log(Level.INFO, "Registering Jail listener");
}
}
@Override
public void finishRead()
{
checkRegister();
}
@Override
public File getStorageFile() {
return new File(ess.getDataFolder(), "jail.yml");
}
@Override
public void finishWrite()
{
checkRegister();
}
@Override
public void finishRead() {
checkRegister();
}
public void resetListener()
{
enabled = false;
checkRegister();
}
@Override
public void finishWrite() {
checkRegister();
}
private void checkRegister()
{
if (enabled == false && getCount() > 0)
{
registerListeners();
}
}
public void resetListener() {
enabled = false;
checkRegister();
}
@Override
public Location getJail(final String jailName) throws Exception
{
acquireReadLock();
try
{
if (getData().getJails() == null || jailName == null
|| !getData().getJails().containsKey(jailName.toLowerCase(Locale.ENGLISH)))
{
throw new Exception(_("jailNotExist"));
}
Location loc = getData().getJails().get(jailName.toLowerCase(Locale.ENGLISH));
if (loc == null || loc.getWorld() == null)
{
throw new Exception(_("jailNotExist"));
}
return loc;
}
finally
{
unlock();
}
}
private void checkRegister() {
if (!enabled && getCount() > 0) {
registerListeners();
}
}
@Override
public Collection<String> getList() throws Exception
{
acquireReadLock();
try
{
if (getData().getJails() == null)
{
return Collections.emptyList();
}
return new ArrayList<String>(getData().getJails().keySet());
}
finally
{
unlock();
}
}
@Override
public Location getJail(final String jailName) throws Exception {
acquireReadLock();
try {
if (getData().getJails() == null || jailName == null || !getData().getJails().containsKey(jailName.toLowerCase(Locale.ENGLISH))) {
throw new Exception(tl("jailNotExist"));
}
final Location loc = getData().getJails().get(jailName.toLowerCase(Locale.ENGLISH));
if (loc == null || loc.getWorld() == null) {
throw new Exception(tl("jailNotExist"));
}
return loc;
} finally {
unlock();
}
}
@Override
public void removeJail(final String jail) throws Exception
{
acquireWriteLock();
try
{
if (getData().getJails() == null)
{
return;
}
getData().getJails().remove(jail.toLowerCase(Locale.ENGLISH));
}
finally
{
unlock();
}
}
@Override
public Collection<String> getList() throws Exception {
acquireReadLock();
try {
if (getData().getJails() == null) {
return Collections.emptyList();
}
return new ArrayList<>(getData().getJails().keySet());
} finally {
unlock();
}
}
@Override
public void sendToJail(final IUser user, final String jail) throws Exception
{
acquireReadLock();
try
{
if (user.isOnline())
{
Location loc = getJail(jail);
user.getTeleport().now(loc, false, TeleportCause.COMMAND);
}
user.setJail(jail);
}
finally
{
unlock();
}
}
@Override
public void removeJail(final String jail) throws Exception {
acquireWriteLock();
try {
if (getData().getJails() == null) {
return;
}
getData().getJails().remove(jail.toLowerCase(Locale.ENGLISH));
} finally {
unlock();
}
}
@Override
public void setJail(final String jailName, final Location loc) throws Exception
{
acquireWriteLock();
try
{
if (getData().getJails() == null)
{
getData().setJails(new HashMap<String, Location>());
}
getData().getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc);
}
finally
{
unlock();
}
}
/**
* @deprecated This method does not use asynchronous teleportation. Use {@link Jails#sendToJail(IUser, String, CompletableFuture)}
*/
@Override
@Deprecated
public void sendToJail(final IUser user, final String jail) throws Exception {
acquireReadLock();
try {
if (user.getBase().isOnline()) {
final Location loc = getJail(jail);
user.getTeleport().now(loc, false, TeleportCause.COMMAND);
}
user.setJail(jail);
} finally {
unlock();
}
}
@Override
public int getCount()
{
try
{
return getList().size();
}
catch (Exception ex)
{
return 0;
}
}
@Override
public void sendToJail(final IUser user, final String jail, final CompletableFuture<Boolean> future) throws Exception {
acquireReadLock();
try {
if (user.getBase().isOnline()) {
final Location loc = getJail(jail);
user.getAsyncTeleport().now(loc, false, TeleportCause.COMMAND, future);
future.thenAccept(success -> user.setJail(jail));
return;
}
user.setJail(jail);
} finally {
unlock();
}
}
@Override
public void setJail(final String jailName, final Location loc) throws Exception {
acquireWriteLock();
try {
if (getData().getJails() == null) {
getData().setJails(new HashMap<>());
}
getData().getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc);
} finally {
unlock();
}
}
private class JailListener implements Listener
{
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockBreak(final BlockBreakEvent event)
{
final User user = ess.getUser(event.getPlayer());
if (user.isJailed())
{
event.setCancelled(true);
}
}
@Override
public int getCount() {
try {
return getList().size();
} catch (final Exception ex) {
return 0;
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockPlace(final BlockPlaceEvent event)
{
final User user = ess.getUser(event.getPlayer());
if (user.isJailed())
{
event.setCancelled(true);
}
}
private class JailListener implements Listener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onJailBlockBreak(final BlockBreakEvent event) {
final User user = ess.getUser(event.getPlayer());
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-break")) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockDamage(final BlockDamageEvent event)
{
final User user = ess.getUser(event.getPlayer());
if (user.isJailed())
{
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onJailBlockPlace(final BlockPlaceEvent event) {
final User user = ess.getUser(event.getPlayer());
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-place")) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityDamageByEntity(final EntityDamageByEntityEvent event)
{
if (event.getCause() != DamageCause.ENTITY_ATTACK || event.getEntity().getType() != EntityType.PLAYER)
{
return;
}
final Entity damager = event.getDamager();
if (damager.getType() == EntityType.PLAYER)
{
final User user = ess.getUser(damager);
if (user != null && user.isJailed())
{
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onJailBlockDamage(final BlockDamageEvent event) {
final User user = ess.getUser(event.getPlayer());
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-block-damage")) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerInteract(final PlayerInteractEvent event)
{
final User user = ess.getUser(event.getPlayer());
if (user.isJailed())
{
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onJailEntityDamageByEntity(final EntityDamageByEntityEvent event) {
if (event.getCause() != DamageCause.ENTITY_ATTACK || event.getEntity().getType() != EntityType.PLAYER) {
return;
}
final Entity damager = event.getDamager();
if (damager.getType() == EntityType.PLAYER) {
final User user = ess.getUser((Player) damager);
if (user != null && user.isJailed()) {
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerRespawn(final PlayerRespawnEvent event)
{
final User user = ess.getUser(event.getPlayer());
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty())
{
return;
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onJailPlayerInteract(final PlayerInteractEvent event) {
final User user = ess.getUser(event.getPlayer());
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-interact")) {
event.setCancelled(true);
}
}
try
{
event.setRespawnLocation(getJail(user.getJail()));
}
catch (Exception ex)
{
if (ess.getSettings().isDebug())
{
LOGGER.log(Level.INFO, _("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
}
else
{
LOGGER.log(Level.INFO, _("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onJailPlayerGameModeChange(final PlayerGameModeChangeEvent event) {
final User user = ess.getUser(event.getPlayer());
if (user.isJailed()) {
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerTeleport(final PlayerTeleportEvent event)
{
final User user = ess.getUser(event.getPlayer());
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty())
{
return;
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onJailPlayerRespawn(final PlayerRespawnEvent event) {
final User user = ess.getUser(event.getPlayer());
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
return;
}
try
{
event.setTo(getJail(user.getJail()));
}
catch (Exception ex)
{
if (ess.getSettings().isDebug())
{
LOGGER.log(Level.INFO, _("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
}
else
{
LOGGER.log(Level.INFO, _("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
}
}
user.sendMessage(_("jailMessage"));
}
try {
event.setRespawnLocation(getJail(user.getJail()));
} catch (final Exception ex) {
if (ess.getSettings().isDebug()) {
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
} else {
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerJoin(final PlayerJoinEvent event)
{
final User user = ess.getUser(event.getPlayer());
final long currentTime = System.currentTimeMillis();
user.checkJailTimeout(currentTime);
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty())
{
return;
}
@EventHandler(priority = EventPriority.HIGH)
public void onJailPlayerTeleport(final PlayerTeleportEvent event) {
final User user = ess.getUser(event.getPlayer());
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
return;
}
try
{
sendToJail(user, user.getJail());
}
catch (Exception ex)
{
if (ess.getSettings().isDebug())
{
LOGGER.log(Level.INFO, _("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
}
else
{
LOGGER.log(Level.INFO, _("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
}
}
user.sendMessage(_("jailMessage"));
}
}
try {
event.setTo(getJail(user.getJail()));
} catch (final Exception ex) {
if (ess.getSettings().isDebug()) {
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
} else {
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
}
}
user.sendMessage(tl("jailMessage"));
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onJailPlayerJoin(final PlayerJoinEvent event) {
final User user = ess.getUser(event.getPlayer());
final long currentTime = System.currentTimeMillis();
user.checkJailTimeout(currentTime);
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
return;
}
final CompletableFuture<Boolean> future = new CompletableFuture<>();
future.exceptionally(ex -> {
if (ess.getSettings().isDebug()) {
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
} else {
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
}
return false;
});
future.thenAccept(success -> user.sendMessage(tl("jailMessage")));
try {
sendToJail(user, user.getJail(), future);
} catch (final Exception ex) {
future.completeExceptionally(ex);
}
}
}
}
+226 -194
View File
@@ -1,224 +1,256 @@
package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._;
import static com.earth2me.essentials.I18n.capitalCase;
import com.earth2me.essentials.Trade.OverflowType;
import com.earth2me.essentials.commands.NoChargeException;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import com.earth2me.essentials.textreader.IText;
import com.earth2me.essentials.textreader.KeywordReplacer;
import com.earth2me.essentials.textreader.SimpleTextInput;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.DateUtil;
import java.math.BigDecimal;
import java.util.*;
import java.util.logging.Level;
import org.bukkit.configuration.ConfigurationSection;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials;
import net.ess3.api.events.KitClaimEvent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
public class Kit
{
//TODO: Convert this to use one of the new text classes?
public static String listKits(final IEssentials ess, final User user) throws Exception
{
try
{
final ConfigurationSection kits = ess.getSettings().getKits();
final StringBuilder list = new StringBuilder();
for (String kitItem : kits.getKeys(false))
{
if (user == null)
{
list.append(" ").append(capitalCase(kitItem));
}
else if (user.isAuthorized("essentials.kits." + kitItem.toLowerCase(Locale.ENGLISH)))
{
String cost = "";
String name = capitalCase(kitItem);
BigDecimal costPrice = new Trade("kit-" + kitItem.toLowerCase(Locale.ENGLISH), ess).getCommandCost(user);
if (costPrice.signum() > 0)
{
cost = _("kitCost", NumberUtil.displayCurrency(costPrice, ess));
}
final Map<String, Object> kit = ess.getSettings().getKit(kitItem);
import static com.earth2me.essentials.I18n.tl;
if (Kit.getNextUse(user, kitItem, kit) != 0)
{
name = _("kitDelay", name);
}
public class Kit {
final IEssentials ess;
final String kitName;
final Map<String, Object> kit;
final Trade charge;
list.append(" ").append(name).append(cost);
}
}
return list.toString().trim();
}
catch (Exception ex)
{
throw new Exception(_("kitError"), ex);
}
public Kit(final String kitName, final IEssentials ess) throws Exception {
this.kitName = kitName;
this.ess = ess;
this.kit = ess.getKits().getKit(kitName);
this.charge = new Trade("kit-" + kitName, new Trade("kit-kit", ess), ess);
}
if (kit == null) {
throw new Exception(tl("kitNotFound"));
}
}
public static void checkTime(final User user, final String kitName, final Map<String, Object> els) throws Exception
{
final Calendar time = new GregorianCalendar();
long nextUse = getNextUse(user, kitName, els);
public String getName() {
return kitName;
}
if (nextUse == 0L)
{
user.setKitTimestamp(kitName, time.getTimeInMillis());
}
else if (nextUse < 0L)
{
user.sendMessage(_("kitOnce"));
throw new NoChargeException();
}
else
{
user.sendMessage(_("kitTimed", DateUtil.formatDateDiff(nextUse)));
throw new NoChargeException();
}
}
public void checkPerms(final User user) throws Exception {
if (!user.isAuthorized("essentials.kits." + kitName)) {
throw new Exception(tl("noKitPermission", "essentials.kits." + kitName));
}
}
public static long getNextUse(final User user, final String kitName, final Map<String, Object> els) throws Exception
{
if (user.isAuthorized("essentials.kit.exemptdelay"))
{
return 0L;
}
public void checkDelay(final User user) throws Exception {
final long nextUse = getNextUse(user);
final Calendar time = new GregorianCalendar();
if (nextUse == 0L) {
} else if (nextUse < 0L) {
user.sendMessage(tl("kitOnce"));
throw new NoChargeException();
} else {
user.sendMessage(tl("kitTimed", DateUtil.formatDateDiff(nextUse)));
throw new NoChargeException();
}
}
double delay = 0;
try
{
// Make sure delay is valid
delay = els.containsKey("delay") ? ((Number)els.get("delay")).doubleValue() : 0.0d;
}
catch (Exception e)
{
throw new Exception(_("kitError2"));
}
public void checkAffordable(final User user) throws Exception {
charge.isAffordableFor(user);
}
// When was the last kit used?
final long lastTime = user.getKitTimestamp(kitName);
public void setTime(final User user) throws Exception {
final Calendar time = new GregorianCalendar();
user.setKitTimestamp(kitName, time.getTimeInMillis());
}
// When can be use the kit again?
final Calendar delayTime = new GregorianCalendar();
delayTime.setTimeInMillis(lastTime);
delayTime.add(Calendar.SECOND, (int)delay);
delayTime.add(Calendar.MILLISECOND, (int)((delay * 1000.0) % 1000.0));
public void chargeUser(final User user) throws Exception {
charge.charge(user);
}
if (lastTime == 0L || lastTime > time.getTimeInMillis())
{
// If we have no record of kit use, or its corrupted, give them benifit of the doubt.
return 0L;
}
else if (delay < 0d)
{
// If the kit has a negative kit time, it can only be used once.
return -1;
}
else if (delayTime.before(time))
{
// If the kit was used in the past, but outside the delay time, it can be used.
return 0L;
}
else
{
// If the kit has been used recently, return the next time it can be used.
return delayTime.getTimeInMillis();
}
}
public long getNextUse(final User user) throws Exception {
if (user.isAuthorized("essentials.kit.exemptdelay")) {
return 0L;
}
public static List<String> getItems(final IEssentials ess, final User user, final Map<String, Object> kit) throws Exception
{
if (kit == null)
{
throw new Exception(_("kitNotFound"));
}
try
{
final List<String> itemList = new ArrayList<String>();
final Object kitItems = kit.get("items");
if (kitItems instanceof List)
{
for (Object item : (List)kitItems)
{
if (item instanceof String)
{
itemList.add(item.toString());
continue;
}
throw new Exception("Error parsing kit item: " + item.toString());
}
return itemList;
}
throw new Exception("Error parsing kit: " + kitItems.toString());
}
catch (Exception e)
{
ess.getLogger().log(Level.WARNING, e.getMessage());
throw new Exception(_("kitError2"), e);
}
}
final Calendar time = new GregorianCalendar();
public static void expandItems(final IEssentials ess, final User user, final List<String> items) throws Exception
{
try
{
IText input = new SimpleTextInput(items);
IText output = new KeywordReplacer(input, user, ess);
double delay = 0;
try {
// Make sure delay is valid
delay = kit.containsKey("delay") ? ((Number) kit.get("delay")).doubleValue() : 0.0d;
} catch (final Exception e) {
throw new Exception(tl("kitError2"));
}
boolean spew = false;
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
for (String kitItem : output.getLines())
{
if (kitItem.startsWith(ess.getSettings().getCurrencySymbol()))
{
BigDecimal value = new BigDecimal(kitItem.substring(ess.getSettings().getCurrencySymbol().length()).trim());
Trade t = new Trade(value, ess);
t.pay(user, OverflowType.DROP);
continue;
}
// When was the last kit used?
final long lastTime = user.getKitTimestamp(kitName);
final String[] parts = kitItem.split(" +");
final ItemStack parseStack = ess.getItemDb().get(parts[0], parts.length > 1 ? Integer.parseInt(parts[1]) : 1);
final MetaItemStack metaStack = new MetaItemStack(parseStack);
// When can be use the kit again?
final Calendar delayTime = new GregorianCalendar();
delayTime.setTimeInMillis(lastTime);
delayTime.add(Calendar.SECOND, (int) delay);
delayTime.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0));
if (parts.length > 2)
{
// We pass a null sender here because kits should not do perm checks
metaStack.parseStringMeta(null, allowUnsafe, parts, 2, ess);
}
if (lastTime == 0L || lastTime > time.getTimeInMillis()) {
// If we have no record of kit use, or its corrupted, give them benefit of the doubt.
return 0L;
} else if (delay < 0d) {
// If the kit has a negative kit time, it can only be used once.
return -1;
} else if (delayTime.before(time)) {
// If the kit was used in the past, but outside the delay time, it can be used.
return 0L;
} else {
// If the kit has been used recently, return the next time it can be used.
return delayTime.getTimeInMillis();
}
}
final Map<Integer, ItemStack> overfilled;
if (user.isAuthorized("essentials.oversizedstacks"))
{
overfilled = InventoryWorkaround.addOversizedItems(user.getInventory(), ess.getSettings().getOversizedStackSize(), metaStack.getItemStack());
}
else
{
overfilled = InventoryWorkaround.addItems(user.getInventory(), metaStack.getItemStack());
}
for (ItemStack itemStack : overfilled.values())
{
user.getWorld().dropItemNaturally(user.getLocation(), itemStack);
spew = true;
}
}
user.updateInventory();
if (spew)
{
user.sendMessage(_("kitInvFull"));
}
}
catch (Exception e)
{
user.updateInventory();
ess.getLogger().log(Level.WARNING, e.getMessage());
throw new Exception(_("kitError2"), e);
}
}
@Deprecated
public List<String> getItems(final User user) throws Exception {
return getItems();
}
public List<String> getItems() throws Exception {
if (kit == null) {
throw new Exception(tl("kitNotFound"));
}
try {
final List<String> itemList = new ArrayList<>();
final Object kitItems = kit.get("items");
if (kitItems instanceof List) {
for (final Object item : (List) kitItems) {
if (item instanceof String) {
itemList.add(item.toString());
continue;
}
throw new Exception("Invalid kit item: " + item.toString());
}
return itemList;
}
throw new Exception("Invalid item list");
} catch (final Exception e) {
ess.getLogger().log(Level.WARNING, "Error parsing kit " + kitName + ": " + e.getMessage());
throw new Exception(tl("kitError2"), e);
}
}
public boolean expandItems(final User user) throws Exception {
return expandItems(user, getItems(user));
}
public boolean expandItems(final User user, final List<String> items) throws Exception {
try {
final IText input = new SimpleTextInput(items);
final IText output = new KeywordReplacer(input, user.getSource(), ess, true, true);
final KitClaimEvent event = new KitClaimEvent(user, this);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return false;
}
boolean spew = false;
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
final boolean currencyIsSuffix = ess.getSettings().isCurrencySymbolSuffixed();
final List<ItemStack> itemList = new ArrayList<>();
final List<String> commandQueue = new ArrayList<>();
final List<String> moneyQueue = new ArrayList<>();
for (final String kitItem : output.getLines()) {
if (!currencyIsSuffix ? kitItem.startsWith(ess.getSettings().getCurrencySymbol()) : kitItem.endsWith(ess.getSettings().getCurrencySymbol())) {
moneyQueue.add(NumberUtil.sanitizeCurrencyString(kitItem, ess));
continue;
}
if (kitItem.startsWith("/")) {
String command = kitItem.substring(1);
final String name = user.getName();
command = command.replace("{player}", name);
commandQueue.add(command);
continue;
}
final String[] parts = kitItem.split(" +");
final ItemStack parseStack = ess.getItemDb().get(parts[0], parts.length > 1 ? Integer.parseInt(parts[1]) : 1);
if (parseStack.getType() == Material.AIR) {
continue;
}
final MetaItemStack metaStack = new MetaItemStack(parseStack);
if (parts.length > 2) {
// We pass a null sender here because kits should not do perm checks
metaStack.parseStringMeta(null, allowUnsafe, parts, 2, ess);
}
itemList.add(metaStack.getItemStack());
}
final Map<Integer, ItemStack> overfilled;
final boolean allowOversizedStacks = user.isAuthorized("essentials.oversizedstacks");
final boolean isDropItemsIfFull = ess.getSettings().isDropItemsIfFull();
if (isDropItemsIfFull) {
if (allowOversizedStacks) {
overfilled = InventoryWorkaround.addOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), itemList.toArray(new ItemStack[0]));
} else {
overfilled = InventoryWorkaround.addItems(user.getBase().getInventory(), itemList.toArray(new ItemStack[0]));
}
for (final ItemStack itemStack : overfilled.values()) {
int spillAmount = itemStack.getAmount();
if (!allowOversizedStacks) {
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
}
while (spillAmount > 0) {
user.getWorld().dropItemNaturally(user.getLocation(), itemStack);
spillAmount -= itemStack.getAmount();
}
spew = true;
}
} else {
if (allowOversizedStacks) {
overfilled = InventoryWorkaround.addAllOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), itemList.toArray(new ItemStack[0]));
} else {
overfilled = InventoryWorkaround.addAllItems(user.getBase().getInventory(), itemList.toArray(new ItemStack[0]));
}
if (overfilled != null) {
user.sendMessage(tl("kitInvFullNoDrop"));
return false;
}
}
user.getBase().updateInventory();
// Process money & command queues
// Done after all items have been processed so commands are not run and money is not given if
// an error occurs during the item giving process
for (final String valueString : moneyQueue) {
final BigDecimal value = new BigDecimal(valueString.trim());
final Trade t = new Trade(value, ess);
t.pay(user, OverflowType.DROP);
}
for (final String cmd : commandQueue) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
}
if (spew) {
user.sendMessage(tl("kitInvFull"));
}
} catch (final Exception e) {
user.getBase().updateInventory();
ess.getLogger().log(Level.WARNING, e.getMessage());
throw new Exception(tl("kitError2"), e);
}
return true;
}
}
@@ -0,0 +1,134 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import java.io.File;
import java.math.BigDecimal;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static com.earth2me.essentials.I18n.capitalCase;
import static com.earth2me.essentials.I18n.tl;
public class Kits implements IConf {
private final EssentialsConf config;
private ConfigurationSection kits;
public Kits(final IEssentials essentials) {
config = new EssentialsConf(new File(essentials.getDataFolder(), "kits.yml"));
config.setTemplateName("/kits.yml");
reloadConfig();
}
@Override
public void reloadConfig() {
config.load();
kits = _getKits();
}
private ConfigurationSection _getKits() {
if (config.isConfigurationSection("kits")) {
final ConfigurationSection section = config.getConfigurationSection("kits");
final ConfigurationSection newSection = new MemoryConfiguration();
for (final String kitItem : section.getKeys(false)) {
if (section.isConfigurationSection(kitItem)) {
newSection.set(kitItem.toLowerCase(Locale.ENGLISH), section.getConfigurationSection(kitItem));
}
}
return newSection;
}
return null;
}
public EssentialsConf getConfig() {
return config;
}
public ConfigurationSection getKits() {
return kits;
}
public Map<String, Object> getKit(String name) {
name = name.replace('.', '_').replace('/', '_');
if (getKits() != null) {
final ConfigurationSection kits = getKits();
// For some reason, YAML doesn't sees keys as always lowercase even if they aren't defined like that.
// Workaround is to toLowercase when getting from the config, but showing normally elsewhere.
// ODDLY ENOUGH when you get the configuration section for ALL kits, it will return the proper
// case of each kit. But when you check for each kit's configuration section, it won't return the kit
// you just found if you don't toLowercase it.
if (kits.isConfigurationSection(name.toLowerCase())) {
return kits.getConfigurationSection(name.toLowerCase()).getValues(true);
}
}
return null;
}
// Tries to find an existing kit name that matches the given name, ignoring case. Returns null if no match.
public String matchKit(final String name) {
if (config.isConfigurationSection("kits")) {
final ConfigurationSection section = config.getConfigurationSection("kits");
if (section != null) {
for (final String kitName : section.getKeys(false)) {
if (kitName.equalsIgnoreCase(name)) {
return kitName;
}
}
}
}
return null;
}
public void addKit(final String name, final List<String> lines, final long delay) {
// Will overwrite but w/e
config.set("kits." + name + ".delay", delay);
config.set("kits." + name + ".items", lines);
kits = _getKits();
config.save();
}
public void removeKit(final String name) {
config.set("kits." + name, null);
kits = _getKits();
config.save();
}
public String listKits(final net.ess3.api.IEssentials ess, final User user) throws Exception {
try {
final ConfigurationSection kits = config.getConfigurationSection("kits");
final StringBuilder list = new StringBuilder();
for (final String kitItem : kits.getKeys(false)) {
if (user == null) {
list.append(" ").append(capitalCase(kitItem));
} else if (user.isAuthorized("essentials.kits." + kitItem.toLowerCase(Locale.ENGLISH))) {
String cost = "";
String name = capitalCase(kitItem);
final BigDecimal costPrice = new Trade("kit-" + kitItem.toLowerCase(Locale.ENGLISH), ess).getCommandCost(user);
if (costPrice.signum() > 0) {
cost = tl("kitCost", NumberUtil.displayCurrency(costPrice, ess));
}
final Kit kit = new Kit(kitItem, ess);
final double nextUse = kit.getNextUse(user);
if (nextUse == -1 && ess.getSettings().isSkippingUsedOneTimeKitsFromKitList()) {
continue;
} else if (nextUse != 0) {
name = tl("kitDelay", name);
}
list.append(" ").append(name).append(cost);
}
}
return list.toString().trim();
} catch (final Exception ex) {
throw new Exception(tl("kitError"), ex);
}
}
}
@@ -2,19 +2,15 @@ package com.earth2me.essentials;
import org.bukkit.Location;
public class LocationTarget implements ITarget {
private final Location location;
public class LocationTarget implements ITarget
{
private final Location location;
LocationTarget(final Location location) {
this.location = location;
}
LocationTarget(Location location)
{
this.location = location;
}
@Override
public Location getLocation()
{
return location;
}
}
@Override
public Location getLocation() {
return location;
}
}
@@ -1,7 +1,18 @@
package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._;
import java.io.*;
import net.ess3.api.IEssentials;
import org.bukkit.Bukkit;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.DigestInputStream;
import java.security.DigestOutputStream;
@@ -11,217 +22,133 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import static com.earth2me.essentials.I18n.tl;
public class ManagedFile
{
private final static int BUFFERSIZE = 1024 * 8;
private final transient File file;
public class ManagedFile {
private static final int BUFFERSIZE = 1024 * 8;
private final transient File file;
public ManagedFile(final String filename, final IEssentials ess)
{
file = new File(ess.getDataFolder(), filename);
public ManagedFile(final String filename, final IEssentials ess) {
file = new File(ess.getDataFolder(), filename);
if (file.exists())
{
try
{
if (checkForVersion(file, ess.getDescription().getVersion()) && !file.delete())
{
throw new IOException("Could not delete file " + file.toString());
}
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
}
if (file.exists()) {
try {
if (checkForVersion(file, ess.getDescription().getVersion()) && !file.delete()) {
throw new IOException("Could not delete file " + file.toString());
}
} catch (final IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
}
if (!file.exists())
{
try
{
copyResourceAscii("/" + filename, file);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, _("itemsCsvNotLoaded"), ex);
}
}
}
if (!file.exists()) {
try {
copyResourceAscii("/" + filename, file);
} catch (final IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, tl("itemsCsvNotLoaded", filename), ex);
}
}
}
public static void copyResourceAscii(final String resourceName, final File file) throws IOException
{
final InputStreamReader reader = new InputStreamReader(ManagedFile.class.getResourceAsStream(resourceName));
try
{
final MessageDigest digest = getDigest();
final DigestOutputStream digestStream = new DigestOutputStream(new FileOutputStream(file), digest);
try
{
final OutputStreamWriter writer = new OutputStreamWriter(digestStream);
try
{
final char[] buffer = new char[BUFFERSIZE];
do
{
final int length = reader.read(buffer);
if (length >= 0)
{
writer.write(buffer, 0, length);
}
else
{
break;
}
}
while (true);
writer.write("\n");
writer.flush();
final BigInteger hashInt = new BigInteger(1, digest.digest());
digestStream.on(false);
digestStream.write('#');
digestStream.write(hashInt.toString(16).getBytes());
}
finally
{
writer.close();
}
}
finally
{
digestStream.close();
}
}
finally
{
reader.close();
}
}
public static void copyResourceAscii(final String resourceName, final File file) throws IOException {
try (final InputStreamReader reader = new InputStreamReader(ManagedFile.class.getResourceAsStream(resourceName))) {
final MessageDigest digest = getDigest();
try (final DigestOutputStream digestStream = new DigestOutputStream(new FileOutputStream(file), digest)) {
try (final OutputStreamWriter writer = new OutputStreamWriter(digestStream)) {
final char[] buffer = new char[BUFFERSIZE];
do {
final int length = reader.read(buffer);
if (length >= 0) {
writer.write(buffer, 0, length);
} else {
break;
}
} while (true);
writer.write("\n");
writer.flush();
final BigInteger hashInt = new BigInteger(1, digest.digest());
digestStream.on(false);
digestStream.write('#');
digestStream.write(hashInt.toString(16).getBytes());
}
}
}
}
public static boolean checkForVersion(final File file, final String version) throws IOException
{
if (file.length() < 33)
{
return false;
}
final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
try
{
final byte[] buffer = new byte[(int)file.length()];
int position = 0;
do
{
final int length = bis.read(buffer, position, Math.min((int)file.length() - position, BUFFERSIZE));
if (length < 0)
{
break;
}
position += length;
}
while (position < file.length());
final ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
if (bais.skip(file.length() - 33) != file.length() - 33)
{
return false;
}
final BufferedReader reader = new BufferedReader(new InputStreamReader(bais));
try
{
String hash = reader.readLine();
if (hash != null && hash.matches("#[a-f0-9]{32}"))
{
hash = hash.substring(1);
bais.reset();
final String versionline = reader.readLine();
if (versionline != null && versionline.matches("#version: .+"))
{
final String versioncheck = versionline.substring(10);
if (!versioncheck.equalsIgnoreCase(version))
{
bais.reset();
final MessageDigest digest = getDigest();
final DigestInputStream digestStream = new DigestInputStream(bais, digest);
try
{
final byte[] bytes = new byte[(int)file.length() - 33];
digestStream.read(bytes);
final BigInteger correct = new BigInteger(hash, 16);
final BigInteger test = new BigInteger(1, digest.digest());
if (correct.equals(test))
{
return true;
}
else
{
Bukkit.getLogger().warning("File " + file.toString() + " has been modified by user and file version differs, please update the file manually.");
}
}
finally
{
digestStream.close();
}
}
}
}
}
finally
{
reader.close();
}
}
finally
{
bis.close();
}
return false;
}
public static boolean checkForVersion(final File file, final String version) throws IOException {
if (file.length() < 33) {
return false;
}
try (final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
final byte[] buffer = new byte[(int) file.length()];
int position = 0;
do {
final int length = bis.read(buffer, position, Math.min((int) file.length() - position, BUFFERSIZE));
if (length < 0) {
break;
}
position += length;
} while (position < file.length());
final ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
if (bais.skip(file.length() - 33) != file.length() - 33) {
return false;
}
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(bais))) {
String hash = reader.readLine();
if (hash != null && hash.matches("#[a-f0-9]{32}")) {
hash = hash.substring(1);
bais.reset();
final String versionline = reader.readLine();
if (versionline != null && versionline.matches("#version: .+")) {
final String versioncheck = versionline.substring(10);
if (!versioncheck.equalsIgnoreCase(version)) {
bais.reset();
final MessageDigest digest = getDigest();
try (final DigestInputStream digestStream = new DigestInputStream(bais, digest)) {
final byte[] bytes = new byte[(int) file.length() - 33];
digestStream.read(bytes);
final BigInteger correct = new BigInteger(hash, 16);
final BigInteger test = new BigInteger(1, digest.digest());
if (correct.equals(test)) {
return true;
} else {
Bukkit.getLogger().warning("File " + file.toString() + " has been modified by user and file version differs, please update the file manually.");
}
}
}
}
}
}
}
return false;
}
public static MessageDigest getDigest() throws IOException
{
try
{
return MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException ex)
{
throw new IOException(ex);
}
}
public static MessageDigest getDigest() throws IOException {
try {
return MessageDigest.getInstance("MD5");
} catch (final NoSuchAlgorithmException ex) {
throw new IOException(ex);
}
}
public List<String> getLines()
{
try
{
final BufferedReader reader = new BufferedReader(new FileReader(file));
try
{
final List<String> lines = new ArrayList<String>();
do
{
final String line = reader.readLine();
if (line == null)
{
break;
}
else
{
lines.add(line);
}
}
while (true);
return lines;
}
finally
{
reader.close();
}
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
return Collections.emptyList();
}
}
public List<String> getLines() {
try {
try (final BufferedReader reader = new BufferedReader(new FileReader(file))) {
final List<String> lines = new ArrayList<>();
do {
final String line = reader.readLine();
if (line == null) {
break;
} else {
lines.add(line);
}
} while (true);
return lines;
}
} catch (final IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
return Collections.emptyList();
}
}
}
File diff suppressed because it is too large. Load diff
+167 -110
View File
@@ -1,135 +1,192 @@
package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
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.Player;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.earth2me.essentials.I18n.tl;
// Suffixes can be appended on the end of a mob name to make it plural
// Entities without a suffix, will default to 's'
public enum Mob
{
CHICKEN("Chicken", Enemies.FRIENDLY, EntityType.CHICKEN),
COW("Cow", Enemies.FRIENDLY, EntityType.COW),
CREEPER("Creeper", Enemies.ENEMY, EntityType.CREEPER),
GHAST("Ghast", Enemies.ENEMY, EntityType.GHAST),
GIANT("Giant", Enemies.ENEMY, EntityType.GIANT),
PIG("Pig", Enemies.FRIENDLY, EntityType.PIG),
PIGZOMB("PigZombie", Enemies.NEUTRAL, EntityType.PIG_ZOMBIE),
SHEEP("Sheep", Enemies.FRIENDLY, "", EntityType.SHEEP),
SKELETON("Skeleton", Enemies.ENEMY, EntityType.SKELETON),
SLIME("Slime", Enemies.ENEMY, EntityType.SLIME),
SPIDER("Spider", Enemies.ENEMY, EntityType.SPIDER),
SQUID("Squid", Enemies.FRIENDLY, EntityType.SQUID),
ZOMBIE("Zombie", Enemies.ENEMY, EntityType.ZOMBIE),
WOLF("Wolf", Enemies.NEUTRAL, EntityType.WOLF),
CAVESPIDER("CaveSpider", Enemies.ENEMY, EntityType.CAVE_SPIDER),
ENDERMAN("Enderman", Enemies.ENEMY, "", EntityType.ENDERMAN),
SILVERFISH("Silverfish", Enemies.ENEMY, "", EntityType.SILVERFISH),
ENDERDRAGON("EnderDragon", Enemies.ENEMY, EntityType.ENDER_DRAGON),
VILLAGER("Villager", Enemies.FRIENDLY, EntityType.VILLAGER),
BLAZE("Blaze", Enemies.ENEMY, EntityType.BLAZE),
MUSHROOMCOW("MushroomCow", Enemies.FRIENDLY, EntityType.MUSHROOM_COW),
MAGMACUBE("MagmaCube", Enemies.ENEMY, EntityType.MAGMA_CUBE),
SNOWMAN("Snowman", Enemies.FRIENDLY, "", EntityType.SNOWMAN),
OCELOT("Ocelot", Enemies.NEUTRAL, EntityType.OCELOT),
IRONGOLEM("IronGolem", Enemies.NEUTRAL, EntityType.IRON_GOLEM),
WITHER("Wither", Enemies.ENEMY, EntityType.WITHER),
BAT("Bat", Enemies.FRIENDLY, EntityType.BAT),
WITCH("Witch", Enemies.ENEMY, EntityType.WITCH),
BOAT("Boat", Enemies.NEUTRAL, EntityType.BOAT),
MINECART("Minecart", Enemies.NEUTRAL, EntityType.MINECART),
MINECART_CHEST("ChestMinecart", Enemies.NEUTRAL, EntityType.MINECART_CHEST),
MINECART_FURNACE("FurnaceMinecart", Enemies.NEUTRAL, EntityType.MINECART_FURNACE),
MINECART_TNT("TNTMinecart", Enemies.NEUTRAL, EntityType.MINECART_TNT),
MINECART_HOPPER("HopperMinecart", Enemies.NEUTRAL, EntityType.MINECART_HOPPER),
ENDERCRYSTAL("EnderCrystal", Enemies.NEUTRAL, EntityType.ENDER_CRYSTAL),
EXPERIENCEORB("ExperienceOrb", Enemies.NEUTRAL, EntityType.EXPERIENCE_ORB);
public static final Logger logger = Logger.getLogger("Minecraft");
public enum Mob {
CHICKEN("Chicken", Enemies.FRIENDLY, EntityType.CHICKEN),
COW("Cow", Enemies.FRIENDLY, EntityType.COW),
CREEPER("Creeper", Enemies.ENEMY, EntityType.CREEPER),
GHAST("Ghast", Enemies.ENEMY, EntityType.GHAST),
GIANT("Giant", Enemies.ENEMY, EntityType.GIANT),
HORSE("Horse", Enemies.FRIENDLY, EntityType.HORSE),
PIG("Pig", Enemies.FRIENDLY, EntityType.PIG),
PIGZOMB("PigZombie", Enemies.NEUTRAL, MobCompat.ZOMBIFIED_PIGLIN),
ZOMBIFIED_PIGLIN("ZombifiedPiglin", Enemies.NEUTRAL, MobCompat.ZOMBIFIED_PIGLIN),
SHEEP("Sheep", Enemies.FRIENDLY, "", EntityType.SHEEP),
SKELETON("Skeleton", Enemies.ENEMY, EntityType.SKELETON),
SLIME("Slime", Enemies.ENEMY, EntityType.SLIME),
SPIDER("Spider", Enemies.ENEMY, EntityType.SPIDER),
SQUID("Squid", Enemies.FRIENDLY, EntityType.SQUID),
ZOMBIE("Zombie", Enemies.ENEMY, EntityType.ZOMBIE),
WOLF("Wolf", Enemies.NEUTRAL, "", EntityType.WOLF),
CAVESPIDER("CaveSpider", Enemies.ENEMY, EntityType.CAVE_SPIDER),
ENDERMAN("Enderman", Enemies.ENEMY, "", EntityType.ENDERMAN),
SILVERFISH("Silverfish", Enemies.ENEMY, "", EntityType.SILVERFISH),
ENDERDRAGON("EnderDragon", Enemies.ENEMY, EntityType.ENDER_DRAGON),
VILLAGER("Villager", Enemies.FRIENDLY, EntityType.VILLAGER),
BLAZE("Blaze", Enemies.ENEMY, EntityType.BLAZE),
MUSHROOMCOW("MushroomCow", Enemies.FRIENDLY, EntityType.MUSHROOM_COW),
MAGMACUBE("MagmaCube", Enemies.ENEMY, EntityType.MAGMA_CUBE),
SNOWMAN("Snowman", Enemies.FRIENDLY, "", EntityType.SNOWMAN),
OCELOT("Ocelot", Enemies.NEUTRAL, EntityType.OCELOT),
IRONGOLEM("IronGolem", Enemies.NEUTRAL, EntityType.IRON_GOLEM),
WITHER("Wither", Enemies.ENEMY, EntityType.WITHER),
BAT("Bat", Enemies.FRIENDLY, EntityType.BAT),
WITCH("Witch", Enemies.ENEMY, EntityType.WITCH),
BOAT("Boat", Enemies.NEUTRAL, EntityType.BOAT),
MINECART("Minecart", Enemies.NEUTRAL, EntityType.MINECART),
MINECART_CHEST("ChestMinecart", Enemies.NEUTRAL, EntityType.MINECART_CHEST),
MINECART_FURNACE("FurnaceMinecart", Enemies.NEUTRAL, EntityType.MINECART_FURNACE),
MINECART_TNT("TNTMinecart", Enemies.NEUTRAL, EntityType.MINECART_TNT),
MINECART_HOPPER("HopperMinecart", Enemies.NEUTRAL, EntityType.MINECART_HOPPER),
MINECART_MOB_SPAWNER("SpawnerMinecart", Enemies.NEUTRAL, EntityType.MINECART_MOB_SPAWNER),
ENDERCRYSTAL("EnderCrystal", Enemies.NEUTRAL, EntityType.ENDER_CRYSTAL),
EXPERIENCEORB("ExperienceOrb", Enemies.NEUTRAL, "EXPERIENCE_ORB"),
ARMOR_STAND("ArmorStand", Enemies.NEUTRAL, "ARMOR_STAND"),
ENDERMITE("Endermite", Enemies.ENEMY, "ENDERMITE"),
GUARDIAN("Guardian", Enemies.ENEMY, "GUARDIAN"),
ELDER_GUARDIAN("ElderGuardian", Enemies.ENEMY, "ELDER_GUARDIAN"),
RABBIT("Rabbit", Enemies.FRIENDLY, "RABBIT"),
SHULKER("Shulker", Enemies.ENEMY, "SHULKER"),
POLAR_BEAR("PolarBear", Enemies.NEUTRAL, "POLAR_BEAR"),
WITHER_SKELETON("WitherSkeleton", Enemies.ENEMY, "WITHER_SKELETON"),
STRAY_SKELETON("StraySkeleton", Enemies.ENEMY, "STRAY"),
ZOMBIE_VILLAGER("ZombieVillager", Enemies.FRIENDLY, "ZOMBIE_VILLAGER"),
SKELETON_HORSE("SkeletonHorse", Enemies.FRIENDLY, "SKELETON_HORSE"),
ZOMBIE_HORSE("ZombieHorse", Enemies.FRIENDLY, "ZOMBIE_HORSE"),
DONKEY("Donkey", Enemies.FRIENDLY, "DONKEY"),
MULE("Mule", Enemies.FRIENDLY, "MULE"),
EVOKER("Evoker", Enemies.ENEMY, "EVOKER"),
VEX("Vex", Enemies.ENEMY, "VEX"),
VINDICATOR("Vindicator", Enemies.ENEMY, "VINDICATOR"),
LLAMA("Llama", Enemies.NEUTRAL, "LLAMA"),
HUSK("Husk", Enemies.ENEMY, "HUSK"),
ILLUSIONER("Illusioner", Enemies.ENEMY, "ILLUSIONER"),
PARROT("Parrot", Enemies.NEUTRAL, "PARROT"),
TURTLE("Turtle", Enemies.NEUTRAL, "TURTLE"),
PHANTOM("Phantom", Enemies.ENEMY, "PHANTOM"),
COD("Cod", Enemies.NEUTRAL, "", "COD"),
SALMON("Salmon", Enemies.NEUTRAL, "", "SALMON"),
PUFFERFISH("Pufferfish", Enemies.NEUTRAL, "", "PUFFERFISH"),
TROPICAL_FISH("TropicalFish", Enemies.NEUTRAL, "", "TROPICAL_FISH"),
DROWNED("Drowned", Enemies.ENEMY, "DROWNED"),
DOLPHIN("Dolphin", Enemies.NEUTRAL, "DOLPHIN"),
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"),
BEE("Bee", Enemies.NEUTRAL, "BEE"),
STRAY("Stray", Enemies.ENEMY, "STRAY"),
HOGLIN("Hoglin", Enemies.ADULT_ENEMY, "HOGLIN"),
PIGLIN("Piglin", Enemies.ADULT_ENEMY, "PIGLIN"),
STRIDER("Strider", Enemies.FRIENDLY, "STRIDER"),
ZOGLIN("Zoglin", Enemies.ENEMY, "ZOGLIN"),
PIGLIN_BRUTE("PiglinBrute", Enemies.ADULT_ENEMY, "PIGLIN_BRUTE"),
;
private Mob(String n, Enemies en, String s, EntityType type)
{
this.suffix = s;
this.name = n;
this.type = en;
this.bukkitType = type;
}
public static final Logger logger = Logger.getLogger("Essentials");
private static final Map<String, Mob> hashMap = new HashMap<>();
private static final Map<EntityType, Mob> bukkitMap = new HashMap<>();
private Mob(String n, Enemies en, EntityType type)
{
this.name = n;
this.type = en;
this.bukkitType = type;
}
public String suffix = "s";
final public String name;
final public Enemies type;
final private EntityType bukkitType;
private static final Map<String, Mob> hashMap = new HashMap<String, Mob>();
static {
for (final Mob mob : Mob.values()) {
hashMap.put(mob.name.toLowerCase(Locale.ENGLISH), mob);
if (mob.bukkitType != null) {
bukkitMap.put(mob.bukkitType, mob);
}
}
}
static
{
for (Mob mob : Mob.values())
{
hashMap.put(mob.name.toLowerCase(Locale.ENGLISH), mob);
}
}
final public String name;
final public Enemies type;
final private EntityType bukkitType;
public String suffix = "s";
public static Set<String> getMobList()
{
return Collections.unmodifiableSet(hashMap.keySet());
}
Mob(final String n, final Enemies en, final String s, final EntityType type) {
this.suffix = s;
this.name = n;
this.type = en;
this.bukkitType = type;
}
public Entity spawn(final Player player, final Server server, final Location loc) throws MobException
{
return spawn(player.getWorld(), server, loc);
}
Mob(final String n, final Enemies en, final EntityType type) {
this.name = n;
this.type = en;
this.bukkitType = type;
}
public Entity spawn(final World world, final Server server, final Location loc) throws MobException
{
final Entity entity = world.spawn(loc, (Class<? extends Entity>)this.bukkitType.getEntityClass());
if (entity == null)
{
logger.log(Level.WARNING, _("unableToSpawnMob"));
throw new MobException();
}
return entity;
}
Mob(final String n, final Enemies en, final String s, final String typeName) {
this.suffix = s;
this.name = n;
this.type = en;
bukkitType = EnumUtil.getEntityType(typeName);
}
Mob(final String n, final Enemies en, final String typeName) {
this.name = n;
this.type = en;
bukkitType = EnumUtil.getEntityType(typeName);
}
public enum Enemies
{
FRIENDLY("friendly"),
NEUTRAL("neutral"),
ENEMY("enemy");
public static Set<String> getMobList() {
return Collections.unmodifiableSet(hashMap.keySet());
}
private Enemies(final String type)
{
this.type = type;
}
final protected String type;
}
public static Mob fromName(final String name) {
return hashMap.get(name.toLowerCase(Locale.ENGLISH));
}
public EntityType getType()
{
return bukkitType;
}
public static Mob fromBukkitType(final EntityType type) {
return bukkitMap.get(type);
}
public static Mob fromName(final String name)
{
return hashMap.get(name.toLowerCase(Locale.ENGLISH));
}
public Entity spawn(final World world, final Server server, final Location loc) throws MobException {
final Entity entity = world.spawn(loc, this.bukkitType.getEntityClass());
if (entity == null) {
logger.log(Level.WARNING, tl("unableToSpawnMob"));
throw new MobException();
}
return entity;
}
public EntityType getType() {
return bukkitType;
}
public static class MobException extends Exception
{
private static final long serialVersionUID = 1L;
}
public enum Enemies {
FRIENDLY("friendly"),
NEUTRAL("neutral"),
ENEMY("enemy"),
ADULT_ENEMY("adult_enemy");
final protected String type;
Enemies(final String type) {
this.type = type;
}
}
public static class MobException extends Exception {
private static final long serialVersionUID = 1L;
}
}
@@ -0,0 +1,219 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.VersionUtil;
import net.ess3.nms.refl.ReflUtil;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Fox;
import org.bukkit.entity.Llama;
import org.bukkit.entity.MushroomCow;
import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Panda;
import org.bukkit.entity.Parrot;
import org.bukkit.entity.TropicalFish;
import org.bukkit.entity.Villager;
import java.lang.reflect.Method;
import static com.earth2me.essentials.utils.EnumUtil.getEntityType;
public final class MobCompat {
// Constants for mob interfaces added in later versions
@SuppressWarnings("rawtypes")
public static final Class RAIDER = ReflUtil.getClassCached("org.bukkit.entity.Raider");
// 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");
public static final EntityType SHULKER = getEntityType("SHULKER");
public static final EntityType STRAY = getEntityType("STRAY");
public static final EntityType FOX = getEntityType("FOX");
public static final EntityType PHANTOM = getEntityType("PHANTOM");
// Constants for mobs that have changed since earlier versions
public static final EntityType CAT = getEntityType("CAT", "OCELOT");
public static final EntityType ZOMBIFIED_PIGLIN = getEntityType("ZOMBIFIED_PIGLIN", "PIG_ZOMBIE");
private MobCompat() {
}
// Older cats are Ocelots, whereas 1.14+ cats are Cats
public static void setCatType(final Entity entity, final CatType type) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
((Ocelot) entity).setCatType(Ocelot.Type.valueOf(type.ocelotTypeName));
} else {
final Class cat = ReflUtil.getClassCached("org.bukkit.entity.Cat");
final Class catType = ReflUtil.getClassCached("org.bukkit.entity.Cat$Type");
final Method setCatType = ReflUtil.getMethodCached(cat, "setCatType", catType);
try {
setCatType.invoke(entity, EnumUtil.valueOf(catType, type.catTypeName));
} catch (final Exception e) {
e.printStackTrace();
}
}
}
// Older villagers have professions and careers, 1.14+ villagers only have professions
public static void setVillagerProfession(final Entity entity, final VillagerProfession profession) {
if (!(entity instanceof Villager)) {
return;
}
final Villager villager = (Villager) entity;
villager.setProfession(profession.asEnum());
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
final Class villagerCareer = ReflUtil.getClassCached("org.bukkit.entity.Villager$Career");
final Method setCareer = ReflUtil.getMethodCached(Villager.class, "setCareer", villagerCareer);
try {
setCareer.invoke(entity, EnumUtil.valueOf(villagerCareer, profession.oldCareer));
} catch (final Exception e) {
e.printStackTrace();
}
}
}
// Only 1.14+ villagers have biome variants
public static void setVillagerType(final Entity entity, final String type) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
return;
}
if (entity instanceof Villager) {
((Villager) entity).setVillagerType(Villager.Type.valueOf(type));
}
}
// Llamas only exist in 1.11+
public static void setLlamaColor(final Entity entity, final String color) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_11_R01)) {
return;
}
if (entity instanceof Llama) {
((Llama) entity).setColor(Llama.Color.valueOf(color));
}
}
// Parrots only exist in 1.12+
public static void setParrotVariant(final Entity entity, final String variant) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) {
return;
}
if (entity instanceof Parrot) {
((Parrot) entity).setVariant(Parrot.Variant.valueOf(variant));
}
}
// Tropical fish only exist in 1.13+
public static void setTropicalFishPattern(final Entity entity, final String pattern) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) {
return;
}
if (entity instanceof TropicalFish) {
((TropicalFish) entity).setPattern(TropicalFish.Pattern.valueOf(pattern));
}
}
// Mushroom cow variant API only exists in 1.14+
public static void setMooshroomVariant(final Entity entity, final String variant) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
return;
}
if (entity instanceof MushroomCow) {
((MushroomCow) entity).setVariant(MushroomCow.Variant.valueOf(variant));
}
}
// Pandas only exists in 1.14+
public static void setPandaGene(final Entity entity, final String gene, final boolean mainGene) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
return;
}
if (entity instanceof Panda) {
final Panda panda = (Panda) entity;
final Panda.Gene pandaGene = Panda.Gene.valueOf(gene);
if (mainGene) {
panda.setMainGene(pandaGene);
} else {
panda.setHiddenGene(pandaGene);
}
}
}
// Foxes only exist in 1.14+
public static void setFoxType(final Entity entity, final String type) {
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
return;
}
if (entity instanceof Fox) {
((Fox) entity).setFoxType(Fox.Type.valueOf(type));
}
}
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 final String oldProfession;
private final String oldCareer;
private final 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);
}
}
}
@@ -0,0 +1,404 @@
package com.earth2me.essentials;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.StringUtil;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Horse;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Phantom;
import org.bukkit.entity.Pig;
import org.bukkit.entity.Player;
import org.bukkit.entity.Raider;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.TropicalFish;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Zombie;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Colorable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.logging.Logger;
import java.util.stream.Collectors;
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),
BABY_HORSE("colt", EntityType.HORSE, Data.BABY, false),
BABY_OCELOT("kitten", EntityType.OCELOT, Data.BABY, false),
BABY_SHEEP("lamb", EntityType.SHEEP, Data.BABY, false),
BABY_COW("calf", EntityType.COW.getEntityClass(), Data.BABY, false),
BABY_VILLAGER("child", EntityType.VILLAGER, Data.BABY, false),
TAMED_TAMEABLE("tamed", Tameable.class, Data.TAMED, true),
TAME_TAMEABLE("tame", Tameable.class, Data.TAMED, false),
RANDOM_SHEEP("random", EntityType.SHEEP, Data.COLORABLE, true),
COLORABLE_SHEEP("", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH)).collect(Collectors.toList()), EntityType.SHEEP, Data.COLORABLE, true),
POLKA_HORSE("polka", EntityType.HORSE, Horse.Style.BLACK_DOTS, true),
SOOTY_HORSE("sooty", EntityType.HORSE, Horse.Style.BLACK_DOTS, false),
BLAZE_HORSE("blaze", EntityType.HORSE, Horse.Style.WHITE, true),
SOCKS_HORSE("socks", EntityType.HORSE, Horse.Style.WHITE, false),
LEOPARD_HORSE("leopard", EntityType.HORSE, Horse.Style.WHITE_DOTS, true),
APPALOOSA_HORSE("appaloosa", EntityType.HORSE, Horse.Style.WHITE_DOTS, false),
PAINT_HORSE("paint", EntityType.HORSE, Horse.Style.WHITEFIELD, true),
MILKY_HORSE("milky", EntityType.HORSE, Horse.Style.WHITEFIELD, false),
SPLOTCHY_HORSE("splotchy", EntityType.HORSE, Horse.Style.WHITEFIELD, false),
BLACK_HORSE("black", EntityType.HORSE, Horse.Color.BLACK, true),
CHESTNUT_HORSE("chestnut", EntityType.HORSE, Horse.Color.CHESTNUT, true),
LIVER_HORSE("liver", EntityType.HORSE, Horse.Color.CHESTNUT, false),
CREAMY_HORSE("creamy", EntityType.HORSE, Horse.Color.CREAMY, true),
FLAXEN_HORSE("flaxen", EntityType.HORSE, Horse.Color.CREAMY, false),
GRAY_HORSE("gray", EntityType.HORSE, Horse.Color.GRAY, true),
DAPPLE_HORSE("dapple", EntityType.HORSE, Horse.Color.GRAY, false),
BUCKSKIN_HORSE("buckskin", EntityType.HORSE, Horse.Color.DARK_BROWN, true),
DARKBROWN_HORSE("darkbrown", EntityType.HORSE, Horse.Color.DARK_BROWN, false),
DARK_HORSE("dark", EntityType.HORSE, Horse.Color.DARK_BROWN, false),
DBROWN_HORSE("dbrown", EntityType.HORSE, Horse.Color.DARK_BROWN, false),
BAY_HORSE("bay", EntityType.HORSE, Horse.Color.BROWN, true),
BROWN_HORSE("brown", EntityType.HORSE, Horse.Color.BROWN, false),
SADDLE_HORSE("saddle", EntityType.HORSE, Data.HORSESADDLE, true),
GOLD_ARMOR_HORSE("goldarmor", EntityType.HORSE, 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", 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),
GOLD_SWORD_ZOMBIE("goldsword", EntityType.ZOMBIE.getEntityClass(), EnumUtil.getMaterial("GOLDEN_SWORD", "GOLD_SWORD"), true),
IRON_SWORD_ZOMBIE("ironsword", EntityType.ZOMBIE.getEntityClass(), Material.IRON_SWORD, true),
STONE_SWORD_ZOMBIE("stonesword", EntityType.ZOMBIE.getEntityClass(), Material.STONE_SWORD, false),
SWORD_ZOMBIE("sword", EntityType.ZOMBIE.getEntityClass(), Material.STONE_SWORD, true),
DIAMOND_SWORD_SKELETON("diamondsword", EntityType.SKELETON, Material.DIAMOND_SWORD, true),
GOLD_SWORD_SKELETON("goldsword", EntityType.SKELETON, EnumUtil.getMaterial("GOLDEN_SWORD", "GOLD_SWORD"), true),
IRON_SWORD_SKELETON("ironsword", EntityType.SKELETON, Material.IRON_SWORD, true),
STONE_SWORD_SKELETON("stonesword", EntityType.SKELETON, Material.STONE_SWORD, false),
SWORD_SKELETON("sword", EntityType.SKELETON, Material.STONE_SWORD, true),
BOW_SKELETON("bow", EntityType.SKELETON, Material.BOW, true),
POWERED_CREEPER("powered", EntityType.CREEPER, Data.ELECTRIFIED, true),
ELECTRIC_CREEPER("electric", EntityType.CREEPER, Data.ELECTRIFIED, false),
CHARGED_CREEPER("charged", EntityType.CREEPER, Data.ELECTRIFIED, false),
SADDLE_PIG("saddle", EntityType.PIG, Data.PIGSADDLE, true),
ANGRY_WOLF("angry", EntityType.WOLF, Data.ANGRY, true),
RABID_WOLF("rabid", EntityType.WOLF, Data.ANGRY, false),
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("", Collections.singletonList("<1-100>"), EntityType.SLIME.getEntityClass(), Data.SIZE, true),
NUM_EXPERIENCE_ORB("", Collections.singletonList("<1-2000000000>"), EntityType.EXPERIENCE_ORB, Data.EXP, 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),
RANDOM_SHULKER("random", MobCompat.SHULKER, Data.COLORABLE, true),
COLORABLE_SHULKER("", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH)).collect(Collectors.toList()), MobCompat.SHULKER, Data.COLORABLE, true),
RED_FOX("red", MobCompat.FOX, "fox:RED", true),
SNOW_FOX("snow", MobCompat.FOX, "fox:SNOW", true),
SIZE_PHANTOM("", Collections.singletonList("<1-100>"), MobCompat.PHANTOM, Data.SIZE, true),
RAID_LEADER("leader", MobCompat.RAIDER, Data.RAID_LEADER, true),
TROPICAL_FISH_BODY_COLOR("fish_body_color", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH) + "body").collect(Collectors.toList()), MobCompat.TROPICAL_FISH, Data.FISH_BODY_COLOR, true),
TROPICAL_FISH_PATTERN_COLOR("fish_pattern_color", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH) + "pattern").collect(Collectors.toList()), MobCompat.TROPICAL_FISH, Data.FISH_PATTERN_COLOR, true),
;
public static final Logger logger = Logger.getLogger("Essentials");
final private String nickname;
final private List<String> suggestions;
final private Object type;
final private Object value;
final private boolean isPublic;
private String matched;
MobData(final String n, final Object type, final Object value, final boolean isPublic) {
this.nickname = n;
this.matched = n;
this.suggestions = Collections.singletonList(n);
this.type = type;
this.value = value;
this.isPublic = isPublic;
}
MobData(final String n, final List<String> s, final Object type, final Object value, final boolean isPublic) {
this.nickname = n;
this.matched = n;
this.suggestions = s;
this.type = type;
this.value = value;
this.isPublic = isPublic;
}
public static LinkedHashMap<String, MobData> getPossibleData(final Entity spawned, final boolean publicOnly) {
final LinkedHashMap<String, MobData> mobList = new LinkedHashMap<>();
for (final MobData data : MobData.values()) {
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())) {
mobList.put(data.nickname.toLowerCase(Locale.ENGLISH), data);
}
}
return mobList;
}
public static List<String> getValidHelp(final Entity spawned) {
final List<String> output = new ArrayList<>();
final LinkedHashMap<String, MobData> posData = getPossibleData(spawned, true);
for (final MobData data : posData.values()) {
output.add(StringUtil.joinList(data.suggestions));
}
return output;
}
public static MobData fromData(final Entity spawned, final String name) {
if (name.isEmpty()) {
return null;
}
final LinkedHashMap<String, MobData> posData = getPossibleData(spawned, false);
for (final MobData data : posData.values()) {
for (final String suggestion : data.suggestions) {
if (name.contains(suggestion)) {
return data;
}
}
}
return null;
}
public String getMatched() {
return this.matched;
}
public void setData(final Entity spawned, final Player target, final String rawData) throws Exception {
if (this.value.equals(Data.ANGRY)) {
((Wolf) spawned).setAngry(true);
} else if (this.value.equals(Data.ADULT)) {
((Ageable) spawned).setAdult();
} else if (this.value.equals(Data.BABY)) {
((Ageable) spawned).setBaby();
} else if (this.value.equals(Data.ADULTZOMBIE)) {
((Zombie) spawned).setBaby(false);
} else if (this.value.equals(Data.BABYZOMBIE)) {
((Zombie) spawned).setBaby(true);
} else if (this.value.equals(Data.ELECTRIFIED)) {
((Creeper) spawned).setPowered(true);
} else if (this.value.equals(Data.HORSESADDLE)) {
final Horse horse = (Horse) spawned;
horse.setTamed(true);
horse.setOwner(target);
horse.getInventory().setSaddle(new ItemStack(Material.SADDLE, 1));
} else if (this.value.equals(Data.PIGSADDLE)) {
((Pig) spawned).setSaddle(true);
} else if (this.value.equals(Data.TAMED)) {
final Tameable tameable = (Tameable) spawned;
tameable.setTamed(true);
tameable.setOwner(target);
} else if (this.value.equals(Data.COLORABLE)) {
final String color = rawData.toUpperCase(Locale.ENGLISH);
try {
if (color.equals("RANDOM")) {
final Random rand = new Random();
((Colorable) spawned).setColor(DyeColor.values()[rand.nextInt(DyeColor.values().length)]);
} else if (!color.isEmpty()) {
((Colorable) spawned).setColor(DyeColor.valueOf(color));
}
this.matched = rawData;
} catch (final Exception e) {
throw new Exception(tl("sheepMalformedColor"), e);
}
} else if (this.value.equals(Data.EXP)) {
try {
((ExperienceOrb) spawned).setExperience(Integer.parseInt(rawData));
this.matched = rawData;
} catch (final NumberFormatException e) {
throw new Exception(tl("invalidNumber"), e);
}
} else if (this.value.equals(Data.SIZE)) {
try {
final int size = Integer.parseInt(rawData);
if (spawned instanceof Slime) {
((Slime) spawned).setSize(size);
} else if (spawned.getType() == MobCompat.PHANTOM) {
((Phantom) spawned).setSize(size);
}
this.matched = rawData;
} catch (final NumberFormatException e) {
throw new Exception(tl("slimeMalformedSize"), e);
}
} else if (this.value instanceof Horse.Color) {
((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 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);
((Horse) spawned).getInventory().setArmor(new ItemStack((Material) this.value, 1));
} else if (this.type.equals(EntityType.ZOMBIE.getEntityClass()) || this.type.equals(EntityType.SKELETON)) {
final EntityEquipment invent = ((LivingEntity) spawned).getEquipment();
InventoryWorkaround.setItemInMainHand(invent, new ItemStack((Material) this.value, 1));
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
}
} else if (this.value.equals(Data.RAID_LEADER)) {
((Raider) spawned).setPatrolLeader(true);
} else if (this.value.equals(Data.FISH_BODY_COLOR)) {
for (final String match : TROPICAL_FISH_BODY_COLOR.suggestions) {
if (rawData.contains(match)) {
this.matched = match;
final String color = match.substring(0, match.indexOf("body")).toUpperCase(Locale.ENGLISH);
((TropicalFish) spawned).setBodyColor(DyeColor.valueOf(color));
break;
}
}
} else if (this.value.equals(Data.FISH_PATTERN_COLOR)) {
for (final String match : TROPICAL_FISH_PATTERN_COLOR.suggestions) {
if (rawData.contains(match)) {
this.matched = match;
final String color = match.substring(0, match.indexOf("pattern")).toUpperCase(Locale.ENGLISH);
((TropicalFish) spawned).setPatternColor(DyeColor.valueOf(color));
break;
}
}
} 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;
case "fox":
MobCompat.setFoxType(spawned, split[1]);
break;
}
} else {
logger.warning("Unknown mob data type: " + this.toString());
}
}
public enum Data {
ADULT,
BABY,
CHEST,
ADULTZOMBIE,
BABYZOMBIE,
HORSESADDLE,
PIGSADDLE,
ELECTRIFIED,
ANGRY,
TAMED,
COLORABLE,
EXP,
SIZE,
RAID_LEADER,
FISH_BODY_COLOR,
FISH_PATTERN_COLOR,
}
}
File diff suppressed because it is too large. Load diff
@@ -1,38 +1,34 @@
package com.earth2me.essentials;
import lombok.Delegate;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.ServerOperator;
public class PlayerExtension {
protected Player base;
public class PlayerExtension implements Player
{
@Delegate(types =
{
Player.class, Entity.class, CommandSender.class, ServerOperator.class,
HumanEntity.class, ConfigurationSerializable.class, LivingEntity.class,
Permissible.class
})
protected Player base;
public PlayerExtension(final Player base) {
this.base = base;
}
public PlayerExtension(final Player base)
{
this.base = base;
}
public final Player getBase() {
return base;
}
public final Player getBase()
{
return base;
}
public final Player setBase(final Player base) {
return this.base = base;
}
public final Player setBase(final Player base)
{
return this.base = base;
}
public Server getServer() {
return base.getServer();
}
public World getWorld() {
return base.getWorld();
}
public Location getLocation() {
return base.getLocation();
}
}
@@ -0,0 +1,128 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.FormatUtil;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import static com.earth2me.essentials.I18n.tl;
public final class PlayerList {
private PlayerList() {
}
// Cosmetic list formatting
public static String listUsers(final IEssentials ess, final List<User> users, final String seperator) {
final StringBuilder groupString = new StringBuilder();
Collections.sort(users);
boolean needComma = false;
for (final User user : users) {
if (needComma) {
groupString.append(seperator);
}
needComma = true;
if (user.isAfk()) {
groupString.append(tl("listAfkTag"));
}
if (user.isHidden()) {
groupString.append(tl("listHiddenTag"));
}
user.setDisplayNick();
groupString.append(user.getDisplayName());
if (ess.getSettings().realNamesOnList() && !ChatColor.stripColor(user.getDisplayName()).equals(user.getName())) {
groupString.append(" (").append(user.getName()).append(")");
}
groupString.append("\u00a7f");
}
return groupString.toString();
}
// Produce a user summary: There are 5 out of maximum 10 players online.
public static String listSummary(final IEssentials ess, final User user, final boolean showHidden) {
final Server server = ess.getServer();
int playerHidden = 0;
int hiddenCount = 0;
for (final User onlinePlayer : ess.getOnlineUsers()) {
if (onlinePlayer.isHidden() || (user != null && !user.getBase().canSee(onlinePlayer.getBase()))) {
playerHidden++;
if (showHidden || user != null && user.getBase().canSee(onlinePlayer.getBase())) {
hiddenCount++;
}
}
}
final String online;
if (hiddenCount > 0) {
online = tl("listAmountHidden", ess.getOnlinePlayers().size() - playerHidden, hiddenCount, server.getMaxPlayers());
} else {
online = tl("listAmount", ess.getOnlinePlayers().size() - playerHidden, server.getMaxPlayers());
}
return online;
}
// Build the basic player list, divided by groups.
public static Map<String, List<User>> getPlayerLists(final IEssentials ess, final IUser sender, final boolean showHidden) {
final Map<String, List<User>> playerList = new HashMap<>();
for (final User onlineUser : ess.getOnlineUsers()) {
if ((sender == null && !showHidden && onlineUser.isHidden()) || (sender != null && !showHidden && !sender.getBase().canSee(onlineUser.getBase()))) {
continue;
}
final String group = FormatUtil.stripFormat(FormatUtil.stripEssentialsFormat(onlineUser.getGroup().toLowerCase()));
final List<User> list = playerList.computeIfAbsent(group, k -> new ArrayList<>());
list.add(onlineUser);
}
return playerList;
}
// Handle the merging of groups
public static List<User> getMergedList(final IEssentials ess, final Map<String, List<User>> playerList, final String groupName) {
final Set<String> configGroups = ess.getSettings().getListGroupConfig().keySet();
final List<User> users = new ArrayList<>();
for (final String configGroup : configGroups) {
if (configGroup.equalsIgnoreCase(groupName)) {
final String[] groupValues = ess.getSettings().getListGroupConfig().get(configGroup).toString().trim().split(" ");
for (String groupValue : groupValues) {
groupValue = groupValue.toLowerCase(Locale.ENGLISH);
if (groupValue.isEmpty()) {
continue;
}
final List<User> u = playerList.get(groupValue.trim());
if (u == null || u.isEmpty()) {
continue;
}
playerList.remove(groupValue);
users.addAll(u);
}
}
}
return users;
}
// Output a playerlist of just a single group, /list <groupname>
public static String listGroupUsers(final IEssentials ess, final Map<String, List<User>> playerList, final String groupName) throws Exception {
final List<User> users = getMergedList(ess, playerList, groupName);
final List<User> groupUsers = playerList.get(groupName);
if (groupUsers != null && !groupUsers.isEmpty()) {
users.addAll(groupUsers);
}
if (users.isEmpty()) {
throw new Exception(tl("groupDoesNotExist"));
}
final String displayGroupName = Character.toTitleCase(groupName.charAt(0)) +
groupName.substring(1);
return outputFormat(displayGroupName, listUsers(ess, users, ", "));
}
// Build the output string
public static String outputFormat(final String group, final String message) {
return tl("listGroupTag", FormatUtil.replaceFormat(group)) +
message;
}
}
@@ -4,19 +4,15 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
public class PlayerTarget implements ITarget {
private final String name;
public class PlayerTarget implements ITarget
{
private final String name;
public PlayerTarget(final Player entity) {
this.name = entity.getName();
}
PlayerTarget(Player entity)
{
this.name = entity.getName();
}
@Override
public Location getLocation()
{
return Bukkit.getServer().getPlayerExact(name).getLocation();
}
}
@Override
public Location getLocation() {
return Bukkit.getServer().getPlayerExact(name).getLocation();
}
}
@@ -1,131 +1,152 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.NumberUtil;
import org.bukkit.potion.PotionEffectType;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.potion.PotionEffectType;
public final class Potions {
private static final Map<String, PotionEffectType> POTIONS = new HashMap<>();
private static final Map<String, PotionEffectType> ALIASPOTIONS = new HashMap<>();
public class Potions
{
private static final Map<String, PotionEffectType> POTIONS = new HashMap<String, PotionEffectType>();
private static final Map<String, PotionEffectType> ALIASPOTIONS = new HashMap<String, PotionEffectType>();
static {
static
{
POTIONS.put("speed", PotionEffectType.SPEED);
ALIASPOTIONS.put("fast", PotionEffectType.SPEED);
ALIASPOTIONS.put("runfast", PotionEffectType.SPEED);
ALIASPOTIONS.put("sprint", PotionEffectType.SPEED);
ALIASPOTIONS.put("swift", PotionEffectType.SPEED);
POTIONS.put("speed", PotionEffectType.SPEED);
ALIASPOTIONS.put("fast", PotionEffectType.SPEED);
ALIASPOTIONS.put("runfast", PotionEffectType.SPEED);
ALIASPOTIONS.put("sprint", PotionEffectType.SPEED);
ALIASPOTIONS.put("swift", PotionEffectType.SPEED);
POTIONS.put("slowness", PotionEffectType.SLOW);
ALIASPOTIONS.put("slow", PotionEffectType.SLOW);
ALIASPOTIONS.put("sluggish", PotionEffectType.SLOW);
POTIONS.put("slowness", PotionEffectType.SLOW);
ALIASPOTIONS.put("slow", PotionEffectType.SLOW);
ALIASPOTIONS.put("sluggish", PotionEffectType.SLOW);
POTIONS.put("haste", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("superpick", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("quickmine", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("digspeed", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("digfast", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("sharp", PotionEffectType.FAST_DIGGING);
POTIONS.put("haste", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("superpick", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("quickmine", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("digspeed", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("digfast", PotionEffectType.FAST_DIGGING);
ALIASPOTIONS.put("sharp", PotionEffectType.FAST_DIGGING);
POTIONS.put("fatigue", PotionEffectType.SLOW_DIGGING);
ALIASPOTIONS.put("slow", PotionEffectType.SLOW_DIGGING);
ALIASPOTIONS.put("dull", PotionEffectType.SLOW_DIGGING);
POTIONS.put("fatigue", PotionEffectType.SLOW_DIGGING);
ALIASPOTIONS.put("slow", PotionEffectType.SLOW_DIGGING);
ALIASPOTIONS.put("dull", PotionEffectType.SLOW_DIGGING);
POTIONS.put("strength", PotionEffectType.INCREASE_DAMAGE);
ALIASPOTIONS.put("strong", PotionEffectType.INCREASE_DAMAGE);
ALIASPOTIONS.put("bull", PotionEffectType.INCREASE_DAMAGE);
ALIASPOTIONS.put("attack", PotionEffectType.INCREASE_DAMAGE);
POTIONS.put("strength", PotionEffectType.INCREASE_DAMAGE);
ALIASPOTIONS.put("strong", PotionEffectType.INCREASE_DAMAGE);
ALIASPOTIONS.put("bull", PotionEffectType.INCREASE_DAMAGE);
ALIASPOTIONS.put("attack", PotionEffectType.INCREASE_DAMAGE);
POTIONS.put("heal", PotionEffectType.HEAL);
ALIASPOTIONS.put("healthy", PotionEffectType.HEAL);
ALIASPOTIONS.put("instaheal", PotionEffectType.HEAL);
POTIONS.put("heal", PotionEffectType.HEAL);
ALIASPOTIONS.put("healthy", PotionEffectType.HEAL);
ALIASPOTIONS.put("instaheal", PotionEffectType.HEAL);
POTIONS.put("harm", PotionEffectType.HARM);
ALIASPOTIONS.put("harming", PotionEffectType.HARM);
ALIASPOTIONS.put("injure", PotionEffectType.HARM);
ALIASPOTIONS.put("damage", PotionEffectType.HARM);
ALIASPOTIONS.put("inflict", PotionEffectType.HARM);
POTIONS.put("harm", PotionEffectType.HARM);
ALIASPOTIONS.put("harming", PotionEffectType.HARM);
ALIASPOTIONS.put("injure", PotionEffectType.HARM);
ALIASPOTIONS.put("damage", PotionEffectType.HARM);
ALIASPOTIONS.put("inflict", PotionEffectType.HARM);
POTIONS.put("jump", PotionEffectType.JUMP);
ALIASPOTIONS.put("leap", PotionEffectType.JUMP);
POTIONS.put("jump", PotionEffectType.JUMP);
ALIASPOTIONS.put("leap", PotionEffectType.JUMP);
POTIONS.put("nausea", PotionEffectType.CONFUSION);
ALIASPOTIONS.put("sick", PotionEffectType.CONFUSION);
ALIASPOTIONS.put("sickness", PotionEffectType.CONFUSION);
ALIASPOTIONS.put("confusion", PotionEffectType.CONFUSION);
POTIONS.put("nausea", PotionEffectType.CONFUSION);
ALIASPOTIONS.put("sick", PotionEffectType.CONFUSION);
ALIASPOTIONS.put("sickness", PotionEffectType.CONFUSION);
ALIASPOTIONS.put("confusion", PotionEffectType.CONFUSION);
POTIONS.put("regeneration", PotionEffectType.REGENERATION);
ALIASPOTIONS.put("regen", PotionEffectType.REGENERATION);
POTIONS.put("regeneration", PotionEffectType.REGENERATION);
ALIASPOTIONS.put("regen", PotionEffectType.REGENERATION);
POTIONS.put("resistance", PotionEffectType.DAMAGE_RESISTANCE);
ALIASPOTIONS.put("dmgresist", PotionEffectType.DAMAGE_RESISTANCE);
ALIASPOTIONS.put("armor", PotionEffectType.DAMAGE_RESISTANCE);
POTIONS.put("resistance", PotionEffectType.DAMAGE_RESISTANCE);
ALIASPOTIONS.put("dmgresist", PotionEffectType.DAMAGE_RESISTANCE);
ALIASPOTIONS.put("armor", PotionEffectType.DAMAGE_RESISTANCE);
ALIASPOTIONS.put("dmgresist", PotionEffectType.DAMAGE_RESISTANCE);
POTIONS.put("fireresist", PotionEffectType.FIRE_RESISTANCE);
ALIASPOTIONS.put("fireresistance", PotionEffectType.FIRE_RESISTANCE);
ALIASPOTIONS.put("resistfire", PotionEffectType.FIRE_RESISTANCE);
POTIONS.put("fireresist", PotionEffectType.FIRE_RESISTANCE);
ALIASPOTIONS.put("fireresistance", PotionEffectType.FIRE_RESISTANCE);
ALIASPOTIONS.put("resistfire", PotionEffectType.FIRE_RESISTANCE);
POTIONS.put("waterbreath", PotionEffectType.WATER_BREATHING);
ALIASPOTIONS.put("waterbreathing", PotionEffectType.WATER_BREATHING);
POTIONS.put("waterbreath", PotionEffectType.WATER_BREATHING);
ALIASPOTIONS.put("waterbreathing", PotionEffectType.WATER_BREATHING);
POTIONS.put("invisibility", PotionEffectType.INVISIBILITY);
ALIASPOTIONS.put("invisible", PotionEffectType.INVISIBILITY);
ALIASPOTIONS.put("invis", PotionEffectType.INVISIBILITY);
ALIASPOTIONS.put("vanish", PotionEffectType.INVISIBILITY);
ALIASPOTIONS.put("disappear", PotionEffectType.INVISIBILITY);
POTIONS.put("invisibility", PotionEffectType.INVISIBILITY);
ALIASPOTIONS.put("invisible", PotionEffectType.INVISIBILITY);
ALIASPOTIONS.put("invis", PotionEffectType.INVISIBILITY);
ALIASPOTIONS.put("vanish", PotionEffectType.INVISIBILITY);
ALIASPOTIONS.put("disappear", PotionEffectType.INVISIBILITY);
POTIONS.put("blindness", PotionEffectType.BLINDNESS);
ALIASPOTIONS.put("blind", PotionEffectType.BLINDNESS);
POTIONS.put("blindness", PotionEffectType.BLINDNESS);
ALIASPOTIONS.put("blind", PotionEffectType.BLINDNESS);
POTIONS.put("nightvision", PotionEffectType.NIGHT_VISION);
ALIASPOTIONS.put("vision", PotionEffectType.NIGHT_VISION);
POTIONS.put("nightvision", PotionEffectType.NIGHT_VISION);
ALIASPOTIONS.put("vision", PotionEffectType.NIGHT_VISION);
POTIONS.put("hunger", PotionEffectType.HUNGER);
ALIASPOTIONS.put("hungry", PotionEffectType.HUNGER);
ALIASPOTIONS.put("starve", PotionEffectType.HUNGER);
POTIONS.put("hunger", PotionEffectType.HUNGER);
ALIASPOTIONS.put("hungry", PotionEffectType.HUNGER);
ALIASPOTIONS.put("starve", PotionEffectType.HUNGER);
POTIONS.put("weakness", PotionEffectType.WEAKNESS);
ALIASPOTIONS.put("weak", PotionEffectType.WEAKNESS);
POTIONS.put("weakness", PotionEffectType.WEAKNESS);
ALIASPOTIONS.put("weak", PotionEffectType.WEAKNESS);
POTIONS.put("poison", PotionEffectType.POISON);
ALIASPOTIONS.put("venom", PotionEffectType.POISON);
POTIONS.put("poison", PotionEffectType.POISON);
ALIASPOTIONS.put("venom", PotionEffectType.POISON);
POTIONS.put("wither", PotionEffectType.WITHER);
ALIASPOTIONS.put("decay", PotionEffectType.WITHER);
POTIONS.put("wither", PotionEffectType.WITHER);
ALIASPOTIONS.put("decay", PotionEffectType.WITHER);
}
POTIONS.put("healthboost", PotionEffectType.HEALTH_BOOST);
ALIASPOTIONS.put("boost", PotionEffectType.HEALTH_BOOST);
public static PotionEffectType getByName(String name)
{
PotionEffectType peffect;
if (NumberUtil.isInt(name))
{
peffect = PotionEffectType.getById(Integer.parseInt(name));
}
else
{
peffect = PotionEffectType.getByName(name.toUpperCase(Locale.ENGLISH));
}
if (peffect == null)
{
peffect = POTIONS.get(name.toLowerCase(Locale.ENGLISH));
}
if (peffect == null)
{
peffect = ALIASPOTIONS.get(name.toLowerCase(Locale.ENGLISH));
}
return peffect;
}
POTIONS.put("absorption", PotionEffectType.ABSORPTION);
ALIASPOTIONS.put("absorb", PotionEffectType.ABSORPTION);
public static Set<Entry<String, PotionEffectType>> entrySet()
{
return POTIONS.entrySet();
}
}
POTIONS.put("saturation", PotionEffectType.SATURATION);
ALIASPOTIONS.put("food", PotionEffectType.SATURATION);
POTIONS.put("waterbreathing", PotionEffectType.WATER_BREATHING);
ALIASPOTIONS.put("underwaterbreathing", PotionEffectType.WATER_BREATHING);
ALIASPOTIONS.put("waterbreath", PotionEffectType.WATER_BREATHING);
ALIASPOTIONS.put("underwaterbreath", PotionEffectType.WATER_BREATHING);
ALIASPOTIONS.put("air", PotionEffectType.WATER_BREATHING);
// 1.9
try {
POTIONS.put("glowing", PotionEffectType.GLOWING);
ALIASPOTIONS.put("glow", PotionEffectType.GLOWING);
POTIONS.put("levitation", PotionEffectType.LEVITATION);
ALIASPOTIONS.put("levitate", PotionEffectType.LEVITATION);
POTIONS.put("luck", PotionEffectType.LUCK);
POTIONS.put("unluck", PotionEffectType.UNLUCK);
} catch (final Throwable ignored) {
}
}
private Potions() {
}
public static PotionEffectType getByName(final String name) {
PotionEffectType peffect;
if (NumberUtil.isInt(name)) {
peffect = PotionEffectType.getById(Integer.parseInt(name));
} else {
peffect = PotionEffectType.getByName(name.toUpperCase(Locale.ENGLISH));
}
if (peffect == null) {
peffect = POTIONS.get(name.toLowerCase(Locale.ENGLISH));
}
if (peffect == null) {
peffect = ALIASPOTIONS.get(name.toLowerCase(Locale.ENGLISH));
}
return peffect;
}
public static Set<Entry<String, PotionEffectType>> entrySet() {
return POTIONS.entrySet();
}
}
@@ -0,0 +1,209 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.VersionUtil;
import io.papermc.lib.PaperLib;
import net.ess3.api.InvalidWorldException;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Biome;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
public class RandomTeleport implements IConf {
private static final Random RANDOM = new Random();
private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0;
private final IEssentials essentials;
private final EssentialsConf config;
private final ConcurrentLinkedQueue<Location> cachedLocations = new ConcurrentLinkedQueue<>();
public RandomTeleport(final IEssentials essentials) {
this.essentials = essentials;
final File file = new File(essentials.getDataFolder(), "tpr.yml");
config = new EssentialsConf(file);
config.setTemplateName("/tpr.yml");
config.options().copyHeader(true);
reloadConfig();
}
@Override
public void reloadConfig() {
config.load();
cachedLocations.clear();
}
public Location getCenter() {
try {
final Location center = config.getLocation("center", essentials.getServer());
if (center != null) {
return center;
}
} catch (final InvalidWorldException ignored) {
}
final Location center = essentials.getServer().getWorlds().get(0).getWorldBorder().getCenter();
center.setY(center.getWorld().getHighestBlockYAt(center) + 1);
setCenter(center);
return center;
}
public void setCenter(final Location center) {
config.setProperty("center", center);
config.save();
}
public double getMinRange() {
return config.getDouble("min-range", 0d);
}
public void setMinRange(final double minRange) {
config.setProperty("min-range", minRange);
config.save();
}
public double getMaxRange() {
return config.getDouble("max-range", getCenter().getWorld().getWorldBorder().getSize() / 2);
}
public void setMaxRange(final double maxRange) {
config.setProperty("max-range", maxRange);
config.save();
}
public Set<Biome> getExcludedBiomes() {
final List<String> biomeNames = config.getStringList("excluded-biomes");
final Set<Biome> excludedBiomes = new HashSet<>();
for (final String biomeName : biomeNames) {
try {
excludedBiomes.add(Biome.valueOf(biomeName.toUpperCase()));
} catch (final IllegalArgumentException ignored) {
}
}
return excludedBiomes;
}
public int getFindAttempts() {
return config.getInt("find-attempts", 10);
}
public int getCacheThreshold() {
return config.getInt("cache-threshold", 10);
}
public boolean getPreCache() {
return config.getBoolean("pre-cache", false);
}
public Queue<Location> getCachedLocations() {
return cachedLocations;
}
// Get a random location; cached if possible. Otherwise on demand.
public CompletableFuture<Location> getRandomLocation(final Location center, final double minRange, final double maxRange) {
final int findAttempts = this.getFindAttempts();
final Queue<Location> cachedLocations = this.getCachedLocations();
// Try to build up the cache if it is below the threshold
if (cachedLocations.size() < this.getCacheThreshold()) {
cacheRandomLocations(center, minRange, maxRange);
}
final CompletableFuture<Location> future = new CompletableFuture<>();
// Return a random location immediately if one is available, otherwise try to find one now
if (cachedLocations.isEmpty()) {
attemptRandomLocation(findAttempts, center, minRange, maxRange).thenAccept(future::complete);
} else {
future.complete(cachedLocations.poll());
}
return future;
}
// Prompts caching random valid locations, up to a maximum number of attempts
public void cacheRandomLocations(final Location center, final double minRange, final double maxRange) {
essentials.getServer().getScheduler().scheduleSyncDelayedTask(essentials, () -> {
for (int i = 0; i < this.getFindAttempts(); ++i) {
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> {
if (isValidRandomLocation(location)) {
this.getCachedLocations().add(location);
}
});
}
});
}
// Recursively attempt to find a random location. After a maximum number of attempts, the center is returned.
private CompletableFuture<Location> attemptRandomLocation(final int attempts, final Location center, final double minRange, final double maxRange) {
final CompletableFuture<Location> future = new CompletableFuture<>();
if (attempts > 0) {
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> {
if (isValidRandomLocation(location)) {
future.complete(location);
} else {
attemptRandomLocation(attempts - 1, center, minRange, maxRange).thenAccept(future::complete);
}
});
} else {
future.complete(center);
}
return future;
}
// Calculates a random location asynchronously.
private CompletableFuture<Location> calculateRandomLocation(final Location center, final double minRange, final double maxRange) {
final CompletableFuture<Location> future = new CompletableFuture<>();
// Find an equally distributed offset by randomly rotating a point inside a rectangle about the origin
final double rectX = RANDOM.nextDouble() * (maxRange - minRange) + minRange;
final double rectZ = RANDOM.nextDouble() * (maxRange + minRange) - minRange;
final double offsetX;
final double offsetZ;
final int transform = RANDOM.nextInt(4);
if (transform == 0) {
offsetX = rectX;
offsetZ = rectZ;
} else if (transform == 1) {
offsetX = -rectZ;
offsetZ = rectX;
} else if (transform == 2) {
offsetX = -rectX;
offsetZ = -rectZ;
} else {
offsetX = rectZ;
offsetZ = -rectX;
}
final Location location = new Location(
center.getWorld(),
center.getX() + offsetX,
center.getWorld().getMaxHeight(),
center.getZ() + offsetZ,
360 * RANDOM.nextFloat() - 180,
0
);
PaperLib.getChunkAtAsync(location).thenAccept(chunk -> {
if (World.Environment.NETHER.equals(center.getWorld().getEnvironment())) {
location.setY(getNetherYAt(location));
} else {
location.setY(center.getWorld().getHighestBlockYAt(location) + HIGHEST_BLOCK_Y_OFFSET);
}
future.complete(location);
});
return future;
}
// Returns an appropriate elevation for a given location in the nether, or -1 if none is found
private double getNetherYAt(final Location location) {
for (int y = 32; y < location.getWorld().getMaxHeight() / 2; ++y) {
if (!LocationUtil.isBlockUnsafe(location.getWorld(), location.getBlockX(), y, location.getBlockZ())) {
return y;
}
}
return -1;
}
private boolean isValidRandomLocation(final Location location) {
return location.getBlockY() > 0 && !this.getExcludedBiomes().contains(location.getBlock().getBiome());
}
}
File diff suppressed because it is too large. Load diff
@@ -1,437 +1,278 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.StringUtil;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.Mob.MobException;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import com.earth2me.essentials.utils.EnumUtil;
import com.earth2me.essentials.utils.LocationUtil;
import com.earth2me.essentials.utils.NumberUtil;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Set;
import org.bukkit.DyeColor;
import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.IEssentials;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.*;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Horse;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.PigZombie;
import org.bukkit.entity.Zombie;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Colorable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
public class SpawnMob
{
public static String mobList(final User user)
{
final Set<String> mobList = Mob.getMobList();
final Set<String> availableList = new HashSet<String>();
for (String mob : mobList)
{
if (user.isAuthorized("essentials.spawnmob." + mob.toLowerCase(Locale.ENGLISH)))
{
availableList.add(mob);
}
}
if (availableList.isEmpty())
{
availableList.add(_("none"));
}
return StringUtil.joinList(availableList);
}
import static com.earth2me.essentials.I18n.tl;
public static List<String> mobParts(final String mobString)
{
String[] mobParts = mobString.split(",");
public final class SpawnMob {
List<String> mobs = new ArrayList<String>();
private static final Material GOLDEN_HELMET = EnumUtil.getMaterial("GOLDEN_HELMET", "GOLD_HELMET");
private static final Material GOLDEN_CHESTPLATE = EnumUtil.getMaterial("GOLDEN_CHESTPLATE", "GOLD_CHESTPLATE");
private static final Material GOLDEN_LEGGINGS = EnumUtil.getMaterial("GOLDEN_LEGGINGS", "GOLD_LEGGINGS");
private static final Material GOLDEN_BOOTS = EnumUtil.getMaterial("GOLDEN_BOOTS", "GOLD_BOOTS");
private static final Material GOLDEN_SWORD = EnumUtil.getMaterial("GOLDEN_SWORD", "GOLD_SWORD");
for (String mobPart : mobParts)
{
String[] mobDatas = mobPart.split(":");
mobs.add(mobDatas[0]);
}
return mobs;
}
private SpawnMob() {
}
public static List<String> mobData(final String mobString)
{
String[] mobParts = mobString.split(",");
public static String mobList(final User user) {
final Set<String> mobList = Mob.getMobList();
final Set<String> availableList = new HashSet<>();
for (final String mob : mobList) {
if (user.isAuthorized("essentials.spawnmob." + mob.toLowerCase(Locale.ENGLISH))) {
availableList.add(mob);
}
}
if (availableList.isEmpty()) {
availableList.add(tl("none"));
}
return StringUtil.joinList(availableList);
}
List<String> mobData = new ArrayList<String>();
public static List<String> mobParts(final String mobString) {
final String[] mobParts = mobString.split(",");
for (String mobPart : mobParts)
{
String[] mobDatas = mobPart.split(":");
if (mobDatas.length == 1)
{
mobData.add(null);
}
else
{
mobData.add(mobDatas[1]);
}
}
final List<String> mobs = new ArrayList<>();
return mobData;
}
for (final String mobPart : mobParts) {
final String[] mobDatas = mobPart.split(":");
mobs.add(mobDatas[0]);
}
return mobs;
}
// This method spawns a mob where the user is looking, owned by user
public static void spawnmob(final IEssentials ess, final Server server, final User user, final List<String> parts, final List<String> data, int mobCount) throws Exception
{
final Block block = LocationUtil.getTarget(user).getBlock();
if (block == null)
{
throw new Exception(_("unableToSpawnMob"));
}
spawnmob(ess, server, user, user, block.getLocation(), parts, data, mobCount);
}
public static List<String> mobData(final String mobString) {
final String[] mobParts = mobString.split(",");
// This method spawns a mob at loc, owned by noone
public static void spawnmob(final IEssentials ess, final Server server, final CommandSender sender, final Location loc, final List<String> parts, final List<String> data, int mobCount) throws Exception
{
spawnmob(ess, server, sender, null, loc, parts, data, mobCount);
}
final List<String> mobData = new ArrayList<>();
// This method spawns a mob at target, owned by target
public static void spawnmob(final IEssentials ess, final Server server, final CommandSender sender, final User target, final List<String> parts, final List<String> data, int mobCount) throws Exception
{
spawnmob(ess, server, sender, target, target.getLocation(), parts, data, mobCount);
}
for (final String mobPart : mobParts) {
final String[] mobDatas = mobPart.split(":");
if (mobDatas.length == 1) {
if (mobPart.contains(":")) {
mobData.add("");
} else {
mobData.add(null);
}
} else {
mobData.add(mobDatas[1]);
}
}
// This method spawns a mob at loc, owned by target
public static void spawnmob(final IEssentials ess, final Server server, final CommandSender sender, final User target, final Location loc, final List<String> parts, final List<String> data, int mobCount) throws Exception
{
final Location sloc = LocationUtil.getSafeDestination(loc);
return mobData;
}
for (int i = 0; i < parts.size(); i++)
{
Mob mob = Mob.fromName(parts.get(i));
checkSpawnable(ess, sender, mob);
}
// This method spawns a mob where the user is looking, owned by user
public static void spawnmob(final IEssentials ess, final Server server, final User user, final List<String> parts, final List<String> data, final int mobCount) throws Exception {
final Block block = LocationUtil.getTarget(user.getBase()).getBlock();
if (block == null) {
throw new Exception(tl("unableToSpawnMob"));
}
spawnmob(ess, server, user.getSource(), user, block.getLocation(), parts, data, mobCount);
}
final int serverLimit = ess.getSettings().getSpawnMobLimit();
int effectiveLimit = serverLimit / parts.size();
// This method spawns a mob at target, owned by target
public static void spawnmob(final IEssentials ess, final Server server, final CommandSource sender, final User target, final List<String> parts, final List<String> data, final int mobCount) throws Exception {
spawnmob(ess, server, sender, target, target.getLocation(), parts, data, mobCount);
}
if (effectiveLimit < 1)
{
effectiveLimit = 1;
while (parts.size() > serverLimit)
{
parts.remove(serverLimit);
}
}
// This method spawns a mob at loc, owned by target
public static void spawnmob(final IEssentials ess, final Server server, final CommandSource sender, final User target, final Location loc, final List<String> parts, final List<String> data, int mobCount) throws Exception {
final Location sloc = LocationUtil.getSafeDestination(loc);
if (mobCount > effectiveLimit)
{
mobCount = effectiveLimit;
sender.sendMessage(_("mobSpawnLimit"));
}
for (final String part : parts) {
final Mob mob = Mob.fromName(part);
checkSpawnable(ess, sender, mob);
}
Mob mob = Mob.fromName(parts.get(0)); // Get the first mob
try
{
for (int i = 0; i < mobCount; i++)
{
spawnMob(ess, server, sender, target, sloc, parts, data);
}
sender.sendMessage(mobCount * parts.size() + " " + mob.name.toLowerCase(Locale.ENGLISH) + mob.suffix + " " + _("spawned"));
}
catch (MobException e1)
{
throw new Exception(_("unableToSpawnMob"), e1);
}
catch (NumberFormatException e2)
{
throw new Exception(_("numberRequired"), e2);
}
catch (NullPointerException np)
{
throw new Exception(_("soloMob"), np);
}
}
final int serverLimit = ess.getSettings().getSpawnMobLimit();
int effectiveLimit = serverLimit / parts.size();
private static void spawnMob(final IEssentials ess, final Server server, final CommandSender sender, final User target, final Location sloc, List<String> parts, List<String> data) throws Exception
{
Mob mob;
Entity spawnedMob = null;
Entity spawnedMount;
if (effectiveLimit < 1) {
effectiveLimit = 1;
while (parts.size() > serverLimit) {
parts.remove(serverLimit);
}
}
for (int i = 0; i < parts.size(); i++)
{
if (i == 0)
{
mob = Mob.fromName(parts.get(i));
spawnedMob = mob.spawn(sloc.getWorld(), server, sloc);
defaultMobData(mob.getType(), spawnedMob);
if (mobCount > effectiveLimit) {
mobCount = effectiveLimit;
sender.sendMessage(tl("mobSpawnLimit"));
}
if (data.get(i) != null)
{
changeMobData(mob.getType(), spawnedMob, data.get(i), target);
}
}
final Mob mob = Mob.fromName(parts.get(0)); // Get the first mob
try {
for (int i = 0; i < mobCount; i++) {
spawnMob(ess, server, sender, target, sloc, parts, data);
}
sender.sendMessage(mobCount * parts.size() + " " + mob.name.toLowerCase(Locale.ENGLISH) + mob.suffix + " " + tl("spawned"));
} catch (final MobException e1) {
throw new Exception(tl("unableToSpawnMob"), e1);
} catch (final NumberFormatException e2) {
throw new Exception(tl("numberRequired"), e2);
} catch (final NullPointerException np) {
throw new Exception(tl("soloMob"), np);
}
}
int next = (i + 1);
if (next < parts.size()) //If it's the last mob in the list, don't set the mount
{
Mob mMob = Mob.fromName(parts.get(next));
spawnedMount = mMob.spawn(sloc.getWorld(), server, sloc);
defaultMobData(mMob.getType(), spawnedMount);
private static void spawnMob(final IEssentials ess, final Server server, final CommandSource sender, final User target, final Location sloc, final List<String> parts, final List<String> data) throws Exception {
Mob mob;
Entity spawnedMob = null;
Entity spawnedMount;
if (data.get(next) != null)
{
changeMobData(mMob.getType(), spawnedMount, data.get(next), target);
}
for (int i = 0; i < parts.size(); i++) {
if (i == 0) {
mob = Mob.fromName(parts.get(i));
spawnedMob = mob.spawn(sloc.getWorld(), server, sloc);
defaultMobData(mob.getType(), spawnedMob);
spawnedMob.setPassenger(spawnedMount);
if (data.get(i) != null) {
changeMobData(sender, mob.getType(), spawnedMob, data.get(i).toLowerCase(Locale.ENGLISH), target);
}
}
spawnedMob = spawnedMount;
}
}
}
final int next = i + 1;
// If it's the last mob in the list, don't set the mount
if (next < parts.size()) {
final Mob mMob = Mob.fromName(parts.get(next));
spawnedMount = mMob.spawn(sloc.getWorld(), server, sloc);
defaultMobData(mMob.getType(), spawnedMount);
private static void checkSpawnable(IEssentials ess, CommandSender sender, Mob mob) throws Exception
{
if (mob == null)
{
throw new Exception(_("invalidMob"));
}
if (data.get(next) != null) {
changeMobData(sender, mMob.getType(), spawnedMount, data.get(next).toLowerCase(Locale.ENGLISH), target);
}
if (ess.getSettings().getProtectPreventSpawn(mob.getType().toString().toLowerCase(Locale.ENGLISH)))
{
throw new Exception(_("disabledToSpawnMob"));
}
spawnedMob.setPassenger(spawnedMount);
if (sender instanceof User && !((User)sender).isAuthorized("essentials.spawnmob." + mob.name.toLowerCase(Locale.ENGLISH)))
{
throw new Exception(_("noPermToSpawnMob"));
}
}
spawnedMob = spawnedMount;
}
}
}
private static void changeMobData(final EntityType type, final Entity spawned, String data, final User target) throws Exception
{
data = data.toLowerCase(Locale.ENGLISH);
private static void checkSpawnable(final IEssentials ess, final CommandSource sender, final Mob mob) throws Exception {
if (mob == null || mob.getType() == null) {
throw new Exception(tl("invalidMob"));
}
if (spawned instanceof Zombie || type == EntityType.SKELETON)
{
//This should match all Living Entities but most mobs will just ignore the equipment.
if (data.contains("armor") || data.contains("armour"))
{
final EntityEquipment invent = ((LivingEntity)spawned).getEquipment();
if (data.contains("diamond"))
{
invent.setBoots(new ItemStack(Material.DIAMOND_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.DIAMOND_BOOTS, 1));
invent.setChestplate(new ItemStack(Material.DIAMOND_BOOTS, 1));
invent.setHelmet(new ItemStack(Material.DIAMOND_BOOTS, 1));
}
else if (data.contains("gold"))
{
invent.setBoots(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setChestplate(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setHelmet(new ItemStack(Material.GOLD_BOOTS, 1));
}
else if (data.contains("leather"))
{
invent.setBoots(new ItemStack(Material.LEATHER_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.LEATHER_BOOTS, 1));
invent.setChestplate(new ItemStack(Material.LEATHER_BOOTS, 1));
invent.setHelmet(new ItemStack(Material.LEATHER_BOOTS, 1));
}
else if (data.contains("no"))
{
invent.clear();
}
else
{
invent.setBoots(new ItemStack(Material.IRON_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.IRON_BOOTS, 1));
invent.setChestplate(new ItemStack(Material.IRON_BOOTS, 1));
invent.setHelmet(new ItemStack(Material.IRON_BOOTS, 1));
}
invent.setBootsDropChance(0f);
invent.setLeggingsDropChance(0f);
invent.setChestplateDropChance(0f);
invent.setHelmetDropChance(0f);
}
if (ess.getSettings().getProtectPreventSpawn(mob.getType().toString().toLowerCase(Locale.ENGLISH))) {
throw new Exception(tl("disabledToSpawnMob"));
}
}
if (spawned instanceof Slime)
{
try
{
((Slime)spawned).setSize(Integer.parseInt(data));
}
catch (Exception e)
{
throw new Exception(_("slimeMalformedSize"), e);
}
}
if (sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.spawnmob." + mob.name.toLowerCase(Locale.ENGLISH))) {
throw new Exception(tl("noPermToSpawnMob"));
}
}
if ((spawned instanceof Ageable) && data.contains("baby"))
{
((Ageable)spawned).setBaby();
data = data.replace("baby", "");
}
private static void changeMobData(final CommandSource sender, final EntityType type, final Entity spawned, final String inputData, final User target) throws Exception {
String data = inputData;
if (spawned instanceof Colorable)
{
final String color = data.toUpperCase(Locale.ENGLISH);
try
{
if (color.equals("RANDOM"))
{
final Random rand = new Random();
((Colorable)spawned).setColor(DyeColor.values()[rand.nextInt(DyeColor.values().length)]);
}
else if (color.length() > 1)
{
((Colorable)spawned).setColor(DyeColor.valueOf(color));
}
}
catch (Exception e)
{
throw new Exception(_("sheepMalformedColor"), e);
}
}
if (data.isEmpty()) {
sender.sendMessage(tl("mobDataList", StringUtil.joinList(MobData.getValidHelp(spawned))));
}
if (spawned instanceof Tameable && data.contains("tamed") && target != null)
{
final Tameable tameable = ((Tameable)spawned);
tameable.setTamed(true);
tameable.setOwner(target.getBase());
data = data.replace("tamed", "");
}
if (spawned instanceof Zombie) {
((Zombie) spawned).setBaby(false);
} else if (spawned instanceof Ageable) {
((Ageable) spawned).setAdult();
}
if (type == EntityType.WOLF)
{
if (data.contains("angry"))
{
((Wolf)spawned).setAngry(true);
}
}
if (spawned instanceof Zombie || type == EntityType.SKELETON) {
if (inputData.contains("armor") || inputData.contains("armour")) {
final EntityEquipment invent = ((LivingEntity) spawned).getEquipment();
if (inputData.contains("noarmor") || inputData.contains("noarmour")) {
invent.clear();
} else if (inputData.contains("diamond")) {
invent.setBoots(new ItemStack(Material.DIAMOND_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.DIAMOND_LEGGINGS, 1));
invent.setChestplate(new ItemStack(Material.DIAMOND_CHESTPLATE, 1));
invent.setHelmet(new ItemStack(Material.DIAMOND_HELMET, 1));
} else if (inputData.contains("gold")) {
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
invent.setLeggings(new ItemStack(GOLDEN_LEGGINGS, 1));
invent.setChestplate(new ItemStack(GOLDEN_CHESTPLATE, 1));
invent.setHelmet(new ItemStack(GOLDEN_HELMET, 1));
} else if (inputData.contains("leather")) {
invent.setBoots(new ItemStack(Material.LEATHER_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.LEATHER_LEGGINGS, 1));
invent.setChestplate(new ItemStack(Material.LEATHER_CHESTPLATE, 1));
invent.setHelmet(new ItemStack(Material.LEATHER_HELMET, 1));
} else if (inputData.contains("iron")) {
invent.setBoots(new ItemStack(Material.IRON_BOOTS, 1));
invent.setLeggings(new ItemStack(Material.IRON_LEGGINGS, 1));
invent.setChestplate(new ItemStack(Material.IRON_CHESTPLATE, 1));
invent.setHelmet(new ItemStack(Material.IRON_HELMET, 1));
}
invent.setBootsDropChance(0f);
invent.setLeggingsDropChance(0f);
invent.setChestplateDropChance(0f);
invent.setHelmetDropChance(0f);
}
if (type == EntityType.CREEPER && data.contains("powered"))
{
((Creeper)spawned).setPowered(true);
}
}
if (type == EntityType.OCELOT)
{
if (data.contains("siamese") || data.contains("white"))
{
((Ocelot)spawned).setCatType(Ocelot.Type.SIAMESE_CAT);
}
else if (data.contains("red") || data.contains("orange") || data.contains("tabby"))
{
((Ocelot)spawned).setCatType(Ocelot.Type.RED_CAT);
}
else if (data.contains("black") || data.contains("tuxedo"))
{
((Ocelot)spawned).setCatType(Ocelot.Type.BLACK_CAT);
}
}
MobData newData = MobData.fromData(spawned, data);
while (newData != null) {
newData.setData(spawned, target.getBase(), data);
data = data.replace(newData.getMatched(), "");
newData = MobData.fromData(spawned, data);
}
}
if (type == EntityType.VILLAGER)
{
for (Villager.Profession prof : Villager.Profession.values())
{
if (data.contains(prof.toString().toLowerCase(Locale.ENGLISH)))
{
((Villager)spawned).setProfession(prof);
}
}
}
private static void defaultMobData(final EntityType type, final Entity spawned) {
if (type == EntityType.SKELETON) {
final EntityEquipment invent = ((LivingEntity) spawned).getEquipment();
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(Material.BOW, 1));
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
}
if (spawned instanceof Zombie)
{
if (data.contains("villager"))
{
((Zombie)spawned).setVillager(true);
}
if (data.contains("baby"))
{
((Zombie)spawned).setBaby(true);
}
}
if (spawned instanceof Zombie || type == EntityType.SKELETON)
{
if (data.contains("sword"))
{
final EntityEquipment invent = ((LivingEntity)spawned).getEquipment();
if (data.contains("diamond"))
{
invent.setItemInHand(new ItemStack(Material.DIAMOND_SWORD, 1));
}
else if (data.contains("gold"))
{
invent.setItemInHand(new ItemStack(Material.GOLD_SWORD, 1));
}
else if (data.contains("iron"))
{
invent.setItemInHand(new ItemStack(Material.IRON_SWORD, 1));
}
else
{
invent.setItemInHand(new ItemStack(Material.STONE_SWORD, 1));
}
invent.setItemInHandDropChance(0.1f);
}
}
if (type == MobCompat.ZOMBIFIED_PIGLIN) {
final PigZombie zombie = (PigZombie) spawned;
setVillager(zombie, false);
if (type == EntityType.SKELETON)
{
if (data.contains("wither"))
{
((Skeleton)spawned).setSkeletonType(SkeletonType.WITHER);
}
}
final EntityEquipment invent = zombie.getEquipment();
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(GOLDEN_SWORD, 1));
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
}
if (type == EntityType.EXPERIENCE_ORB)
{
if (NumberUtil.isInt(data))
{
((ExperienceOrb)spawned).setExperience(Integer.parseInt(data));
if (type == EntityType.ZOMBIE) {
final Zombie zombie = (Zombie) spawned;
setVillager(zombie, false);
}
}
}
}
if (type == EntityType.HORSE) {
((Horse) spawned).setJumpStrength(1.2);
}
}
private static void defaultMobData(final EntityType type, final Entity spawned)
{
if (type == EntityType.SKELETON)
{
final EntityEquipment invent = ((LivingEntity)spawned).getEquipment();
invent.setItemInHand(new ItemStack(Material.BOW, 1));
invent.setItemInHandDropChance(0.1f);
invent.setBoots(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setBootsDropChance(0.0f);
}
if (type == EntityType.PIG_ZOMBIE)
{
final EntityEquipment invent = ((LivingEntity)spawned).getEquipment();
invent.setItemInHand(new ItemStack(Material.GOLD_SWORD, 1));
invent.setItemInHandDropChance(0.1f);
invent.setBoots(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setBootsDropChance(0.0f);
}
if (type == EntityType.ZOMBIE)
{
final EntityEquipment invent = ((LivingEntity)spawned).getEquipment();
invent.setBoots(new ItemStack(Material.GOLD_BOOTS, 1));
invent.setBootsDropChance(0.0f);
}
}
@SuppressWarnings("deprecation")
private static void setVillager(final Zombie zombie, final boolean villager) {
try {
zombie.setVillager(villager);
} catch (final Exception ignored) {
}
}
}
@@ -1,61 +1,51 @@
package com.earth2me.essentials;
import net.ess3.api.IEssentials;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
public class TNTExplodeListener implements Listener, Runnable {
private final transient IEssentials ess;
private transient boolean enabled = false;
private transient int timer = -1;
public class TNTExplodeListener implements Listener, Runnable
{
private final transient IEssentials ess;
private transient boolean enabled = false;
private transient int timer = -1;
public TNTExplodeListener(final IEssentials ess) {
super();
this.ess = ess;
}
public TNTExplodeListener(final IEssentials ess)
{
super();
this.ess = ess;
}
public void enable() {
if (!enabled) {
enabled = true;
timer = ess.scheduleSyncDelayedTask(this, 200);
return;
}
if (timer != -1) {
ess.getScheduler().cancelTask(timer);
timer = ess.scheduleSyncDelayedTask(this, 200);
}
}
public void enable()
{
if (!enabled)
{
enabled = true;
timer = ess.scheduleSyncDelayedTask(this, 200);
return;
}
if (timer != -1)
{
ess.getScheduler().cancelTask(timer);
timer = ess.scheduleSyncDelayedTask(this, 200);
}
}
@EventHandler(priority = EventPriority.LOW)
public void onEntityExplode(final EntityExplodeEvent event) {
if (!enabled) {
return;
}
if (event.getEntity() instanceof LivingEntity) {
return;
}
if (event.blockList().size() < 1) {
return;
}
event.setCancelled(true);
event.getLocation().getWorld().createExplosion(event.getLocation(), 0F);
}
@EventHandler(priority = EventPriority.LOW)
public void onEntityExplode(final EntityExplodeEvent event)
{
if (!enabled)
{
return;
}
if (event.getEntity() instanceof LivingEntity)
{
return;
}
if (event.blockList().size() < 1)
{
return;
}
event.setCancelled(true);
event.getLocation().getWorld().createExplosion(event.getLocation(), 0F);
}
@Override
public void run()
{
enabled = false;
}
@Override
public void run() {
enabled = false;
}
}
@@ -1,257 +1,403 @@
package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.api.ITeleport;
import com.earth2me.essentials.utils.DateUtil;
import com.earth2me.essentials.utils.LocationUtil;
import java.util.Calendar;
import java.util.GregorianCalendar;
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 net.ess3.api.events.teleport.PreTeleportEvent;
import net.ess3.api.events.teleport.TeleportWarmupEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class Teleport implements ITeleport
{
private final IUser teleportOwner;
private final IEssentials ess;
private TimedTeleport timedTeleport;
import static com.earth2me.essentials.I18n.tl;
public Teleport(IUser user, IEssentials ess)
{
this.teleportOwner = user;
this.ess = ess;
}
/**
* @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.AsyncTeleport AsyncTeleport}
*/
@Deprecated
public class Teleport implements ITeleport {
private final IUser teleportOwner;
private final IEssentials ess;
private TimedTeleport timedTeleport;
public void cooldown(boolean check) throws Exception
{
final Calendar time = new GregorianCalendar();
if (teleportOwner.getLastTeleportTimestamp() > 0)
{
// Take the current time, and remove the delay from it.
final double cooldown = ess.getSettings().getTeleportCooldown();
final Calendar earliestTime = new GregorianCalendar();
earliestTime.add(Calendar.SECOND, -(int)cooldown);
earliestTime.add(Calendar.MILLISECOND, -(int)((cooldown * 1000.0) % 1000.0));
// This value contains the most recent time a teleportPlayer could have been used that would allow another use.
final long earliestLong = earliestTime.getTimeInMillis();
private TeleportType tpType;
// When was the last teleportPlayer used?
final Long lastTime = teleportOwner.getLastTeleportTimestamp();
@Deprecated
public Teleport(final IUser user, final IEssentials ess) {
this.teleportOwner = user;
this.ess = ess;
tpType = TeleportType.NORMAL;
}
if (lastTime > time.getTimeInMillis())
{
// This is to make sure time didn't get messed up on last teleportPlayer use.
// If this happens, let's give the user the benifit of the doubt.
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
return;
}
else if (lastTime > earliestLong && !teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass"))
{
time.setTimeInMillis(lastTime);
time.add(Calendar.SECOND, (int)cooldown);
time.add(Calendar.MILLISECOND, (int)((cooldown * 1000.0) % 1000.0));
throw new Exception(_("timeBeforeTeleport", DateUtil.formatDateDiff(time.getTimeInMillis())));
}
}
// if justCheck is set, don't update lastTeleport; we're just checking
if (!check)
{
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
}
}
@Deprecated
public void cooldown(final boolean check) throws Exception {
final Calendar time = new GregorianCalendar();
if (teleportOwner.getLastTeleportTimestamp() > 0) {
// Take the current time, and remove the delay from it.
final double cooldown = ess.getSettings().getTeleportCooldown();
final Calendar earliestTime = new GregorianCalendar();
earliestTime.add(Calendar.SECOND, -(int) cooldown);
earliestTime.add(Calendar.MILLISECOND, -(int) ((cooldown * 1000.0) % 1000.0));
// This value contains the most recent time a teleportPlayer could have been used that would allow another use.
final long earliestLong = earliestTime.getTimeInMillis();
private void warnUser(final IUser user, final double delay)
{
Calendar c = new GregorianCalendar();
c.add(Calendar.SECOND, (int)delay);
c.add(Calendar.MILLISECOND, (int)((delay * 1000.0) % 1000.0));
user.sendMessage(_("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis())));
}
// When was the last teleportPlayer used?
final long lastTime = teleportOwner.getLastTeleportTimestamp();
//The now function is used when you want to skip tp delay when teleporting someone to a location or player.
@Override
public void now(Location loc, boolean cooldown, TeleportCause cause) throws Exception
{
if (cooldown)
{
cooldown(false);
}
now(teleportOwner, new LocationTarget(loc), cause);
}
if (lastTime > time.getTimeInMillis()) {
// This is to make sure time didn't get messed up on last teleportPlayer use.
// If this happens, let's give the user the benifit of the doubt.
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
return;
} else if (lastTime > earliestLong
&& cooldownApplies()) {
time.setTimeInMillis(lastTime);
time.add(Calendar.SECOND, (int) cooldown);
time.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0));
throw new Exception(tl("timeBeforeTeleport", DateUtil.formatDateDiff(time.getTimeInMillis())));
}
}
// if justCheck is set, don't update lastTeleport; we're just checking
if (!check) {
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
}
}
@Override
public void now(Player entity, boolean cooldown, TeleportCause cause) throws Exception
{
if (cooldown)
{
cooldown(false);
}
now(teleportOwner, new PlayerTarget(entity), cause);
}
@Deprecated
private boolean cooldownApplies() {
boolean applies = true;
final String globalBypassPerm = "essentials.teleport.cooldown.bypass";
switch (tpType) {
case NORMAL:
applies = !teleportOwner.isAuthorized(globalBypassPerm);
break;
case BACK:
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.back"));
break;
case TPA:
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.tpa"));
break;
}
return applies;
}
protected void now(IUser teleportee, ITarget target, TeleportCause cause) throws Exception
{
cancel(false);
teleportee.setLastLocation();
teleportee.getBase().teleport(LocationUtil.getSafeDestination(target.getLocation()), cause);
}
@Deprecated
private void warnUser(final IUser user, final double delay) {
final Calendar c = new GregorianCalendar();
c.add(Calendar.SECOND, (int) delay);
c.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0));
user.sendMessage(tl("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis())));
}
//The teleportPlayer function is used when you want to normally teleportPlayer someone to a location or player.
//This method is nolonger used internally and will be removed.
@Deprecated
public void teleport(Location loc, Trade chargeFor) throws Exception
{
teleport(loc, chargeFor, TeleportCause.PLUGIN);
}
//The now function is used when you want to skip tp delay when teleporting someone to a location or player.
@Override
@Deprecated
public void now(final Location loc, final boolean cooldown, final TeleportCause cause) throws Exception {
if (cooldown) {
cooldown(false);
}
final ITarget target = new LocationTarget(loc);
now(teleportOwner, target, cause);
}
@Override
public void teleport(Location loc, Trade chargeFor, TeleportCause cause) throws Exception
{
teleport(teleportOwner, new LocationTarget(loc), chargeFor, cause);
}
@Override
@Deprecated
public void now(final Player entity, final boolean cooldown, final TeleportCause cause) throws Exception {
if (cooldown) {
cooldown(false);
}
final ITarget target = new PlayerTarget(entity);
now(teleportOwner, target, cause);
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
}
@Override
public void teleport(Player entity, Trade chargeFor, TeleportCause cause) throws Exception
{
teleport(teleportOwner, new PlayerTarget(entity), chargeFor, cause);
}
@Deprecated
protected void now(final IUser teleportee, final ITarget target, final TeleportCause cause) throws Exception {
cancel(false);
Location loc = target.getLocation();
@Override
public void teleportPlayer(IUser teleportee, Location loc, Trade chargeFor, TeleportCause cause) throws Exception
{
teleport(teleportee, new LocationTarget(loc), chargeFor, cause);
}
final PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
@Override
public void teleportPlayer(IUser teleportee, Player entity, Trade chargeFor, TeleportCause cause) throws Exception
{
teleport(teleportee, new PlayerTarget(entity), chargeFor, cause);
}
if (teleportee.isAuthorized("essentials.back.onteleport")) {
teleportee.setLastLocation();
}
private void teleport(IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause) throws Exception
{
double delay = ess.getSettings().getTeleportDelay();
if (!teleportee.getBase().isEmpty()) {
if (!ess.getSettings().isTeleportPassengerDismount()) {
throw new Exception(tl("passengerTeleportFail"));
}
teleportee.getBase().eject();
}
if (chargeFor != null)
{
chargeFor.isAffordableFor(teleportOwner);
}
cooldown(true);
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass")
|| teleportee.isAuthorized("essentials.teleport.timer.bypass"))
{
cooldown(false);
now(teleportee, target, cause);
if (chargeFor != null)
{
chargeFor.charge(teleportOwner);
}
return;
}
if (LocationUtil.isBlockUnsafeForUser(teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
if (ess.getSettings().isTeleportSafetyEnabled()) {
if (ess.getSettings().isForceDisableTeleportSafety()) {
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
} else {
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()) {
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
} else {
if (ess.getSettings().isTeleportToCenterLocation()) {
loc = LocationUtil.getRoundedDestination(loc);
}
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
}
}
}
cancel(false);
warnUser(teleportee, delay);
initTimer((long)(delay * 1000.0), teleportee, target, chargeFor, cause, false);
}
//The teleportPlayer function is used when you want to normally teleportPlayer someone to a location or player.
//This method is nolonger used internally and will be removed.
@Deprecated
@Override
public void teleport(final Location loc, final Trade chargeFor) throws Exception {
teleport(loc, chargeFor, TeleportCause.PLUGIN);
}
//The teleportToMe function is a wrapper used to handle teleporting players to them, like /tphere
@Override
public void teleportToMe(IUser otherUser, Trade chargeFor, TeleportCause cause) throws Exception
{
ITarget target = new PlayerTarget(teleportOwner);
teleport(otherUser, target, chargeFor, cause);
}
@Override
@Deprecated
public void teleport(final Location loc, final Trade chargeFor, final TeleportCause cause) throws Exception {
teleport(teleportOwner, new LocationTarget(loc), chargeFor, cause);
}
//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
{
double delay = ess.getSettings().getTeleportDelay();
if (chargeFor != null)
{
chargeFor.isAffordableFor(teleportOwner);
}
cooldown(true);
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass"))
{
cooldown(false);
respawnNow(teleportOwner, cause);
if (chargeFor != null)
{
chargeFor.charge(teleportOwner);
}
return;
}
//This is used when teleporting to a player
@Override
@Deprecated
public void teleport(final Player entity, final Trade chargeFor, final TeleportCause cause) throws Exception {
final ITarget target = new PlayerTarget(entity);
teleportOwner.sendMessage(tl("teleportToPlayer", entity.getDisplayName()));
teleport(teleportOwner, target, chargeFor, cause);
}
cancel(false);
warnUser(teleportOwner, delay);
initTimer((long)(delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
}
//This is used when teleporting to stored location
@Override
@Deprecated
public void teleportPlayer(final IUser teleportee, final Location loc, final Trade chargeFor, final TeleportCause cause) throws Exception {
teleport(teleportee, new LocationTarget(loc), chargeFor, cause);
}
protected void respawnNow(IUser teleportee, TeleportCause cause) throws Exception
{
final Player player = teleportee.getBase();
Location bed = player.getBedSpawnLocation();
if (bed != null)
{
now(teleportee, new LocationTarget(bed), cause);
}
else
{
if (ess.getSettings().isDebug())
{
ess.getLogger().info("Could not find bed spawn, forcing respawn event.");
}
final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, player.getWorld().getSpawnLocation(), false);
ess.getServer().getPluginManager().callEvent(pre);
now(teleportee, new LocationTarget(pre.getRespawnLocation()), cause);
}
}
//This is used on /tphere
@Override
@Deprecated
public void teleportPlayer(final IUser teleportee, final Player entity, final Trade chargeFor, final TeleportCause cause) throws Exception {
final ITarget target = new PlayerTarget(entity);
teleport(teleportee, target, chargeFor, cause);
teleportee.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
}
//The warp function is a wrapper used to teleportPlayer a player to a /warp
@Override
public void warp(IUser teleportee, String warp, Trade chargeFor, TeleportCause cause) throws Exception
{
Location loc = ess.getWarps().getWarp(warp);
teleportee.sendMessage(_("warpingTo", warp));
teleport(teleportee, new LocationTarget(loc), chargeFor, cause);
}
@Deprecated
private void teleport(final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause) throws Exception {
double delay = ess.getSettings().getTeleportDelay();
//The back function is a wrapper used to teleportPlayer a player /back to their previous location.
@Override
public void back(Trade chargeFor) throws Exception
{
teleport(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), chargeFor, TeleportCause.COMMAND);
}
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
delay = event.getDelay();
//This function is used to throw a user back after a jail sentence
@Override
public void back() throws Exception
{
now(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND);
}
Trade cashCharge = chargeFor;
//This function handles teleporting to /home
@Override
public void home(Location loc, Trade chargeFor) throws Exception
{
teleport(teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND);
}
if (chargeFor != null) {
chargeFor.isAffordableFor(teleportOwner);
//If we need to cancelTimer a pending teleportPlayer call this method
private void cancel(boolean notifyUser)
{
if (timedTeleport != null)
{
timedTeleport.cancelTimer(notifyUser);
timedTeleport = null;
}
}
//This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world.
if (!chargeFor.getCommandCost(teleportOwner).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(teleportOwner), ess);
}
}
private void initTimer(long delay, IUser teleportUser, ITarget target, Trade chargeFor, TeleportCause cause, boolean respawn)
{
timedTeleport = new TimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn);
}
cooldown(true);
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass") || teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
cooldown(false);
now(teleportee, target, cause);
if (cashCharge != null) {
cashCharge.charge(teleportOwner);
}
return;
}
cancel(false);
warnUser(teleportee, delay);
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
}
@Deprecated
private void teleportOther(final IUser teleporter, final IUser teleportee, final ITarget target, final Trade chargeFor, final TeleportCause cause) throws Exception {
double delay = ess.getSettings().getTeleportDelay();
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleporter, teleportee, cause, target, delay);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
delay = event.getDelay();
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
@Deprecated
public void respawn(final Trade chargeFor, final TeleportCause cause) throws Exception {
double delay = ess.getSettings().getTeleportDelay();
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
delay = event.getDelay();
if (chargeFor != null) {
chargeFor.isAffordableFor(teleportOwner);
}
cooldown(true);
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass")) {
cooldown(false);
respawnNow(teleportOwner, cause);
if (chargeFor != null) {
chargeFor.charge(teleportOwner);
}
return;
}
cancel(false);
warnUser(teleportOwner, delay);
initTimer((long) (delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
}
@Deprecated
void respawnNow(final IUser teleportee, final TeleportCause cause) throws Exception {
final Player player = teleportee.getBase();
final Location bed = player.getBedSpawnLocation();
if (bed != null) {
now(teleportee, new LocationTarget(bed), cause);
} else {
if (ess.getSettings().isDebug()) {
ess.getLogger().info("Could not find bed spawn, forcing respawn event.");
}
final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, player.getWorld().getSpawnLocation(), false);
ess.getServer().getPluginManager().callEvent(pre);
now(teleportee, new LocationTarget(pre.getRespawnLocation()), cause);
}
}
//The warp function is a wrapper used to teleportPlayer a player to a /warp
@Override
@Deprecated
public void warp(final IUser teleportee, String warp, final Trade chargeFor, final TeleportCause cause) throws Exception {
final UserWarpEvent event = new UserWarpEvent(teleportee, warp, chargeFor);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
warp = event.getWarp();
final Location loc = ess.getWarps().getWarp(warp);
teleportee.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
if (!teleportee.equals(teleportOwner)) {
teleportOwner.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
}
teleport(teleportee, new LocationTarget(loc), chargeFor, cause);
}
//The back function is a wrapper used to teleportPlayer a player /back to their previous location.
@Override
@Deprecated
public void back(final 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
@Deprecated
public void back(final IUser teleporter, final 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()));
teleportOther(teleporter, teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND);
}
//This function is used to throw a user back after a jail sentence
@Override
@Deprecated
public void back() throws Exception {
now(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND);
}
@Deprecated
public void setTpType(final TeleportType tpType) {
this.tpType = tpType;
}
//If we need to cancelTimer a pending teleportPlayer call this method
@Deprecated
private void cancel(final boolean notifyUser) {
if (timedTeleport != null) {
timedTeleport.cancelTimer(notifyUser);
timedTeleport = null;
}
}
@Deprecated
private void initTimer(final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
timedTeleport = new TimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn);
}
public enum TeleportType {
TPA,
BACK,
NORMAL
}
}
@@ -1,153 +1,140 @@
package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._;
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import org.bukkit.Location;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.UUID;
public class TimedTeleport implements Runnable
{
private static final double MOVE_CONSTANT = 0.3;
private final IUser teleportOwner;
private final IEssentials ess;
private final Teleport teleport;
private String timer_teleportee;
private int timer_task = -1;
private long timer_started; // time this task was initiated
private long timer_delay; // how long to delay the teleportPlayer
private int 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)
// so, the X/Y/Z values are stored instead and rounded off
private long timer_initX;
private long timer_initY;
private long timer_initZ;
private ITarget timer_teleportTarget;
private boolean timer_respawn;
private boolean timer_canMove;
private Trade timer_chargeFor;
private TeleportCause timer_cause;
import static com.earth2me.essentials.I18n.tl;
public TimedTeleport(IUser user, IEssentials ess, Teleport teleport, long delay, IUser teleportUser, ITarget target, Trade chargeFor, TeleportCause cause, boolean respawn)
{
@Deprecated
public class TimedTeleport implements Runnable {
private static final double MOVE_CONSTANT = 0.3;
private final IUser teleportOwner;
private final IEssentials ess;
private final Teleport teleport;
private final UUID timer_teleportee;
private final long timer_started; // time this task was initiated
private final long timer_delay; // how long to delay the teleportPlayer
// note that I initially stored a clone of the location for reference, but...
// when comparing locations, I got incorrect mismatches (rounding errors, looked like)
// so, the X/Y/Z values are stored instead and rounded off
private final long timer_initX;
private final long timer_initY;
private final long timer_initZ;
private final ITarget timer_teleportTarget;
private final boolean timer_respawn;
private final boolean timer_canMove;
private final Trade timer_chargeFor;
private final TeleportCause timer_cause;
private int timer_task;
private double timer_health;
this.teleportOwner = user;
this.ess = ess;
this.teleport = teleport;
this.timer_started = System.currentTimeMillis();
this.timer_delay = delay;
this.timer_health = teleportUser.getHealth();
this.timer_initX = Math.round(teleportUser.getLocation().getX() * MOVE_CONSTANT);
this.timer_initY = Math.round(teleportUser.getLocation().getY() * MOVE_CONSTANT);
this.timer_initZ = Math.round(teleportUser.getLocation().getZ() * MOVE_CONSTANT);
this.timer_teleportee = teleportUser.getName();
this.timer_teleportTarget = target;
this.timer_chargeFor = chargeFor;
this.timer_cause = cause;
this.timer_respawn = respawn;
this.timer_canMove = user.isAuthorized("essentials.teleport.timer.move");
TimedTeleport(final IUser user, final IEssentials ess, final Teleport teleport, final long delay, final IUser teleportUser, final ITarget target, final Trade chargeFor, final TeleportCause cause, final boolean respawn) {
this.teleportOwner = user;
this.ess = ess;
this.teleport = teleport;
this.timer_started = System.currentTimeMillis();
this.timer_delay = delay;
this.timer_health = teleportUser.getBase().getHealth();
this.timer_initX = Math.round(teleportUser.getBase().getLocation().getX() * MOVE_CONSTANT);
this.timer_initY = Math.round(teleportUser.getBase().getLocation().getY() * MOVE_CONSTANT);
this.timer_initZ = Math.round(teleportUser.getBase().getLocation().getZ() * MOVE_CONSTANT);
this.timer_teleportee = teleportUser.getBase().getUniqueId();
this.timer_teleportTarget = target;
this.timer_chargeFor = chargeFor;
this.timer_cause = cause;
this.timer_respawn = respawn;
this.timer_canMove = user.isAuthorized("essentials.teleport.timer.move");
timer_task = ess.scheduleSyncRepeatingTask(this, 20, 20);
}
timer_task = ess.runTaskTimerAsynchronously(this, 20, 20).getTaskId();
}
@Override
public void run()
{
@Override
public void run() {
if (teleportOwner == null || !teleportOwner.isOnline() || teleportOwner.getLocation() == null)
{
cancelTimer(false);
return;
}
if (teleportOwner == null || !teleportOwner.getBase().isOnline() || teleportOwner.getBase().getLocation() == null) {
cancelTimer(false);
return;
}
IUser teleportUser = ess.getUser(this.timer_teleportee);
final IUser teleportUser = ess.getUser(this.timer_teleportee);
if (teleportUser == null || !teleportUser.isOnline())
{
cancelTimer(false);
return;
}
if (teleportUser == null || !teleportUser.getBase().isOnline()) {
cancelTimer(false);
return;
}
final Location currLocation = teleportUser.getLocation();
if (currLocation == null)
{
cancelTimer(false);
return;
}
final Location currLocation = teleportUser.getBase().getLocation();
if (currLocation == null) {
cancelTimer(false);
return;
}
if (!timer_canMove
&& (Math.round(currLocation.getX() * MOVE_CONSTANT) != timer_initX
|| Math.round(currLocation.getY() * MOVE_CONSTANT) != timer_initY
|| Math.round(currLocation.getZ() * MOVE_CONSTANT) != timer_initZ
|| teleportUser.getHealth() < timer_health))
{
// user moved, cancelTimer teleportPlayer
cancelTimer(true);
return;
}
if (!timer_canMove && (Math.round(currLocation.getX() * MOVE_CONSTANT) != timer_initX || Math.round(currLocation.getY() * MOVE_CONSTANT) != timer_initY || Math.round(currLocation.getZ() * MOVE_CONSTANT) != timer_initZ || teleportUser.getBase().getHealth() < timer_health)) {
// user moved, cancelTimer teleportPlayer
cancelTimer(true);
return;
}
timer_health = teleportUser.getHealth(); // in case user healed, then later gets injured
final long now = System.currentTimeMillis();
if (now > timer_started + timer_delay)
{
try
{
teleport.cooldown(false);
teleportUser.sendMessage(_("teleportationCommencing"));
try
{
if (timer_respawn)
{
teleport.respawnNow(teleportUser, timer_cause);
}
else
{
teleport.now(teleportUser, timer_teleportTarget, timer_cause);
}
cancelTimer(false);
if (timer_chargeFor != null)
{
timer_chargeFor.charge(teleportOwner);
}
}
catch (Throwable ex)
{
ess.showError(teleportOwner.getBase(), ex, "teleport");
}
}
catch (Exception ex)
{
teleportOwner.sendMessage(_("cooldownWithMessage", ex.getMessage()));
if (teleportOwner != teleportUser)
{
teleportUser.sendMessage(_("cooldownWithMessage", ex.getMessage()));
}
}
}
}
class DelayedTeleportTask implements Runnable {
@Override
public void run() {
//If we need to cancelTimer a pending teleportPlayer call this method
public void cancelTimer(boolean notifyUser)
{
if (timer_task == -1)
{
return;
}
try
{
ess.getServer().getScheduler().cancelTask(timer_task);
if (notifyUser)
{
teleportOwner.sendMessage(_("pendingTeleportCancelled"));
if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getName()))
{
ess.getUser(timer_teleportee).sendMessage(_("pendingTeleportCancelled"));
}
}
}
finally
{
timer_task = -1;
}
}
timer_health = teleportUser.getBase().getHealth(); // in case user healed, then later gets injured
final long now = System.currentTimeMillis();
if (now > timer_started + timer_delay) {
try {
teleport.cooldown(false);
} catch (final Exception ex) {
teleportOwner.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
if (teleportOwner != teleportUser) {
teleportUser.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
}
}
try {
cancelTimer(false);
teleportUser.sendMessage(tl("teleportationCommencing"));
if (timer_chargeFor != null) {
timer_chargeFor.isAffordableFor(teleportOwner);
}
if (timer_respawn) {
teleport.respawnNow(teleportUser, timer_cause);
} else {
teleport.now(teleportUser, timer_teleportTarget, timer_cause);
}
if (timer_chargeFor != null) {
timer_chargeFor.charge(teleportOwner);
}
} catch (final Exception ex) {
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
}
}
}
}
ess.scheduleSyncDelayedTask(new DelayedTeleportTask());
}
//If we need to cancelTimer a pending teleportPlayer call this method
void cancelTimer(final boolean notifyUser) {
if (timer_task == -1) {
return;
}
try {
ess.getServer().getScheduler().cancelTask(timer_task);
if (notifyUser) {
teleportOwner.sendMessage(tl("pendingTeleportCancelled"));
if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getBase().getUniqueId())) {
ess.getUser(timer_teleportee).sendMessage(tl("pendingTeleportCancelled"));
}
}
} finally {
timer_task = -1;
}
}
}
+339 -396
View File
@@ -1,8 +1,15 @@
package com.earth2me.essentials;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
import com.earth2me.essentials.craftbukkit.SetExpFix;
import com.earth2me.essentials.utils.NumberUtil;
import net.ess3.api.IEssentials;
import net.ess3.api.IUser;
import net.ess3.api.MaxMoneyException;
import org.bukkit.Location;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
@@ -11,438 +18,374 @@ import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Location;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
import static com.earth2me.essentials.I18n.tl;
public class Trade
{
private final transient String command;
private final transient Trade fallbackTrade;
private final transient BigDecimal money;
private final transient ItemStack itemStack;
private final transient Integer exp;
private final transient IEssentials ess;
public class Trade {
private static FileWriter fw = null;
private final transient String command;
private final transient Trade fallbackTrade;
private final transient BigDecimal money;
private final transient ItemStack itemStack;
private final transient Integer exp;
private final transient IEssentials ess;
public Trade(final String command, final IEssentials ess) {
this(command, null, null, null, null, ess);
}
public enum TradeType
{
MONEY,
EXP,
ITEM
}
public Trade(final String command, final Trade fallback, final IEssentials ess) {
this(command, fallback, null, null, null, ess);
}
@Deprecated
public Trade(final double money, final com.earth2me.essentials.IEssentials ess) {
this(null, null, BigDecimal.valueOf(money), null, null, (IEssentials) ess);
}
public enum OverflowType
{
ABORT,
DROP,
RETURN
}
public Trade(final BigDecimal money, final IEssentials ess) {
this(null, null, money, null, null, ess);
}
public Trade(final String command, final IEssentials ess)
{
this(command, null, null, null, null, ess);
}
public Trade(final ItemStack items, final IEssentials ess) {
this(null, null, null, items, null, ess);
}
public Trade(final String command, final Trade fallback, final IEssentials ess)
{
this(command, fallback, null, null, null, ess);
}
public Trade(final int exp, final IEssentials ess) {
this(null, null, null, null, exp, ess);
}
@Deprecated
public Trade(final double money, final IEssentials ess)
{
this(null, null, BigDecimal.valueOf(money), null, null, ess);
}
private Trade(final String command, final Trade fallback, final BigDecimal money, final ItemStack item, final Integer exp, final IEssentials ess) {
this.command = command;
this.fallbackTrade = fallback;
this.money = money;
this.itemStack = item;
this.exp = exp;
this.ess = ess;
}
public Trade(final BigDecimal money, final IEssentials ess)
{
this(null, null, money, null, null, ess);
}
public static void log(final String type, final String subtype, final String event, final String sender, final Trade charge, final String receiver, final Trade pay, final Location loc, final IEssentials ess) {
//isEcoLogUpdateEnabled() - This refers to log entries with no location, ie API updates #EasterEgg
//isEcoLogEnabled() - This refers to log entries with with location, ie /pay /sell and eco signs.
public Trade(final ItemStack items, final IEssentials ess)
{
this(null, null, null, items, null, ess);
}
if ((loc == null && !ess.getSettings().isEcoLogUpdateEnabled()) || (loc != null && !ess.getSettings().isEcoLogEnabled())) {
return;
}
if (fw == null) {
try {
fw = new FileWriter(new File(ess.getDataFolder(), "trade.log"), true);
} catch (final IOException ex) {
Logger.getLogger("Essentials").log(Level.SEVERE, null, ex);
}
}
final StringBuilder sb = new StringBuilder();
sb.append(type).append(",").append(subtype).append(",").append(event).append(",\"");
sb.append(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
sb.append("\",\"");
if (sender != null) {
sb.append(sender);
}
sb.append("\",");
if (charge == null) {
sb.append("\"\",\"\",\"\"");
} else {
if (charge.getItemStack() != null) {
sb.append(charge.getItemStack().getAmount()).append(",");
sb.append(charge.getItemStack().getType().toString()).append(",");
sb.append(charge.getItemStack().getDurability());
}
if (charge.getMoney() != null) {
sb.append(charge.getMoney()).append(",");
sb.append("money").append(",");
sb.append(ess.getSettings().getCurrencySymbol());
}
if (charge.getExperience() != null) {
sb.append(charge.getExperience()).append(",");
sb.append("exp").append(",");
sb.append("\"\"");
}
}
sb.append(",\"");
if (receiver != null) {
sb.append(receiver);
}
sb.append("\",");
if (pay == null) {
sb.append("\"\",\"\",\"\"");
} else {
if (pay.getItemStack() != null) {
sb.append(pay.getItemStack().getAmount()).append(",");
sb.append(pay.getItemStack().getType().toString()).append(",");
sb.append(pay.getItemStack().getDurability());
}
if (pay.getMoney() != null) {
sb.append(pay.getMoney()).append(",");
sb.append("money").append(",");
sb.append(ess.getSettings().getCurrencySymbol());
}
if (pay.getExperience() != null) {
sb.append(pay.getExperience()).append(",");
sb.append("exp").append(",");
sb.append("\"\"");
}
}
if (loc == null) {
sb.append(",\"\",\"\",\"\",\"\"");
} else {
sb.append(",\"");
sb.append(loc.getWorld().getName()).append("\",");
sb.append(loc.getBlockX()).append(",");
sb.append(loc.getBlockY()).append(",");
sb.append(loc.getBlockZ()).append(",");
}
sb.append("\n");
try {
fw.write(sb.toString());
fw.flush();
} catch (final IOException ex) {
Logger.getLogger("Essentials").log(Level.SEVERE, null, ex);
}
}
public Trade(final int exp, final IEssentials ess)
{
this(null, null, null, null, exp, ess);
}
public static void closeLog() {
if (fw != null) {
try {
fw.close();
} catch (final IOException ex) {
Logger.getLogger("Essentials").log(Level.SEVERE, null, ex);
}
fw = null;
}
}
private Trade(final String command, final Trade fallback, final BigDecimal money, final ItemStack item, final Integer exp, final IEssentials ess)
{
this.command = command;
this.fallbackTrade = fallback;
this.money = money;
this.itemStack = item;
this.exp = exp;
this.ess = ess;
}
public void isAffordableFor(final IUser user) throws ChargeException {
final CompletableFuture<Boolean> future = new CompletableFuture<>();
isAffordableFor(user, future);
if (future.isCompletedExceptionally()) {
try {
future.get();
} catch (final InterruptedException e) { //If this happens, we have bigger problems...
e.printStackTrace();
} catch (final ExecutionException e) {
throw (ChargeException) e.getCause();
}
}
}
public void isAffordableFor(final IUser user) throws ChargeException
{
public void isAffordableFor(final IUser user, final CompletableFuture<Boolean> future) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "checking if " + user.getName() + " can afford charge.");
}
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "checking if " + user.getName() + " can afford charge.");
}
if (getMoney() != null && getMoney().signum() > 0 && !user.canAfford(getMoney())) {
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess))));
return;
}
if (getMoney() != null
&& getMoney().signum() > 0
&& !user.canAfford(getMoney()))
{
throw new ChargeException(_("notEnoughMoney"));
}
if (getItemStack() != null && !user.getBase().getInventory().containsAtLeast(itemStack, itemStack.getAmount())) {
future.completeExceptionally(new ChargeException(tl("missingItems", getItemStack().getAmount(), ess.getItemDb().name(getItemStack()))));
return;
}
if (getItemStack() != null
&& !user.getInventory().containsAtLeast(itemStack, itemStack.getAmount()))
{
throw new ChargeException(_("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " ")));
}
final BigDecimal money;
if (command != null && !command.isEmpty() && (money = getCommandCost(user)).signum() > 0 && !user.canAfford(money)) {
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(money, ess))));
return;
}
BigDecimal money;
if (command != null && !command.isEmpty()
&& (money = getCommandCost(user)).signum() > 0
&& !user.canAfford(money))
{
throw new ChargeException(_("notEnoughMoney"));
}
if (exp != null && exp > 0 && SetExpFix.getTotalExperience(user.getBase()) < exp) {
future.completeExceptionally(new ChargeException(tl("notEnoughExperience")));
}
}
if (exp != null && exp > 0
&& SetExpFix.getTotalExperience(user) < exp)
{
throw new ChargeException(_("notEnoughExperience"));
}
}
public boolean pay(final IUser user) throws MaxMoneyException {
return pay(user, OverflowType.ABORT) == null;
}
public boolean pay(final IUser user)
{
return pay(user, OverflowType.ABORT) == null;
}
public Map<Integer, ItemStack> pay(final IUser user, final OverflowType type) throws MaxMoneyException {
if (getMoney() != null && getMoney().signum() > 0) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "paying user " + user.getName() + " via trade " + getMoney().toPlainString());
}
user.giveMoney(getMoney());
}
if (getItemStack() != null) {
// This stores the would be overflow
final Map<Integer, ItemStack> overFlow = InventoryWorkaround.addAllItems(user.getBase().getInventory(), getItemStack());
public Map<Integer, ItemStack> pay(final IUser user, final OverflowType type)
{
if (getMoney() != null && getMoney().signum() > 0)
{
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "paying user " + user.getName() + " via trade " + getMoney().toPlainString());
}
user.giveMoney(getMoney());
}
if (getItemStack() != null)
{
// This stores the would be overflow
Map<Integer, ItemStack> overFlow = InventoryWorkaround.addAllItems(user.getInventory(), getItemStack());
if (overFlow != null) {
switch (type) {
case ABORT:
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "abort paying " + user.getName() + " itemstack " + getItemStack().toString() + " due to lack of inventory space ");
}
if (overFlow != null)
{
switch (type)
{
case ABORT:
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "abort paying " + user.getName() + " itemstack " + getItemStack().toString() + " due to lack of inventory space ");
}
return overFlow;
return overFlow;
case RETURN:
// Pay the user the items, and return overflow
final Map<Integer, ItemStack> returnStack = InventoryWorkaround.addItems(user.getBase().getInventory(), getItemStack());
user.getBase().updateInventory();
case RETURN:
// Pay the user the items, and return overflow
final Map<Integer, ItemStack> returnStack = InventoryWorkaround.addItems(user.getInventory(), getItemStack());
user.updateInventory();
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " with overflow " + returnStack.get(0).toString());
}
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " with overflow " + returnStack.get(0).toString());
}
return returnStack;
case DROP:
// Pay the users the items directly, and drop the rest, will always return no overflow.
final Map<Integer, ItemStack> leftOver = InventoryWorkaround.addItems(user.getBase().getInventory(), getItemStack());
final Location loc = user.getBase().getLocation();
for (final ItemStack loStack : leftOver.values()) {
final int maxStackSize = loStack.getType().getMaxStackSize();
final int stacks = loStack.getAmount() / maxStackSize;
final int leftover = loStack.getAmount() % maxStackSize;
final Item[] itemStacks = new Item[stacks + (leftover > 0 ? 1 : 0)];
for (int i = 0; i < stacks; i++) {
final ItemStack stack = loStack.clone();
stack.setAmount(maxStackSize);
itemStacks[i] = loc.getWorld().dropItem(loc, stack);
}
if (leftover > 0) {
final ItemStack stack = loStack.clone();
stack.setAmount(leftover);
itemStacks[stacks] = loc.getWorld().dropItem(loc, stack);
}
}
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " and dropping overflow " + leftOver.get(0).toString());
}
break;
}
} else if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " itemstack " + getItemStack().toString());
}
user.getBase().updateInventory();
}
if (getExperience() != null) {
SetExpFix.setTotalExperience(user.getBase(), SetExpFix.getTotalExperience(user.getBase()) + getExperience());
}
return null;
}
return returnStack;
public void charge(final IUser user) throws ChargeException {
final CompletableFuture<Boolean> future = new CompletableFuture<>();
charge(user, future);
if (future.isCompletedExceptionally()) {
try {
future.get();
} catch (final InterruptedException e) { //If this happens, we have bigger problems...
e.printStackTrace();
} catch (final ExecutionException e) {
throw (ChargeException) e.getCause();
}
}
}
case DROP:
// Pay the users the items directly, and drop the rest, will always return no overflow.
final Map<Integer, ItemStack> leftOver = InventoryWorkaround.addItems(user.getInventory(), getItemStack());
final Location loc = user.getLocation();
for (ItemStack loStack : leftOver.values())
{
final int maxStackSize = loStack.getType().getMaxStackSize();
final int stacks = loStack.getAmount() / maxStackSize;
final int leftover = loStack.getAmount() % maxStackSize;
final Item[] itemStacks = new Item[stacks + (leftover > 0 ? 1 : 0)];
for (int i = 0; i < stacks; i++)
{
final ItemStack stack = loStack.clone();
stack.setAmount(maxStackSize);
itemStacks[i] = loc.getWorld().dropItem(loc, stack);
}
if (leftover > 0)
{
final ItemStack stack = loStack.clone();
stack.setAmount(leftover);
itemStacks[stacks] = loc.getWorld().dropItem(loc, stack);
}
}
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " partial itemstack " + getItemStack().toString() + " and dropping overflow " + leftOver.get(0).toString());
}
}
}
else if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "paying " + user.getName() + " itemstack " + getItemStack().toString());
}
user.updateInventory();
}
if (getExperience() != null)
{
SetExpFix.setTotalExperience(user, SetExpFix.getTotalExperience(user) + getExperience());
}
return null;
}
public void charge(final IUser user, final CompletableFuture<Boolean> future) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "attempting to charge user " + user.getName());
}
if (getMoney() != null) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " money " + getMoney().toPlainString());
}
if (!user.canAfford(getMoney()) && getMoney().signum() > 0) {
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess))));
return;
}
user.takeMoney(getMoney());
}
if (getItemStack() != null) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemstack " + getItemStack().toString());
}
if (!user.getBase().getInventory().containsAtLeast(getItemStack(), getItemStack().getAmount())) {
future.completeExceptionally(new ChargeException(tl("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " "))));
return;
}
user.getBase().getInventory().removeItem(getItemStack());
user.getBase().updateInventory();
}
if (command != null) {
final BigDecimal cost = getCommandCost(user);
if (!user.canAfford(cost) && cost.signum() > 0) {
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(cost, ess))));
return;
}
user.takeMoney(cost);
}
if (getExperience() != null) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " exp " + getExperience());
}
final int experience = SetExpFix.getTotalExperience(user.getBase());
if (experience < getExperience() && getExperience() > 0) {
future.completeExceptionally(new ChargeException(tl("notEnoughExperience")));
return;
}
SetExpFix.setTotalExperience(user.getBase(), experience - getExperience());
}
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "charge user " + user.getName() + " completed");
}
}
public void charge(final IUser user) throws ChargeException
{
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "attempting to charge user " + user.getName());
}
if (getMoney() != null)
{
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " money " + getMoney().toPlainString());
}
if (!user.canAfford(getMoney()) && getMoney().signum() > 0)
{
throw new ChargeException(_("notEnoughMoney"));
}
user.takeMoney(getMoney());
}
if (getItemStack() != null)
{
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemstack " + getItemStack().toString());
}
if (!user.getInventory().containsAtLeast(getItemStack(), getItemStack().getAmount()))
{
throw new ChargeException(_("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " ")));
}
user.getInventory().removeItem(getItemStack());
user.updateInventory();
}
if (command != null)
{
final BigDecimal cost = getCommandCost(user);
if (!user.canAfford(cost) && cost.signum() > 0)
{
throw new ChargeException(_("notEnoughMoney"));
}
user.takeMoney(cost);
}
if (getExperience() != null)
{
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " exp " + getExperience());
}
final int experience = SetExpFix.getTotalExperience(user);
if (experience < getExperience() && getExperience() > 0)
{
throw new ChargeException(_("notEnoughExperience"));
}
SetExpFix.setTotalExperience(user, experience - getExperience());
}
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "charge user " + user.getName() + " completed");
}
}
public BigDecimal getMoney() {
return money;
}
public BigDecimal getMoney()
{
return money;
}
public ItemStack getItemStack() {
return itemStack;
}
public ItemStack getItemStack()
{
return itemStack;
}
public Integer getExperience() {
return exp;
}
public Integer getExperience()
{
return exp;
}
public TradeType getType() {
if (getExperience() != null) {
return TradeType.EXP;
}
public TradeType getType()
{
if (getExperience() != null)
{
return TradeType.EXP;
}
if (getItemStack() != null) {
return TradeType.ITEM;
}
if (getItemStack() != null)
{
return TradeType.ITEM;
}
return TradeType.MONEY;
}
return TradeType.MONEY;
}
public BigDecimal getCommandCost(final IUser user) {
BigDecimal cost = BigDecimal.ZERO;
if (command != null && !command.isEmpty()) {
cost = ess.getSettings().getCommandCost(command.charAt(0) == '/' ? command.substring(1) : command);
if (cost.signum() == 0 && fallbackTrade != null) {
cost = fallbackTrade.getCommandCost(user);
}
public BigDecimal getCommandCost(final IUser user)
{
BigDecimal cost = BigDecimal.ZERO;
if (command != null && !command.isEmpty())
{
cost = ess.getSettings().getCommandCost(command.charAt(0) == '/' ? command.substring(1) : command);
if (cost.signum() == 0 && fallbackTrade != null)
{
cost = fallbackTrade.getCommandCost(user);
}
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "calculated command (" + command + ") cost for " + user.getName() + " as " + cost);
}
}
if (cost.signum() != 0 && (user.isAuthorized("essentials.nocommandcost.all") || user.isAuthorized("essentials.nocommandcost." + command))) {
return BigDecimal.ZERO;
}
return cost;
}
if (ess.getSettings().isDebug())
{
ess.getLogger().log(Level.INFO, "calculated command (" + command + ") cost for " + user.getName() + " as " + cost);
}
}
if (cost.signum() != 0 && (user.isAuthorized("essentials.nocommandcost.all")
|| user.isAuthorized("essentials.nocommandcost." + command)))
{
return BigDecimal.ZERO;
}
return cost;
}
private static FileWriter fw = null;
public enum TradeType {
MONEY,
EXP,
ITEM
}
public static void log(String type, String subtype, String event, String sender, Trade charge, String receiver, Trade pay, Location loc, IEssentials ess)
{
//isEcoLogUpdateEnabled() - This refers to log entries with no location, ie API updates #EasterEgg
//isEcoLogEnabled() - This refers to log entries with with location, ie /pay /sell and eco signs.
if ((loc == null && !ess.getSettings().isEcoLogUpdateEnabled())
|| (loc != null && !ess.getSettings().isEcoLogEnabled()))
{
return;
}
if (fw == null)
{
try
{
fw = new FileWriter(new File(ess.getDataFolder(), "trade.log"), true);
}
catch (IOException ex)
{
Logger.getLogger("Minecraft").log(Level.SEVERE, null, ex);
}
}
StringBuilder sb = new StringBuilder();
sb.append(type).append(",").append(subtype).append(",").append(event).append(",\"");
sb.append(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date()));
sb.append("\",\"");
if (sender != null)
{
sb.append(sender);
}
sb.append("\",");
if (charge == null)
{
sb.append("\"\",\"\",\"\"");
}
else
{
if (charge.getItemStack() != null)
{
sb.append(charge.getItemStack().getAmount()).append(",");
sb.append(charge.getItemStack().getType().toString()).append(",");
sb.append(charge.getItemStack().getDurability());
}
if (charge.getMoney() != null)
{
sb.append(charge.getMoney()).append(",");
sb.append("money").append(",");
sb.append(ess.getSettings().getCurrencySymbol());
}
if (charge.getExperience() != null)
{
sb.append(charge.getExperience()).append(",");
sb.append("exp").append(",");
sb.append("\"\"");
}
}
sb.append(",\"");
if (receiver != null)
{
sb.append(receiver);
}
sb.append("\",");
if (pay == null)
{
sb.append("\"\",\"\",\"\"");
}
else
{
if (pay.getItemStack() != null)
{
sb.append(pay.getItemStack().getAmount()).append(",");
sb.append(pay.getItemStack().getType().toString()).append(",");
sb.append(pay.getItemStack().getDurability());
}
if (pay.getMoney() != null)
{
sb.append(pay.getMoney()).append(",");
sb.append("money").append(",");
sb.append(ess.getSettings().getCurrencySymbol());
}
if (pay.getExperience() != null)
{
sb.append(pay.getExperience()).append(",");
sb.append("exp").append(",");
sb.append("\"\"");
}
}
if (loc == null)
{
sb.append(",\"\",\"\",\"\",\"\"");
}
else
{
sb.append(",\"");
sb.append(loc.getWorld().getName()).append("\",");
sb.append(loc.getBlockX()).append(",");
sb.append(loc.getBlockY()).append(",");
sb.append(loc.getBlockZ()).append(",");
}
sb.append("\n");
try
{
fw.write(sb.toString());
fw.flush();
}
catch (IOException ex)
{
Logger.getLogger("Minecraft").log(Level.SEVERE, null, ex);
}
}
public static void closeLog()
{
if (fw != null)
{
try
{
fw.close();
}
catch (IOException ex)
{
Logger.getLogger("Minecraft").log(Level.SEVERE, null, ex);
}
fw = null;
}
}
public enum OverflowType {
ABORT,
DROP,
RETURN
}
}
@@ -0,0 +1,156 @@
package com.earth2me.essentials;
import com.google.common.io.Files;
import org.bukkit.Bukkit;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.regex.Pattern;
public class UUIDMap {
private static final ScheduledExecutorService writeScheduler = Executors.newScheduledThreadPool(1);
private static boolean pendingWrite;
private static boolean loading = false;
private final transient net.ess3.api.IEssentials ess;
private final File userList;
private final transient Pattern splitPattern = Pattern.compile(",");
private final Runnable writeTaskRunnable;
public UUIDMap(final net.ess3.api.IEssentials ess) {
this.ess = ess;
userList = new File(ess.getDataFolder(), "usermap.csv");
pendingWrite = false;
writeTaskRunnable = () -> {
if (pendingWrite) {
try {
new WriteRunner(ess.getDataFolder(), userList, ess.getUserMap().getNames()).run();
} catch (final Throwable t) { // bad code to prevent task from being suppressed
t.printStackTrace();
}
}
};
writeScheduler.scheduleWithFixedDelay(writeTaskRunnable, 5, 5, TimeUnit.SECONDS);
}
public void loadAllUsers(final ConcurrentSkipListMap<String, UUID> names, final ConcurrentSkipListMap<UUID, ArrayList<String>> history) {
try {
if (!userList.exists()) {
userList.createNewFile();
}
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "Reading usermap from disk");
}
if (loading) {
return;
}
names.clear();
history.clear();
loading = true;
try (final BufferedReader reader = new BufferedReader(new FileReader(userList))) {
while (true) {
final String line = reader.readLine();
if (line == null) {
break;
} else {
final String[] values = splitPattern.split(line);
if (values.length == 2) {
final String name = values[0];
final UUID uuid = UUID.fromString(values[1]);
names.put(name, uuid);
if (!history.containsKey(uuid)) {
final ArrayList<String> list = new ArrayList<>();
list.add(name);
history.put(uuid, list);
} else {
final ArrayList<String> list = history.get(uuid);
if (!list.contains(name)) {
list.add(name);
}
}
}
}
}
}
loading = false;
} catch (final IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
}
}
public void writeUUIDMap() {
pendingWrite = true;
}
public void forceWriteUUIDMap() {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "Forcing usermap write to disk");
}
pendingWrite = true;
writeTaskRunnable.run();
}
public void shutdown() {
writeScheduler.submit(writeTaskRunnable);
writeScheduler.shutdown();
}
private static final class WriteRunner implements Runnable {
private final File location;
private final File endFile;
private final Map<String, UUID> names;
private WriteRunner(final File location, final File endFile, final Map<String, UUID> names) {
this.location = location;
this.endFile = endFile;
this.names = new HashMap<>(names);
}
@Override
public void run() {
pendingWrite = false;
if (loading || names.isEmpty()) {
return;
}
File configFile = null;
try {
configFile = File.createTempFile("usermap", ".tmp.csv", location);
final BufferedWriter bWriter = new BufferedWriter(new FileWriter(configFile));
for (final Map.Entry<String, UUID> entry : names.entrySet()) {
bWriter.write(entry.getKey() + "," + entry.getValue().toString());
bWriter.newLine();
}
bWriter.close();
Files.move(configFile, endFile);
} catch (final IOException ex) {
try {
if (configFile != null && configFile.exists()) {
Files.move(configFile, new File(endFile.getParentFile(), "usermap.bak.csv"));
}
} catch (final Exception ex2) {
Bukkit.getLogger().log(Level.SEVERE, ex2.getMessage(), ex2);
}
Bukkit.getLogger().log(Level.WARNING, ex.getMessage(), ex);
}
}
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,143 +1,313 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.StringUtil;
import com.google.common.base.Charsets;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.UncheckedExecutionException;
import java.io.File;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.ExecutionException;
import net.ess3.api.IEssentials;
import org.bukkit.entity.Player;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;
public class UserMap extends CacheLoader<String, User> implements IConf
{
private final transient IEssentials ess;
private final transient Cache<String, User> users = CacheBuilder.newBuilder().softValues().build(this);
private final transient ConcurrentSkipListSet<String> keys = new ConcurrentSkipListSet<String>();
public class UserMap extends CacheLoader<String, User> implements IConf {
private static boolean legacy = false;
private static Method getLegacy;
private final transient IEssentials ess;
private final transient ConcurrentSkipListSet<UUID> keys = new ConcurrentSkipListSet<>();
private final transient ConcurrentSkipListMap<String, UUID> names = new ConcurrentSkipListMap<>();
private final transient ConcurrentSkipListMap<UUID, ArrayList<String>> history = new ConcurrentSkipListMap<>();
private final UUIDMap uuidMap;
private final transient Cache<String, User> users;
private final Pattern validUserPattern = Pattern.compile("^[a-zA-Z0-9_]{2,16}$");
public UserMap(final IEssentials ess)
{
super();
this.ess = ess;
loadAllUsersAsync(ess);
}
public UserMap(final IEssentials ess) {
super();
this.ess = ess;
uuidMap = new UUIDMap(ess);
//RemovalListener<UUID, User> remListener = new UserMapRemovalListener();
//users = CacheBuilder.newBuilder().maximumSize(ess.getSettings().getMaxUserCacheCount()).softValues().removalListener(remListener).build(this);
final CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder();
final int maxCount = ess.getSettings().getMaxUserCacheCount();
try {
cacheBuilder.maximumSize(maxCount);
} catch (final NoSuchMethodError nsme) {
legacy = true;
legacyMaximumSize(cacheBuilder, maxCount);
}
cacheBuilder.softValues();
if (!legacy) {
users = cacheBuilder.build(this);
} else {
users = legacyBuild(cacheBuilder);
}
}
private void loadAllUsersAsync(final IEssentials ess)
{
ess.runTaskAsynchronously(new Runnable()
{
@Override
public void run()
{
final File userdir = new File(ess.getDataFolder(), "userdata");
if (!userdir.exists())
{
return;
}
keys.clear();
users.invalidateAll();
for (String string : userdir.list())
{
if (!string.endsWith(".yml"))
{
continue;
}
final String name = string.substring(0, string.length() - 4);
keys.add(StringUtil.sanitizeFileName(name));
}
}
});
}
private void loadAllUsersAsync(final IEssentials ess) {
ess.runTaskAsynchronously(() -> {
synchronized (users) {
final File userdir = new File(ess.getDataFolder(), "userdata");
if (!userdir.exists()) {
return;
}
keys.clear();
users.invalidateAll();
for (final String string : userdir.list()) {
if (!string.endsWith(".yml")) {
continue;
}
final String name = string.substring(0, string.length() - 4);
try {
keys.add(UUID.fromString(name));
} catch (final IllegalArgumentException ex) {
//Ignore these users till they rejoin.
}
}
uuidMap.loadAllUsers(names, history);
}
});
}
public boolean userExists(final String name)
{
return keys.contains(StringUtil.sanitizeFileName(name));
}
public boolean userExists(final UUID uuid) {
return keys.contains(uuid);
}
public User getUser(final String name)
{
try
{
return users.get(name);
}
catch (ExecutionException ex)
{
return null;
}
catch (UncheckedExecutionException ex)
{
return null;
}
}
public User getUser(final String name) {
try {
final String sanitizedName = StringUtil.safeString(name);
if (names.containsKey(sanitizedName)) {
final UUID uuid = names.get(sanitizedName);
return getUser(uuid);
}
@Override
public User load(final String name) throws Exception
{
String sanitizedName = StringUtil.sanitizeFileName(name);
if (!sanitizedName.equals(name))
{
User user = getUser(sanitizedName);
if (user == null)
{
throw new Exception("User not found!");
}
else
{
return user;
}
}
for (Player player : ess.getServer().getOnlinePlayers())
{
if (player.getName().equalsIgnoreCase(name))
{
keys.add(sanitizedName);
return new User(player, ess);
}
}
final File userFile = getUserFile2(sanitizedName);
if (userFile.exists())
{
keys.add(sanitizedName);
return new User(new OfflinePlayer(name, ess), ess);
}
throw new Exception("User not found!");
}
final File userFile = getUserFileFromString(sanitizedName);
if (userFile.exists()) {
ess.getLogger().info("Importing user " + name + " to usermap.");
final User user = new User(new OfflinePlayer(sanitizedName, ess.getServer()), ess);
trackUUID(user.getBase().getUniqueId(), user.getName(), true);
return user;
}
return null;
} catch (final UncheckedExecutionException ex) {
return null;
}
}
@Override
public void reloadConfig()
{
loadAllUsersAsync(ess);
}
public User getUser(final UUID uuid) {
try {
if (!legacy) {
return ((LoadingCache<String, User>) users).get(uuid.toString());
} else {
return legacyCacheGet(uuid);
}
} catch (final ExecutionException | UncheckedExecutionException ex) {
return null;
}
}
public void removeUser(final String name)
{
keys.remove(StringUtil.sanitizeFileName(name));
users.invalidate(StringUtil.sanitizeFileName(name));
users.invalidate(name);
}
public void trackUUID(final UUID uuid, final String name, final boolean replace) {
if (uuid != null) {
keys.add(uuid);
if (name != null && name.length() > 0) {
final String keyName = ess.getSettings().isSafeUsermap() ? StringUtil.safeString(name) : name;
if (!names.containsKey(keyName)) {
names.put(keyName, uuid);
uuidMap.writeUUIDMap();
} else if (!names.get(keyName).equals(uuid)) {
if (replace) {
ess.getLogger().info("Found new UUID for " + name + ". Replacing " + names.get(keyName).toString() + " with " + uuid.toString());
names.put(keyName, uuid);
uuidMap.writeUUIDMap();
} else {
if (ess.getSettings().isDebug()) {
ess.getLogger().info("Found old UUID for " + name + " (" + uuid.toString() + "). Not adding to usermap.");
}
}
}
}
}
}
public Set<String> getAllUniqueUsers()
{
return Collections.unmodifiableSet(keys);
}
@Override
public User load(final String stringUUID) throws Exception {
final UUID uuid = UUID.fromString(stringUUID);
Player player = ess.getServer().getPlayer(uuid);
if (player != null) {
final User user = new User(player, ess);
trackUUID(uuid, user.getName(), true);
return user;
}
public int getUniqueUsers()
{
return keys.size();
}
final File userFile = getUserFileFromID(uuid);
public File getUserFile(final String name)
{
return getUserFile2(StringUtil.sanitizeFileName(name));
}
if (userFile.exists()) {
player = new OfflinePlayer(uuid, ess.getServer());
final User user = new User(player, ess);
((OfflinePlayer) player).setName(user.getLastAccountName());
trackUUID(uuid, user.getName(), false);
return user;
}
private File getUserFile2(final String name)
{
final File userFolder = new File(ess.getDataFolder(), "userdata");
return new File(userFolder, name + ".yml");
}
throw new Exception("User not found!");
}
@Override
public void reloadConfig() {
getUUIDMap().forceWriteUUIDMap();
loadAllUsersAsync(ess);
}
public void invalidateAll() {
users.invalidateAll();
}
public void removeUser(final String name) {
if (names == null) {
ess.getLogger().warning("Name collection is null, cannot remove user.");
return;
}
final UUID uuid = names.get(name);
if (uuid != null) {
keys.remove(uuid);
users.invalidate(uuid.toString());
}
names.remove(name);
names.remove(StringUtil.safeString(name));
}
public Set<UUID> getAllUniqueUsers() {
return Collections.unmodifiableSet(keys);
}
public int getUniqueUsers() {
return keys.size();
}
protected ConcurrentSkipListMap<String, UUID> getNames() {
return names;
}
protected ConcurrentSkipListMap<UUID, ArrayList<String>> getHistory() {
return history;
}
public List<String> getUserHistory(final UUID uuid) {
return history.get(uuid);
}
public UUIDMap getUUIDMap() {
return uuidMap;
}
// class UserMapRemovalListener implements RemovalListener
// {
// @Override
// public void onRemoval(final RemovalNotification notification)
// {
// Object value = notification.getValue();
// if (value != null)
// {
// ((User)value).cleanup();
// }
// }
// }
private File getUserFileFromID(final UUID uuid) {
final File userFolder = new File(ess.getDataFolder(), "userdata");
return new File(userFolder, uuid.toString() + ".yml");
}
public File getUserFileFromString(final String name) {
final File userFolder = new File(ess.getDataFolder(), "userdata");
return new File(userFolder, StringUtil.sanitizeFileName(name) + ".yml");
}
@SuppressWarnings("deprecation")
public User getUserFromBukkit(String name) {
name = StringUtil.safeString(name);
if (ess.getSettings().isDebug()) {
ess.getLogger().warning("Using potentially blocking Bukkit UUID lookup for: " + name);
}
// Don't attempt to look up entirely invalid usernames
if (name == null || !validUserPattern.matcher(name).matches()) {
return null;
}
final org.bukkit.OfflinePlayer offlinePlayer = ess.getServer().getOfflinePlayer(name);
if (offlinePlayer == null) {
return null;
}
final UUID uuid;
try {
uuid = offlinePlayer.getUniqueId();
} catch (final UnsupportedOperationException | NullPointerException e) {
return null;
}
// This is how Bukkit generates fake UUIDs
if (UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)).equals(uuid)) {
return null;
} else {
names.put(name, uuid);
return getUser(uuid);
}
}
private User legacyCacheGet(final UUID uuid) {
if (getLegacy == null) {
final Class<?> usersClass = users.getClass();
for (final Method m : usersClass.getDeclaredMethods()) {
if (m.getName().equals("get")) {
getLegacy = m;
getLegacy.setAccessible(true);
break;
}
}
}
try {
return (User) getLegacy.invoke(users, uuid.toString());
} catch (final IllegalAccessException | InvocationTargetException e) {
return null;
}
}
private void legacyMaximumSize(final CacheBuilder builder, final int maxCount) {
try {
final Method maxSizeLegacy = builder.getClass().getDeclaredMethod("maximumSize", Integer.TYPE);
maxSizeLegacy.setAccessible(true);
maxSizeLegacy.invoke(builder, maxCount);
} catch (final NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
private Cache<String, User> legacyBuild(final CacheBuilder builder) {
Method build = null;
for (final Method method : builder.getClass().getDeclaredMethods()) {
if (method.getName().equals("build")) {
build = method;
break;
}
}
Cache<String, User> legacyUsers;
try {
assert build != null;
build.setAccessible(true);
legacyUsers = (Cache<String, User>) build.invoke(builder, this);
} catch (final IllegalAccessException | InvocationTargetException e) {
legacyUsers = null;
}
return legacyUsers;
}
}
+155 -159
View File
@@ -1,181 +1,177 @@
package com.earth2me.essentials;
import com.earth2me.essentials.utils.StringUtil;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.api.IWarps;
import com.earth2me.essentials.api.InvalidNameException;
import com.earth2me.essentials.api.InvalidWorldException;
import com.earth2me.essentials.commands.WarpNotFoundException;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.earth2me.essentials.utils.StringUtil;
import net.ess3.api.InvalidNameException;
import net.ess3.api.InvalidWorldException;
import org.bukkit.Location;
import org.bukkit.Server;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Warps implements IConf, IWarps
{
private static final Logger logger = Logger.getLogger("Minecraft");
private final Map<StringIgnoreCase, EssentialsConf> warpPoints = new HashMap<StringIgnoreCase, EssentialsConf>();
private final File warpsFolder;
private final Server server;
import static com.earth2me.essentials.I18n.tl;
public Warps(Server server, File dataFolder)
{
this.server = server;
warpsFolder = new File(dataFolder, "warps");
if (!warpsFolder.exists())
{
warpsFolder.mkdirs();
}
reloadConfig();
}
public class Warps implements IConf, net.ess3.api.IWarps {
private static final Logger logger = Logger.getLogger("Essentials");
private final Map<StringIgnoreCase, EssentialsConf> warpPoints = new HashMap<>();
private final File warpsFolder;
private final Server server;
@Override
public boolean isEmpty()
{
return warpPoints.isEmpty();
}
public Warps(final Server server, final File dataFolder) {
this.server = server;
warpsFolder = new File(dataFolder, "warps");
if (!warpsFolder.exists()) {
warpsFolder.mkdirs();
}
reloadConfig();
}
@Override
public Collection<String> getList()
{
final List<String> keys = new ArrayList<String>();
for (StringIgnoreCase stringIgnoreCase : warpPoints.keySet())
{
keys.add(stringIgnoreCase.getString());
}
Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
return keys;
}
@Override
public boolean isEmpty() {
return warpPoints.isEmpty();
}
@Override
public Location getWarp(String warp) throws WarpNotFoundException, InvalidWorldException
{
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
if (conf == null)
{
throw new WarpNotFoundException();
}
return conf.getLocation(null, server);
}
@Override
public Collection<String> getList() {
final List<String> keys = new ArrayList<>();
for (final StringIgnoreCase stringIgnoreCase : warpPoints.keySet()) {
keys.add(stringIgnoreCase.getString());
}
keys.sort(String.CASE_INSENSITIVE_ORDER);
return keys;
}
@Override
public void setWarp(String name, Location loc) throws Exception
{
String filename = StringUtil.sanitizeFileName(name);
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
if (conf == null)
{
File confFile = new File(warpsFolder, filename + ".yml");
if (confFile.exists())
{
throw new Exception(_("similarWarpExist"));
}
conf = new EssentialsConf(confFile);
warpPoints.put(new StringIgnoreCase(name), conf);
}
conf.setProperty(null, loc);
conf.setProperty("name", name);
try
{
conf.saveWithError();
}
catch (IOException ex)
{
throw new IOException(_("invalidWarpName"));
}
}
@Override
public Location getWarp(final String warp) throws WarpNotFoundException, InvalidWorldException {
final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
if (conf == null) {
throw new WarpNotFoundException();
}
return conf.getLocation(null, server);
}
@Override
public void removeWarp(String name) throws Exception
{
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
if (conf == null)
{
throw new Exception(_("warpNotExist"));
}
if (!conf.getFile().delete())
{
throw new Exception(_("warpDeleteError"));
}
warpPoints.remove(new StringIgnoreCase(name));
}
@Override
public void setWarp(final String name, final Location loc) throws Exception {
setWarp(null, name, loc);
}
@Override
public final void reloadConfig()
{
warpPoints.clear();
File[] listOfFiles = warpsFolder.listFiles();
if (listOfFiles.length >= 1)
{
for (int i = 0; i < listOfFiles.length; i++)
{
String filename = listOfFiles[i].getName();
if (listOfFiles[i].isFile() && filename.endsWith(".yml"))
{
try
{
EssentialsConf conf = new EssentialsConf(listOfFiles[i]);
conf.load();
String name = conf.getString("name");
if (name != null)
{
warpPoints.put(new StringIgnoreCase(name), conf);
}
}
catch (Exception ex)
{
logger.log(Level.WARNING, _("loadWarpError", filename), ex);
}
}
}
}
}
@Override
public void setWarp(final IUser user, final String name, final Location loc) throws Exception {
final String filename = StringUtil.sanitizeFileName(name);
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
if (conf == null) {
final File confFile = new File(warpsFolder, filename + ".yml");
if (confFile.exists()) {
throw new Exception(tl("similarWarpExist"));
}
conf = new EssentialsConf(confFile);
warpPoints.put(new StringIgnoreCase(name), conf);
}
conf.setProperty(null, loc);
conf.setProperty("name", name);
if (user != null) conf.setProperty("lastowner", user.getBase().getUniqueId().toString());
try {
conf.saveWithError();
} catch (final IOException ex) {
throw new IOException(tl("invalidWarpName"));
}
}
//This is here for future 3.x api support. Not implemented here becasue storage is handled differently
@Override
public File getWarpFile(String name) throws InvalidNameException
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public UUID getLastOwner(final String warp) throws WarpNotFoundException {
final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
if (conf == null) {
throw new WarpNotFoundException();
}
UUID uuid = null;
try {
uuid = UUID.fromString(conf.getString("lastowner"));
} catch (final Exception ignored) {
}
return uuid;
}
@Override
public int getCount()
{
return getList().size();
}
@Override
public void removeWarp(final String name) throws Exception {
final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
if (conf == null) {
throw new Exception(tl("warpNotExist"));
}
if (!conf.getFile().delete()) {
throw new Exception(tl("warpDeleteError"));
}
warpPoints.remove(new StringIgnoreCase(name));
}
private static class StringIgnoreCase
{
private final String string;
@Override
public final void reloadConfig() {
warpPoints.clear();
final File[] listOfFiles = warpsFolder.listFiles();
if (listOfFiles.length >= 1) {
for (final File listOfFile : listOfFiles) {
final String filename = listOfFile.getName();
if (listOfFile.isFile() && filename.endsWith(".yml")) {
try {
final EssentialsConf conf = new EssentialsConf(listOfFile);
conf.load();
final String name = conf.getString("name");
if (name != null) {
warpPoints.put(new StringIgnoreCase(name), conf);
}
} catch (final Exception ex) {
logger.log(Level.WARNING, tl("loadWarpError", filename), ex);
}
}
}
}
}
public StringIgnoreCase(String string)
{
this.string = string;
}
/**
* @deprecated This method relates to the abandoned 3.x storage refactor and is not implemented.
*/
@Override
@Deprecated
public File getWarpFile(final String name) throws InvalidNameException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public int hashCode()
{
return getString().toLowerCase(Locale.ENGLISH).hashCode();
}
@Override
public int getCount() {
return getList().size();
}
@Override
public boolean equals(Object o)
{
if (o instanceof StringIgnoreCase)
{
return getString().equalsIgnoreCase(((StringIgnoreCase)o).getString());
}
return false;
}
private static class StringIgnoreCase {
private final String string;
public String getString()
{
return string;
}
}
StringIgnoreCase(final String string) {
this.string = string;
}
@Override
public int hashCode() {
return getString().toLowerCase(Locale.ENGLISH).hashCode();
}
@Override
public boolean equals(final Object o) {
if (o instanceof StringIgnoreCase) {
return getString().equalsIgnoreCase(((StringIgnoreCase) o).getString());
}
return false;
}
public String getString() {
return string;
}
}
}
+143 -54
View File
@@ -1,66 +1,155 @@
package com.earth2me.essentials;
import com.earth2me.essentials.commands.NotEnoughArgumentsException;
import com.earth2me.essentials.utils.VersionUtil;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.math.BigDecimal;
import java.util.Locale;
import java.util.logging.Logger;
import org.bukkit.inventory.ItemStack;
import static com.earth2me.essentials.I18n.tl;
public class Worth implements IConf
{
private static final Logger logger = Logger.getLogger("Minecraft");
private final EssentialsConf config;
public class Worth implements IConf {
private final EssentialsConf config;
public Worth(File dataFolder)
{
config = new EssentialsConf(new File(dataFolder, "worth.yml"));
config.setTemplateName("/worth.yml");
config.load();
}
public Worth(final File dataFolder) {
config = new EssentialsConf(new File(dataFolder, "worth.yml"));
config.setTemplateName("/worth.yml");
config.load();
}
public BigDecimal getPrice(ItemStack itemStack)
{
String itemname = itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
BigDecimal result;
result = config.getBigDecimal("worth." + itemname + "." + itemStack.getDurability(), BigDecimal.ONE.negate());
if (result.signum() < 0)
{
result = config.getBigDecimal("worth." + itemname + ".0", BigDecimal.ONE.negate());
}
if (result.signum() < 0)
{
result = config.getBigDecimal("worth." + itemname, BigDecimal.ONE.negate());
}
if (result.signum() < 0)
{
result = config.getBigDecimal("worth-" + itemStack.getTypeId(), BigDecimal.ONE.negate());
}
if (result.signum() < 0)
{
return null;
}
return result;
}
/**
* Get the value of an item stack from the config.
*
* @param ess The Essentials instance.
* @param itemStack The item stack to look up in the config.
* @return The price from the config.
*/
public BigDecimal getPrice(final IEssentials ess, final ItemStack itemStack) {
BigDecimal result;
public void setPrice(ItemStack itemStack, double price)
{
if (itemStack.getType().getData() == null)
{
config.setProperty("worth." + itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", ""), price);
}
else
{
// Bukkit-bug: getDurability still contains the correct value, while getData().getData() is 0.
config.setProperty("worth." + itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "") + "." + itemStack.getDurability(), price);
}
config.removeProperty("worth-" + itemStack.getTypeId());
config.save();
}
final String itemname = itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
@Override
public void reloadConfig()
{
config.load();
}
// Check for matches with data value from stack
// Note that we always default to BigDecimal.ONE.negate(), equivalent to -1
result = config.getBigDecimal("worth." + itemname + "." + itemStack.getDurability(), BigDecimal.ONE.negate());
// Check for matches with data value 0
if (result.signum() < 0) {
final ConfigurationSection itemNameMatch = config.getConfigurationSection("worth." + itemname);
if (itemNameMatch != null && itemNameMatch.getKeys(false).size() == 1) {
result = config.getBigDecimal("worth." + itemname + ".0", BigDecimal.ONE.negate());
}
}
// Check for matches with data value wildcard
if (result.signum() < 0) {
result = config.getBigDecimal("worth." + itemname + ".*", BigDecimal.ONE.negate());
}
// Check for matches with item name alone
if (result.signum() < 0) {
result = config.getBigDecimal("worth." + itemname, BigDecimal.ONE.negate());
}
if (result.signum() < 0) {
return null;
}
return result;
}
/**
* Get the amount of items to be sold from a player's inventory.
*
* @param ess The Essentials instance.
* @param user The user attempting to sell the item.
* @param is A stack of the item to search the inventory for.
* @param args The amount to try to sell.
* @param isBulkSell Whether or not to try and bulk sell all items.
* @return The amount of items to sell from the player's inventory.
* @throws Exception Thrown if trying to sell air or an invalid amount.
*/
public int getAmount(final IEssentials ess, final User user, final ItemStack is, final String[] args, final boolean isBulkSell) throws Exception {
if (is == null || is.getType() == Material.AIR) {
throw new Exception(tl("itemSellAir"));
}
int amount = 0;
if (args.length > 1) {
try {
amount = Integer.parseInt(args[1].replaceAll("[^0-9]", ""));
} catch (final NumberFormatException ex) {
throw new NotEnoughArgumentsException(ex);
}
if (args[1].startsWith("-")) {
amount = -amount;
}
}
final boolean stack = args.length > 1 && args[1].endsWith("s");
final boolean requireStack = ess.getSettings().isTradeInStacks(is.getType());
if (requireStack && !stack) {
throw new Exception(tl("itemMustBeStacked"));
}
int max = 0;
for (final ItemStack s : user.getBase().getInventory().getContents()) {
if (s == null || !s.isSimilar(is)) {
continue;
}
max += s.getAmount();
}
if (stack) {
amount *= is.getType().getMaxStackSize();
}
if (amount < 1) {
amount += max;
}
if (requireStack) {
amount -= amount % is.getType().getMaxStackSize();
}
if (amount > max || amount < 1) {
if (!isBulkSell) {
user.sendMessage(tl("itemNotEnough2"));
user.sendMessage(tl("itemNotEnough3"));
throw new Exception(tl("itemNotEnough1"));
} else {
return amount;
}
}
return amount;
}
/**
* Set the price of an item and save it to the config.
*
* @param ess The Essentials instance.
* @param itemStack A stack of the item to save.
* @param price The new price of the item.
*/
public void setPrice(final IEssentials ess, final ItemStack itemStack, final double price) {
String path = "worth." + itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
// Spigot 1.13+ throws an exception if a 1.13+ plugin even *attempts* to do set data.
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01) && itemStack.getType().getData() == null) {
// Bukkit-bug: getDurability still contains the correct value, while getData().getData() is 0.
path = path + "." + itemStack.getDurability();
}
config.setProperty(path, price);
config.save();
}
@Override
public void reloadConfig() {
config.load();
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,126 @@
package com.earth2me.essentials.api;
import com.earth2me.essentials.Trade;
import net.ess3.api.IUser;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.concurrent.CompletableFuture;
/**
* Manages EssentialsX's teleport functionality for a player.
* Use this if you want to access EssentialsX's async/safe teleport functionality and teleport warmups and cooldowns.
*/
public interface IAsyncTeleport {
/**
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
*
* @param loc - Where should the player end up
* @param cooldown - If cooldown should be enforced
* @param cause - The reported teleportPlayer cause
* @param future - Future which is completed with the success status of the execution
*/
void now(Location loc, boolean cooldown, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
/**
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
*
* @param entity - Where should the player end up
* @param cooldown - If cooldown should be enforced
* @param cause - The reported teleportPlayer cause
* @param future - Future which is completed with the success status of the execution
*/
void now(Player entity, boolean cooldown, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
/**
* Teleport a player to a specific location
*
* @param loc - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause.
* @param future - Future which is completed with the success status of the execution
*/
void teleport(Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
/**
* Teleport a player to a specific player
*
* @param entity - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @param future - Future which is completed with the success status of the execution
*/
void teleport(Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
/**
* Teleport a player to a specific location
*
* @param otherUser - Which user will be teleported
* @param loc - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @param future - Future which is completed with the success status of the execution
*/
void teleportPlayer(IUser otherUser, Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
/**
* Teleport a player to a specific player
*
* @param otherUser - Which user will be teleported
* @param entity - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @param future - Future which is completed with the success status of the execution
*/
void teleportPlayer(IUser otherUser, Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
/**
* Teleport wrapper used to handle tp fallback on /jail and /home
*
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @param future - Future which is completed with the success status of the execution
*/
void respawn(final Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
/**
* Teleport wrapper used to handle /warp teleports
*
* @param otherUser - Which user will be teleported
* @param warp - The name of the warp the user will be teleported too.
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @param future - Future which is completed with the success status of the execution
*/
void warp(IUser otherUser, String warp, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
/**
* Teleport wrapper used to handle /back teleports
*
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param future - Future which is completed with the success status of the execution
*/
void back(Trade chargeFor, CompletableFuture<Boolean> future);
/**
* 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
* @param future - Future which is completed with the success status of the execution
*/
void back(IUser teleporter, Trade chargeFor, CompletableFuture<Boolean> future);
/**
* Teleport wrapper used to handle throwing user home after a jail sentence
*
* @param future - Future which is completed with the success status of the execution
*/
void back(CompletableFuture<Boolean> future);
}
@@ -1,13 +1,21 @@
package com.earth2me.essentials.api;
import org.bukkit.entity.Player;
import java.util.Locale;
public interface II18n
{
/**
* Gets the current locale setting
* @return the current locale, if not set it will return the default locale
*/
Locale getCurrentLocale();
/**
* Provides access to the current locale in use.
*
* @deprecated External plugins should prefer to use either the player's client language ({@link Player#getLocale()} or
* {@link net.ess3.api.II18n} in case of future additions.
*/
@Deprecated
public interface II18n {
/**
* Gets the current locale setting
*
* @return the current locale, if not set it will return the default locale
*/
Locale getCurrentLocale();
}
@@ -1,11 +1,171 @@
package com.earth2me.essentials.api;
import com.earth2me.essentials.User;
import com.earth2me.essentials.utils.MaterialUtil;
import com.earth2me.essentials.utils.NumberUtil;
import com.earth2me.essentials.utils.StringUtil;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
public interface IItemDb
{
ItemStack get(final String name, final int quantity) throws Exception;
/**
* Provides access to the current item alias registry.
*
* @deprecated External plugins should use {@link net.ess3.api.IItemDb} instead, which includes access to {@link net.ess3.api.IItemDb.ItemResolver}
* APIs.
*/
@Deprecated
public interface IItemDb {
ItemStack get(final String name) throws Exception;
/**
* Create a stack from the given name with the given quantity.
*
* @param name Item name to look up in the database
* @param quantity Quantity of the item stack
* @return The requested item stack
* @throws Exception if the item stack cannot be created
*/
default ItemStack get(final String name, final int quantity) throws Exception {
final ItemStack stack = get(name.toLowerCase(Locale.ENGLISH));
stack.setAmount(quantity);
return stack;
}
/**
* Create a stack from the given name with the maximum stack size for that material.
* <p>
* 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
*/
ItemStack get(final String name) throws Exception;
/**
* Get a comma-separated string list of up to 15 aliases for the given stack.
*
* @param item Item stack whose names to find
* @return Comma-separated list of up to 15 item names
*/
default String names(final ItemStack item) {
List<String> nameList = nameList(item);
if (nameList.size() > 15) {
nameList = nameList.subList(0, 14);
}
return StringUtil.joinList(", ", nameList);
}
/**
* Get a List of all aliases for the given item stack.
*
* @param item Item stack whose names to find
* @return List of all names
*/
List<String> nameList(ItemStack item);
/**
* Get the primary name for the given item stack.
*
* @param item Item stack whose name to find
* @return Primary name of the item
*/
String name(ItemStack item);
/**
* Get all stacks in a given User's inventory that matches the given arguments.
*
* @param user The user with the player inventory to search
* @param args Either an item name, or one of the following:
* hand (default), inventory/invent/all, blocks
* @return A List of all matching ItemStacks
* @throws Exception if the given args are invalid or no blocks are found
*/
List<ItemStack> getMatching(User user, String[] args) throws Exception;
/**
* Converts the given {@link ItemStack} to a string representation that can be saved.
* This is typically used for /createkit but can be used by other plugins for various purposes too.
* Note that this will try registered resolvers first - to avoid this, use {@link net.ess3.api.IItemDb#serialize(ItemStack, boolean)} instead.
*
* @param is The stack to serialize
* @return A string representing the given stack
*/
String serialize(ItemStack is);
/**
* Return names recognised by the database, intended for tab-completion.
*
* @return Collection of all item names
*/
Collection<String> listNames();
/**
* Get the material matching the given legacy ID. Used for conversion from item IDs to
* modern names.
*
* @param id Legacy ID of material to find
* @return Updated material
*/
@Deprecated
default Material getFromLegacyId(final int id) {
return getFromLegacy(id, (byte) 0);
}
/**
* Get the legacy ID for the given material.
*
* @param material Material to look up
* @return Legacy ID of given material
* @throws Exception if the ID cannot be looked up
* @deprecated Item IDs are no longer supported.
*/
@Deprecated
int getLegacyId(Material material) throws Exception;
/**
* Convert colon syntax (eg. "13", "1:5") legacy IDs to Material. Used for conversion from
* item IDs to modern names.
*
* @param item Legacy ID in colon syntax.
* @return Material if an appropriate material exists, else null.
*/
default Material getFromLegacy(final String item) {
final String[] split = item.split(":");
if (!NumberUtil.isInt(split[0])) return null;
final int id = Integer.parseInt(split[0]);
byte damage = 0;
if (split.length > 1 && NumberUtil.isInt(split[1])) {
damage = Byte.parseByte(split[1]);
}
return getFromLegacy(id, damage);
}
/**
* Convert legacy ID and damage value to Material. Used for conversion from item IDs to
* modern names.
*
* @param id Legacy ID
* @param damage Damage value
* @return Material
*/
default Material getFromLegacy(final int id, final byte damage) {
return MaterialUtil.convertFromLegacy(id, damage);
}
/**
* Check whether the item database is loaded and ready for use.
*
* @return Whether items have finished loading
*/
boolean isReady();
}
@@ -1,52 +1,77 @@
package com.earth2me.essentials.api;
import java.util.Collection;
import net.ess3.api.IUser;
import org.bukkit.Location;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
public interface IJails extends IReload
{
/**
* Gets the location of the jail with the given name
* @param jailName The name of the jail
* @return the location of the jail
* @throws Exception if the jail does not exist
*/
Location getJail(String jailName) throws Exception;
/**
* Provides access to the storage of jail locations. Maintainers should add methods to <i>this interface</i>.
*
* @deprecated External plugins should use {@link net.ess3.api.IJails} instead of this interface in case future APIs are added.
*/
@Deprecated
public interface IJails extends IReload {
/**
* Gets the location of the jail with the given name
*
* @param jailName The name of the jail
* @return the location of the jail
* @throws Exception if the jail does not exist
*/
Location getJail(String jailName) throws Exception;
/**
* Gets a list of jails by names
* @return a list of jails, if there are none the list will be empty
* @throws Exception
*/
Collection<String> getList() throws Exception;
/**
* Gets a list of jails by names
*
* @return a list of jails, if there are none the list will be empty
* @throws Exception
*/
Collection<String> getList() throws Exception;
/**
* Gets the number of jails
* @return the size of the list of jails
*/
int getCount();
/**
* Gets the number of jails
*
* @return the size of the list of jails
*/
int getCount();
/**
* Remove the jail with the given name
* @param jail the jail to remove
* @throws Exception if the jail does not exist
*/
void removeJail(String jail) throws Exception;
/**
* Remove the jail with the given name
*
* @param jail the jail to remove
* @throws Exception if the jail does not exist
*/
void removeJail(String jail) throws Exception;
/**
* Attempts to send the given user to the given jail
* @param user the user to send to jail
* @param jail the jail to send the user to
* @throws Exception if the user is offline or jail does not exist
*/
void sendToJail(com.earth2me.essentials.IUser user, String jail) throws Exception;
/**
* Attempts to send the given user to the given jail
*
* @param user the user to send to jail
* @param jail the jail to send the user to
* @throws Exception if the user is offline or jail does not exist
* @deprecated Use {@link IJails#sendToJail(IUser, String, CompletableFuture)}
*/
@Deprecated
void sendToJail(IUser user, String jail) throws Exception;
/**
* Set a new jail with the given name and location
* @param jailName the name of the jail being set
* @param loc the location of the jail being set
* @throws Exception
*/
void setJail(String jailName, Location loc) throws Exception;
/**
* Attempts to send the given user to the given jail
*
* @param user the user to send to jail
* @param jail the jail to send the user to
* @param future Future which is completed with the success status of the execution
* @throws Exception if the user is offline or jail does not exist
*/
void sendToJail(IUser user, String jail, CompletableFuture<Boolean> future) throws Exception;
/**
* Set a new jail with the given name and location
*
* @param jailName the name of the jail being set
* @param loc the location of the jail being set
* @throws Exception
*/
void setJail(String jailName, Location loc) throws Exception;
}
@@ -1,7 +1,15 @@
package com.earth2me.essentials.api;
public interface IReload
{
void onReload();
/**
* Represents a storage object that is reloadable.
*
* @deprecated This is a remnant of the abandoned 3.x storage system. Neither future 2.x code nor external plugins
* should use this interface.
*/
@Deprecated
public interface IReload {
/**
* Reloads the given storage object.
*/
void onReload();
}
@@ -1,130 +1,143 @@
package com.earth2me.essentials.api;
import com.earth2me.essentials.IUser;
import com.earth2me.essentials.Trade;
import net.ess3.api.IUser;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.event.player.PlayerTeleportEvent;
/**
* @deprecated This API is not asynchronous and is no longer maintained. Use {@link com.earth2me.essentials.api.IAsyncTeleport IAsyncTeleport}.
*/
public interface ITeleport {
/**
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
*
* @param loc - Where should the player end up
* @param cooldown - If cooldown should be enforced
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
@Deprecated
void now(Location loc, boolean cooldown, PlayerTeleportEvent.TeleportCause cause) throws Exception;
public interface ITeleport
{
/**
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
*
* @param loc - Where should the player end up
* @param cooldown - If cooldown should be enforced
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
void now(Location loc, boolean cooldown, TeleportCause cause) throws Exception;
/**
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
*
* @param entity - Where should the player end up
* @param cooldown - If cooldown should be enforced
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
@Deprecated
void now(Player entity, boolean cooldown, PlayerTeleportEvent.TeleportCause cause) throws Exception;
/**
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
*
* @param entity - Where should the player end up
* @param cooldown - If cooldown should be enforced
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
void now(Player entity, boolean cooldown, TeleportCause cause) throws Exception;
/**
* Teleport a player to a specific location
*
* @param loc - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @throws Exception
*/
@Deprecated
void teleport(Location loc, Trade chargeFor) throws Exception;
@Deprecated
void teleport(Location loc, Trade chargeFor) throws Exception;
/**
* Teleport a player to a specific location
*
* @param loc - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
void teleport(Location loc, Trade chargeFor, TeleportCause cause) throws Exception;
/**
* Teleport a player to a specific location
*
* @param loc - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
@Deprecated
void teleport(Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
/**
* Teleport a player to a specific player
*
* @param entity - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
void teleport(Player entity, Trade chargeFor, TeleportCause cause) throws Exception;
/**
* Teleport a player to a specific location
*
* @param otherUser - Which user will be teleported
* @param loc - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
void teleportPlayer(IUser otherUser, Location loc, Trade chargeFor, TeleportCause cause) throws Exception;
/**
* Teleport a player to a specific player
*
* @param entity - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
@Deprecated
void teleport(Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
/**
* Teleport a player to a specific player
*
* @param otherUser - Which user will be teleported
* @param entity - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
void teleportPlayer(IUser otherUser, Player entity, Trade chargeFor, TeleportCause cause) throws Exception;
/**
* Teleport a player to a specific location
*
* @param otherUser - Which user will be teleported
* @param loc - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
@Deprecated
void teleportPlayer(IUser otherUser, Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
/**
* Teleport wrapper used to handle teleporting players to them, like /tphere
*
* @param otherUser - Which user will be teleported
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
public void teleportToMe(IUser otherUser, Trade chargeFor, TeleportCause cause) throws Exception;
/**
* Teleport a player to a specific player
*
* @param otherUser - Which user will be teleported
* @param entity - Where should the player end up
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
@Deprecated
void teleportPlayer(IUser otherUser, Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
/**
* Teleport wrapper used to handle tp fallback on /jail and /home
*
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
public void respawn(final Trade chargeFor, TeleportCause cause) throws Exception;
/**
* Teleport wrapper used to handle tp fallback on /jail and /home
*
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
@Deprecated
void respawn(final Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
/**
* Teleport wrapper used to handle /warp teleports
*
* @param otherUser - Which user will be teleported
* @param warp - The name of the warp the user will be teleported too.
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
public void warp(IUser otherUser, String warp, Trade chargeFor, TeleportCause cause) throws Exception;
/**
* Teleport wrapper used to handle /warp teleports
*
* @param otherUser - Which user will be teleported
* @param warp - The name of the warp the user will be teleported too.
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @param cause - The reported teleportPlayer cause
* @throws Exception
*/
@Deprecated
void warp(IUser otherUser, String warp, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
/**
* Teleport wrapper used to handle /back teleports
*
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @throws Exception
*/
public void back(Trade chargeFor) throws Exception;
/**
* Teleport wrapper used to handle /back teleports
*
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @throws Exception
*/
@Deprecated
void back(Trade chargeFor) throws Exception;
/**
* Teleport wrapper used to handle throwing user home after a jail sentence
*
* @throws Exception
*/
public void back() 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
*/
@Deprecated
void back(IUser teleporter, Trade chargeFor) throws Exception;
/**
* Teleport wrapper used to handle throwing user home after a jail sentence
*
* @throws Exception
*/
@Deprecated
void back() throws Exception;
/**
* Teleport wrapper used to handle /home teleports
*
* @param loc - Location where player will be teleported too
* @param chargeFor - What the user will be charged if teleportPlayer is successful
* @throws Exception
*/
public void home(Location loc, Trade chargeFor) throws Exception;
}
@@ -1,69 +1,90 @@
package com.earth2me.essentials.api;
import com.earth2me.essentials.IConf;
import java.io.File;
import java.util.Collection;
import com.earth2me.essentials.IUser;
import com.earth2me.essentials.commands.WarpNotFoundException;
import org.bukkit.Location;
import java.io.File;
import java.util.Collection;
import java.util.UUID;
public interface IWarps extends IConf
{
/**
* Get a warp by name
*
* @param warp - Warp name
* @return - Location the warp is set to
* @throws WarpNotFoundException When the warp is not found
* @throws InvalidWorldException When the world the warp is in is not found
*/
Location getWarp(String warp) throws WarpNotFoundException, InvalidWorldException;
/**
* Provides access to the storage of warp locations. Maintainers should add methods to <i>this interface</i>.
*
* @deprecated External plugins should use {@link net.ess3.api.IWarps} instead of this interface, in case future APIs are added.
*/
@Deprecated
public interface IWarps extends IConf {
/**
* Get a warp by name
*
* @param warp - Warp name
* @return - Location the warp is set to
* @throws WarpNotFoundException When the warp is not found
* @throws net.ess3.api.InvalidWorldException When the world the warp is in is not found
*/
Location getWarp(String warp) throws WarpNotFoundException, net.ess3.api.InvalidWorldException;
/**
* Gets a list of warps
*
* @return - A {@link Collection} of warps
*/
Collection<String> getList();
/**
* Gets a list of warps
*
* @return - A {@link Collection} of warps
*/
Collection<String> getList();
/**
* Gets the number of warps
*
* @return the size of the list of warps
*/
int getCount();
/**
* Gets the number of warps
*
* @return the size of the list of warps
*/
int getCount();
/**
* Delete a warp from the warp DB
*
* @param name - Name of warp
* @throws Exception
*/
void removeWarp(String name) throws Exception;
/**
* Delete a warp from the warp DB
*
* @param name - Name of warp
* @throws Exception
*/
void removeWarp(String name) throws Exception;
/**
* Set a warp
*
* @param name - Name of warp
* @param loc - Location of warp
* @throws Exception
*/
void setWarp(String name, Location loc) throws Exception;
/**
* Set a warp
*
* @param name - Name of warp
* @param loc - Location of warp
* @throws Exception
*/
void setWarp(String name, Location loc) throws Exception;
/**
* Check to see if the file is empty
*
* @return
*/
boolean isEmpty();
/**
* Set a warp
*
* @param user - User of warp
* @param name - Name of warp
* @param loc - Location of warp
* @throws Exception
*/
void setWarp(IUser user, String name, Location loc) throws Exception;
/**
* Get a warp file note: this is not yet implemented, as 3.x uses different storage methods
*
* @param name - name of file
* @return - an instance of the file
* @throws InvalidNameException - When the file is not found
*/
File getWarpFile(String name) throws InvalidNameException;
/**
* Gets Lastowner UUID
*
* @param warp - Name of warp
* @throws WarpNotFoundException
*/
UUID getLastOwner(String warp) throws WarpNotFoundException;
/**
* Check to see if the file is empty
*
* @return
*/
boolean isEmpty();
/**
* @deprecated This method relates to the abandoned 3.x storage refactor and is not implemented.
*/
@Deprecated
File getWarpFile(String name) throws net.ess3.api.InvalidNameException;
}
@@ -1,16 +1,17 @@
package com.earth2me.essentials.api;
/**
* @deprecated This exception relates to the abandoned 3.x storage refactor and is not implemented.
*/
@Deprecated
public class InvalidNameException extends Exception {
/**
* NOTE: This is not implemented yet, just here for future 3.x api support Allow serialization of the
* InvalidNameException exception
*/
private static final long serialVersionUID = 1485321420293663139L;
public class InvalidNameException extends Exception
{
/**
* NOTE: This is not implemented yet, just here for future 3.x api support
* Allow serialization of the InvalidNameException exception
*/
private static final long serialVersionUID = 1485321420293663139L;
public InvalidNameException(Throwable thrwbl)
{
super(thrwbl);
}
public InvalidNameException(final Throwable thrwbl) {
super(thrwbl);
}
}
@@ -1,20 +1,20 @@
package com.earth2me.essentials.api;
import static com.earth2me.essentials.I18n._;
import static com.earth2me.essentials.I18n.tl;
/**
* @deprecated This exception is unused. Use {@link net.ess3.api.InvalidWorldException} instead.
*/
@Deprecated
public class InvalidWorldException extends Exception {
private final String world;
public class InvalidWorldException extends Exception
{
private final String world;
public InvalidWorldException(final String world) {
super(tl("invalidWorld"));
this.world = world;
}
public InvalidWorldException(final String world)
{
super(_("invalidWorld"));
this.world = world;
}
public String getWorld()
{
return this.world;
}
public String getWorld() {
return this.world;
}
}
@@ -1,12 +1,8 @@
package com.earth2me.essentials.api;
import static com.earth2me.essentials.I18n._;
/**
* Thrown when a user does not have the balance for a transaction and cannot take a loan.
*/
public class NoLoanPermittedException extends net.ess3.api.NoLoanPermittedException {
public class NoLoanPermittedException extends Exception
{
public NoLoanPermittedException()
{
super(_("negativeBalanceError"));
}
}
@@ -1,12 +1,18 @@
package com.earth2me.essentials.api;
import static com.earth2me.essentials.I18n._;
import java.util.UUID;
import static com.earth2me.essentials.I18n.tl;
public class UserDoesNotExistException extends Exception
{
public UserDoesNotExistException(String name)
{
super(_("userDoesNotExist", name));
}
/**
* Thrown when the requested user does not exist.
*/
public class UserDoesNotExistException extends Exception {
public UserDoesNotExistException(final String name) {
super(tl("userDoesNotExist", name));
}
public UserDoesNotExistException(final UUID uuid) {
super(tl("uuidDoesNotExist", uuid.toString()));
}
}
@@ -1,71 +1,101 @@
package com.earth2me.essentials.commands;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.CommandSource;
import com.earth2me.essentials.User;
import org.bukkit.command.CommandSender;
import com.earth2me.essentials.utils.DateUtil;
import net.ess3.api.events.AfkStatusChangeEvent;
import org.bukkit.Server;
import java.util.Collections;
import java.util.List;
public class Commandafk extends EssentialsCommand
{
public Commandafk()
{
super("afk");
}
import static com.earth2me.essentials.I18n.tl;
@Override
public void run(Server server, User user, String commandLabel, String[] args) throws Exception
{
if (args.length > 0 && user.isAuthorized("essentials.afk.others"))
{
User afkUser = getPlayer(server, user, args, 0);
toggleAfk(afkUser);
}
else
{
toggleAfk(user);
}
}
@Override
public void run(Server server, CommandSender sender, String commandLabel, String[] args) throws Exception
{
if (args.length > 0)
{
User afkUser = getPlayer(server, args, 0, true, false);
toggleAfk(afkUser);
}
else
{
throw new NotEnoughArgumentsException();
}
}
public class Commandafk extends EssentialsCommand {
public Commandafk() {
super("afk");
}
private void toggleAfk(User user)
{
user.setDisplayNick();
String msg = "";
if (!user.toggleAfk())
{
//user.sendMessage(_("markedAsNotAway"));
if (!user.isHidden())
{
msg = _("userIsNotAway", user.getDisplayName());
}
user.updateActivity(false);
}
else
{
//user.sendMessage(_("markedAsAway"));
if (!user.isHidden())
{
msg = _("userIsAway", user.getDisplayName());
}
}
if (!msg.isEmpty())
{
ess.broadcastMessage(user, msg);
}
}
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
if (args.length > 0 && user.isAuthorized("essentials.afk.others")) {
User afkUser = user; // if no player found, but message specified, set command executor to target user
String message;
try {
afkUser = getPlayer(server, user, args, 0);
message = args.length > 1 ? getFinalArg(args, 1) : null;
} catch (final PlayerNotFoundException e) {
message = getFinalArg(args, 0);
}
toggleAfk(user, afkUser, message);
} else {
final String message = args.length > 0 ? getFinalArg(args, 0) : null;
toggleAfk(user, user, message);
}
}
@Override
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
if (args.length > 0) {
final User afkUser = getPlayer(server, args, 0, true, false);
final String message = args.length > 1 ? getFinalArg(args, 1) : null;
toggleAfk(null, afkUser, message);
} else {
throw new NotEnoughArgumentsException();
}
}
private void toggleAfk(final User sender, final User user, final String message) throws Exception {
if (message != null && sender != null) {
if (sender.isMuted()) {
final String dateDiff = sender.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(sender.getMuteTimeout()) : null;
if (dateDiff == null) {
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReason", sender.getMuteReason()) : tl("voiceSilenced"));
}
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, sender.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
}
if (!sender.isAuthorized("essentials.afk.message")) {
throw new Exception(tl("noPermToAFKMessage"));
}
}
user.setDisplayNick();
String msg = "";
String selfmsg = "";
if (!user.toggleAfk(AfkStatusChangeEvent.Cause.COMMAND)) {
if (!user.isHidden()) {
msg = tl("userIsNotAway", user.getDisplayName());
selfmsg = tl("userIsNotAwaySelf", user.getDisplayName());
}
user.updateActivity(false, AfkStatusChangeEvent.Cause.COMMAND);
} else {
if (!user.isHidden()) {
if (message != null) {
msg = tl("userIsAwayWithMessage", user.getDisplayName(), message);
selfmsg = tl("userIsAwaySelfWithMessage", user.getDisplayName(), message);
} else {
msg = tl("userIsAway", user.getDisplayName());
selfmsg = tl("userIsAwaySelf", user.getDisplayName());
}
}
user.setAfkMessage(message);
}
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
// exclude user from receiving general AFK announcement in favor of personal message
ess.broadcastMessage(user, msg, u -> u == user);
}
if (!selfmsg.isEmpty()) {
user.sendMessage(selfmsg);
}
user.setDisplayNick(); // Set this again after toggling
}
@Override
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
if (args.length == 1 && sender.isAuthorized("essentials.afk.others", ess)) {
return getPlayers(server, sender);
} else {
return Collections.emptyList();
}
}
}
@@ -7,23 +7,19 @@ import org.bukkit.Server;
import org.bukkit.entity.TNTPrimed;
// This command has a in theme message that only shows if you supply a parameter #EasterEgg
public class Commandantioch extends EssentialsCommand
{
public Commandantioch()
{
super("antioch");
}
public class Commandantioch extends EssentialsCommand {
public Commandantioch() {
super("antioch");
}
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception
{
if (args.length > 0)
{
ess.broadcastMessage(user, "...lobbest thou thy Holy Hand Grenade of Antioch towards thy foe,");
ess.broadcastMessage(user, "who being naughty in My sight, shall snuff it.");
}
@Override
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
if (args.length > 0) {
ess.broadcastMessage(user, "...lobbest thou thy Holy Hand Grenade of Antioch towards thy foe,");
ess.broadcastMessage(user, "who being naughty in My sight, shall snuff it.");
}
final Location loc = LocationUtil.getTarget(user);
loc.getWorld().spawn(loc, TNTPrimed.class);
}
final Location loc = LocationUtil.getTarget(user.getBase());
loc.getWorld().spawn(loc, TNTPrimed.class);
}
}
@@ -0,0 +1,23 @@
package com.earth2me.essentials.commands;
import com.earth2me.essentials.User;
import org.bukkit.Server;
import static com.earth2me.essentials.I18n.tl;
public class Commandanvil extends EssentialsCommand {
public Commandanvil() {
super("anvil");
}
@Override
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
if (ess.getContainerProvider() == null) {
user.sendMessage(tl("unsupportedBrand"));
return;
}
ess.getContainerProvider().openAnvil(user.getBase());
}
}
Loaded 100 of 661 files, more files were not shown because too many files have changed in this diff. Show more