mirror of
https://github.com/EssentialsX/Essentials.git
synced 2026-11-05 01:00:13 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2dde4154c | ||
|
|
12c2a4f2b5 | ||
|
|
ee7c1b1cf1 | ||
|
|
422f25af8b | ||
|
|
728c746200 | ||
|
|
6dfa18ca53 | ||
|
|
a394760677 | ||
|
|
5f48cdef13 | ||
|
|
c56a9e6741 | ||
|
|
5b20f30350 | ||
|
|
037577162b | ||
|
|
908189a233 | ||
|
|
c938767b2d | ||
|
|
b135fcf086 | ||
|
|
09dc49aacb | ||
|
|
f4b6197a49 | ||
|
|
4a53cfe7ac | ||
|
|
2bba577567 | ||
|
|
6e674c73e0 | ||
|
|
a60f3c067f | ||
|
|
6816eb4e18 | ||
|
|
9c5536b2e6 | ||
|
|
ff80338350 | ||
|
|
8d856dd6db | ||
|
|
96c6c951e8 | ||
|
|
0931b21f6d | ||
|
|
9147d1036d | ||
|
|
a7f602e2ad | ||
|
|
0c81980ead | ||
|
|
2d5794f68d | ||
|
|
6b80e0b113 | ||
|
|
18f9af898e | ||
|
|
d04c933abe | ||
|
|
b916488de2 | ||
|
|
c6066bd2d8 | ||
|
|
3af931740b | ||
|
|
1c5a7e9ffb | ||
|
|
ea5cdc097d | ||
|
|
d891268143 | ||
|
|
4bd1b3c09f | ||
|
|
c4f10d9c1d | ||
|
|
e12f1b5022 | ||
|
|
31732cec95 | ||
|
|
f104b6ec15 | ||
|
|
695546420f | ||
|
|
997fb1800e | ||
|
|
3984bddd9d | ||
|
|
d92ce8bdfe | ||
|
|
3348bd9129 | ||
|
|
1a5526867c | ||
|
|
c5253bc5e2 | ||
|
|
29a2a865c5 | ||
|
|
c3b994808f | ||
|
|
bc2da98703 | ||
|
|
cbb012853c | ||
|
|
4bf4bd432a | ||
|
|
83d0e0d9a0 | ||
|
|
2f5c24d114 | ||
|
|
88c8ccd29b | ||
|
|
94edbcfeb1 | ||
|
|
d5822e9a41 | ||
|
|
debf09437e | ||
|
|
a9e5f079a9 | ||
|
|
f00c2dcf92 | ||
|
|
63cbf7e2da | ||
|
|
19837f9309 | ||
|
|
4b8b770c30 | ||
|
|
ddc258ed11 | ||
|
|
d23796dade | ||
|
|
41f5cc3175 | ||
|
|
c6fe160b47 | ||
|
|
5c46bea2ca | ||
|
|
a9585bb525 | ||
|
|
bb88a6a749 | ||
|
|
739600eb05 | ||
|
|
5f98d3fac5 | ||
|
|
84326cf13e | ||
|
|
685084219e | ||
|
|
c4e62ae22b | ||
|
|
05ce11f657 | ||
|
|
bcb0fb5825 | ||
|
|
91f4493fe0 | ||
|
|
d53ff36a2a | ||
|
|
98917d97c8 | ||
|
|
7e1d18fee4 | ||
|
|
0b7e7801d0 | ||
|
|
840035944a | ||
|
|
20a7d1c7ee | ||
|
|
253185bd0e | ||
|
|
dae519494e | ||
|
|
dc27af78bf | ||
|
|
41861a8551 | ||
|
|
9b629e42d8 | ||
|
|
7794634d37 | ||
|
|
d091d6902c | ||
|
|
c45c741210 | ||
|
|
e35c65b976 | ||
|
|
0983167740 | ||
|
|
1509cf8978 | ||
|
|
c0082ee734 | ||
|
|
db2ec1b436 | ||
|
|
7a1e50d10f | ||
|
|
b6ba1768a1 | ||
|
|
c38dd997d2 | ||
|
|
f8ca1bae5d | ||
|
|
3c60bcf2de | ||
|
|
3f857e3183 | ||
|
|
668c9634ca | ||
|
|
51c49b0de6 | ||
|
|
5723dac6ba | ||
|
|
680d3230ea | ||
|
|
8f679de352 | ||
|
|
86d435eee1 | ||
|
|
e4cf965bae | ||
|
|
78c846a0a8 | ||
|
|
c466c9c370 | ||
|
|
6994005a5f | ||
|
|
e43f06bfa6 | ||
|
|
9601687190 | ||
|
|
2ed94f1048 | ||
|
|
70045c30f3 | ||
|
|
ce88c0e1e4 | ||
|
|
494e82e581 | ||
|
|
edd15132fd | ||
|
|
add664441e | ||
|
|
58b0fb089f | ||
|
|
90e4845627 | ||
|
|
43f4d306be | ||
|
|
cb7d9baf7a | ||
|
|
f3aea5e6ec | ||
|
|
a7a1fcd98c | ||
|
|
ef8bcc8bc4 | ||
|
|
b3692d18b0 | ||
|
|
a7b2b675d5 | ||
|
|
7d7a8e47ac | ||
|
|
f0da17b75c | ||
|
|
d86b471402 | ||
|
|
767508fb87 | ||
|
|
c85d772e1b | ||
|
|
fde6524e46 | ||
|
|
b2886969f0 | ||
|
|
19ca5186e4 | ||
|
|
b86a34c909 |
No files matched your search
@@ -22,24 +22,10 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "`/ess version` output"
|
||||
description: Run `/ess version` in the console, then copy and paste the full output of the command into this box.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Server startup log
|
||||
description: Upload your server startup log (from the start of `latest.log` up to where it says "Done!") to either https://paste.gg or https://gist.github.com, save and then paste the link in this box.
|
||||
placeholder: "Example: https://paste.gg/p/anonymous/109dd6a10a734a3aa430d5a351ea5210"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: EssentialsX config files
|
||||
description: Upload your EssentialsX `config.yml` (and any other relevant files like `kits.yml`) to either https://paste.gg or https://gist.github.com, save and then paste the link in this box. If you included those files in the same paste as your startup log, paste the same link here.
|
||||
placeholder: "Example: https://paste.gg/p/anonymous/109dd6a10a734a3aa430d5a351ea5210"
|
||||
label: "`/ess dump all` output"
|
||||
description: Run `/ess dump all` in the console, then copy and paste the link from the output of the command into this box. (If this command doesn't work, you should [update EssentialsX](https://essentialsx.net/downloads.html) and try again.)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
|
||||
@@ -4,6 +4,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- 2.x
|
||||
- dev/*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -9,6 +9,7 @@ on:
|
||||
branches:
|
||||
- 2.x
|
||||
- mc/*
|
||||
- dev/*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
+93
-22
@@ -1,31 +1,102 @@
|
||||
Contributing to EssentialsX
|
||||
===========================
|
||||
# Contributing to EssentialsX
|
||||
|
||||
Want to help improve EssentialsX? There are several ways you can support and contribute to the project.
|
||||
*By contributing to EssentialsX, you agree to license your changes under the [GNU General Public License version 3](https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE).*
|
||||
|
||||
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:
|
||||
## Submitting code changes to EssentialsX
|
||||
|
||||
* 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.
|
||||
If you're interested in submitting new code to EssentialsX, we accept changes via GitHub pull requests.
|
||||
|
||||
Submitting a PR
|
||||
---------------
|
||||
### Adding features
|
||||
|
||||
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)
|
||||
In general, we will only consider PRs for features if they have already been discussed with the team through
|
||||
GitHub issues and discussions. Check the list of
|
||||
["open to PR" issues](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22status%3A+open+to+PR%22)
|
||||
and [feature request discussions](https://github.com/EssentialsX/Essentials/discussions/categories/ideas-and-feature-suggestions)
|
||||
before you start working on your changes. If you don't see your desired feature listed,
|
||||
[open a feature request](https://github.com/EssentialsX/Essentials/issues/new/choose) and wait for a response, otherwise
|
||||
you may end up wasting your time on a feature that we aren't in a position to accept.
|
||||
|
||||
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.
|
||||
#### Keep it focused
|
||||
|
||||
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).
|
||||
Please try to keep feature PRs focused around one feature. Your PR should ideally contain
|
||||
one feature, or a few closely-linked features. If you submit several unrelated features
|
||||
in one PR, the PR will not be accepted.
|
||||
|
||||
### Fixing bugs
|
||||
|
||||
If you're opening a PR to fix a bug, please ensure a bug report has been filed - search the
|
||||
[issue tracker](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22bug%3A+confirmed%22%2C%22bug%3A+unconfirmed%22%2C%22bug%3A+upstream%22)
|
||||
for an existing report, and if you can't find a bug report,
|
||||
[create one](https://github.com/EssentialsX/Essentials/issues/new/choose) before you submit your PR.
|
||||
|
||||
#### Unconfirmed bugs
|
||||
|
||||
You may find a bug report with the label `bug: unconfirmed`. This means the EssentialsX team hasn't had the time
|
||||
to review the bug report yet or hasn't been able to confirm
|
||||
whether the reported issue is actually a bug in EssentialsX. You can help us by following the steps in the report and
|
||||
posting whether you are able to replicate this issue, ideally on the latest versions of EssentialsX and Paper. This will
|
||||
help us confirm issues and prioritise PRs accordingly.
|
||||
|
||||
#### Upstream bugs
|
||||
|
||||
You may also find bug reports with the `bug: upstream` label. This label means the issue is caused by a bug in *another
|
||||
project*, not EssentialsX. This includes bugs in CraftBukkit/Spigot and bugs in other plugins. It may be appropriate to
|
||||
mitigate an issue in EssentialsX, but please check with us in the [EssentialsX Development Discord server](https://discord.gg/CUN7qVb) before you submit a PR.
|
||||
|
||||
### Making your changes
|
||||
|
||||
You'll need the following to make your changes to EssentialsX:
|
||||
|
||||
* A GitHub account
|
||||
* [`git`](https://git-scm.com/downloads): the Git command-line tool, used to track and save your changes
|
||||
* [`gh`](https://cli.github.com/): the GitHub command-line tool, used to submit your changes to EssentialsX
|
||||
* Your IDE of choice - we recommend [IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download)
|
||||
|
||||
If you're already familiar with Git, you can skip this next section.
|
||||
|
||||
You'll need to clone the EssentialsX repository
|
||||
(`gh repo clone EssentialsX/Essentials`), then create a new branch for your work
|
||||
(`cd Essentials` then `git switch -c my-cool-pr`).
|
||||
|
||||
You can then make changes using your IDE of choice. Follow the instructions in `README.md` to build and test your
|
||||
changes.
|
||||
|
||||
Once you've finished, you should commit your changes (`git commit -am "My cool commit name!"`).
|
||||
|
||||
### Submitting your PR
|
||||
|
||||
*Even if you're already familiar with GitHub, you will need to follow these steps in order to submit a PR to
|
||||
EssentialsX. This ensures we have the information we need to test and review your changes.*
|
||||
|
||||
Next, you'll need to fork EssentialsX on GitHub and push your changes to a branch on that fork. We strongly recommend
|
||||
using the `gh` command-line tool for this:
|
||||
|
||||
* In your terminal, run `gh pr create`.
|
||||
* Select either the bug fix or feature template, depending on what your PR is for.
|
||||
* If you get asked `Where should we push the '...' branch?`, select `Create a fork of EssentialsX/Essentials`.
|
||||
* For the title, choose a title that describes what your PR does. For example, `Add more ducks to /spawnmob`.
|
||||
* For the body, press E. You will then need to fill in the PR template in your text editor.
|
||||
- Follow the instructions in the template and fill out the sections as required.
|
||||
- This step is important! Without it, we won't know why you've made your changes or how to test them.
|
||||
* Save the file in your text editor and close it, then return to the terminal.
|
||||
* Select `Submit` to open your PR.
|
||||
|
||||
If you follow these steps correctly, GitHub will create a fork (if necessary) and then open a PR with your changes. You
|
||||
can now sit back while we review your changes. If we need to ask questions or request further changes to your code,
|
||||
we will review your PR and post a comment on GitHub. You can respond to our reviews and comments on the GitHub website,
|
||||
and you can push new changes using `git commit` and `git push`.
|
||||
|
||||
|
||||
## Submitting community translations to EssentialsX
|
||||
|
||||
EssentialsX relies on community translations for its messages in other languages. You can help translate EssentialsX on
|
||||
[Crowdin](https://translate.essentialsx.net/). You'll need a Crowdin account to translate and improve messages.
|
||||
|
||||
If your language isn't listed or doesn't have an active proofreader, please let us know on Discord (see below).
|
||||
|
||||
|
||||
## Discussing EssentialsX contributions
|
||||
|
||||
Want to discuss something before opening a PR or translating messages? 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.
|
||||
@@ -10,6 +10,8 @@ dependencies {
|
||||
|
||||
api 'io.papermc:paperlib:1.0.6'
|
||||
|
||||
api 'org.bstats:bstats-bukkit:2.2.1'
|
||||
|
||||
implementation 'org.spongepowered:configurate-yaml:4.1.2'
|
||||
implementation 'org.checkerframework:checker-qual:3.14.0'
|
||||
|
||||
@@ -20,6 +22,9 @@ dependencies {
|
||||
exclude group: "org.bukkit", module: "bukkit"
|
||||
}
|
||||
api(project(':providers:1_8Provider')) {
|
||||
exclude group: "org.spigotmc", module: "spigot"
|
||||
}
|
||||
api(project(':providers:1_12Provider')) {
|
||||
exclude group: "org.bukkit", module: "bukkit"
|
||||
}
|
||||
}
|
||||
@@ -28,6 +33,7 @@ shadowJar {
|
||||
dependencies {
|
||||
include (dependency('io.papermc:paperlib'))
|
||||
include (dependency('org.bstats:bstats-bukkit'))
|
||||
include (dependency('org.bstats:bstats-base'))
|
||||
include (dependency('org.spongepowered:configurate-yaml'))
|
||||
include (dependency('org.spongepowered:configurate-core'))
|
||||
include (dependency('org.yaml:snakeyaml'))
|
||||
@@ -37,9 +43,10 @@ shadowJar {
|
||||
include (project(':providers:PaperProvider'))
|
||||
include (project(':providers:NMSReflectionProvider'))
|
||||
include (project(':providers:1_8Provider'))
|
||||
include (project(':providers:1_12Provider'))
|
||||
}
|
||||
relocate 'io.papermc.lib', 'com.earth2me.essentials.paperlib'
|
||||
relocate 'org.bstats.bukkit', 'com.earth2me.essentials.metrics'
|
||||
relocate 'org.bstats', 'com.earth2me.essentials.libs.bstats'
|
||||
relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.libs.configurate'
|
||||
relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.libs.snakeyaml'
|
||||
relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref'
|
||||
|
||||
@@ -11,10 +11,8 @@ 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("Essentials");
|
||||
private final transient Map<String, List<Command>> altcommands = new HashMap<>();
|
||||
private final transient Map<String, String> disabledList = new HashMap<>();
|
||||
private final transient IEssentials ess;
|
||||
@@ -29,11 +27,12 @@ public class AlternativeCommandsHandler {
|
||||
}
|
||||
|
||||
public final void addPlugin(final Plugin plugin) {
|
||||
if (plugin.getDescription().getMain().contains("com.earth2me.essentials")) {
|
||||
if (plugin.getDescription().getMain().contains("com.earth2me.essentials") || plugin.getDescription().getMain().contains("net.essentialsx")) {
|
||||
return;
|
||||
}
|
||||
for (final Map.Entry<String, Command> entry : getPluginCommands(plugin).entrySet()) {
|
||||
final String commandName = entry.getKey().contains(":") ? entry.getKey().split(":")[1] : entry.getKey();
|
||||
final String[] commandSplit = entry.getKey().split(":", 2);
|
||||
final String commandName = commandSplit.length > 1 ? commandSplit[1] : entry.getKey();
|
||||
final Command command = entry.getValue();
|
||||
|
||||
final List<Command> pluginCommands = altcommands.computeIfAbsent(commandName.toLowerCase(Locale.ENGLISH), k -> new ArrayList<>());
|
||||
@@ -94,7 +93,7 @@ public class AlternativeCommandsHandler {
|
||||
if (pc instanceof PluginIdentifiableCommand) {
|
||||
final String altString = ((PluginIdentifiableCommand) pc).getPlugin().getName() + ":" + pc.getName();
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Essentials: Alternative command " + label + " found, using " + altString);
|
||||
ess.getLogger().log(Level.INFO, "Essentials: Alternative command " + label + " found, using " + altString);
|
||||
}
|
||||
disabledList.put(label, altString);
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ public class AsyncTeleport implements IAsyncTeleport {
|
||||
}
|
||||
PaperLib.getChunkAtAsync(targetLoc.getWorld(), targetLoc.getBlockX() >> 4, targetLoc.getBlockZ() >> 4, true, true).thenAccept(chunk -> {
|
||||
Location loc = targetLoc;
|
||||
if (LocationUtil.isBlockUnsafeForUser(teleportee, chunk.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
|
||||
if (LocationUtil.isBlockUnsafeForUser(ess, 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.
|
||||
@@ -308,7 +308,7 @@ public class AsyncTeleport implements IAsyncTeleport {
|
||||
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);
|
||||
final TeleportWarmupEvent event = new TeleportWarmupEvent(teleporter, teleportee, cause, target, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
|
||||
@@ -10,12 +10,10 @@ 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;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
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);
|
||||
@@ -81,7 +79,7 @@ public class Backup implements Runnable {
|
||||
taskLock.complete(new Object());
|
||||
return;
|
||||
}
|
||||
LOGGER.log(Level.INFO, tl("backupStarted"));
|
||||
ess.getLogger().log(Level.INFO, tl("backupStarted"));
|
||||
final CommandSender cs = server.getConsoleSender();
|
||||
server.dispatchCommand(cs, "save-all");
|
||||
server.dispatchCommand(cs, "save-off");
|
||||
@@ -99,17 +97,17 @@ public class Backup implements Runnable {
|
||||
do {
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
LOGGER.log(Level.INFO, line);
|
||||
ess.getLogger().log(Level.INFO, line);
|
||||
}
|
||||
} while (line != null);
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
ess.getLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
});
|
||||
child.waitFor();
|
||||
} catch (final InterruptedException | IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
ess.getLogger().log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
class BackupEnableSaveTask implements Runnable {
|
||||
@Override
|
||||
@@ -120,7 +118,7 @@ public class Backup implements Runnable {
|
||||
}
|
||||
active = false;
|
||||
taskLock.complete(new Object());
|
||||
LOGGER.log(Level.INFO, tl("backupFinished"));
|
||||
ess.getLogger().log(Level.INFO, tl("backupFinished"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -263,6 +263,14 @@ public final class Enchantments {
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
try { // 1.19
|
||||
final Enchantment swiftSneak = Enchantment.getByName("SWIFT_SNEAK");
|
||||
if (swiftSneak != null) {
|
||||
ENCHANTMENTS.put("swiftsneak", swiftSneak);
|
||||
}
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
try {
|
||||
final Class<?> namespacedKeyClass = Class.forName("org.bukkit.NamespacedKey");
|
||||
final Class<?> enchantmentClass = Class.forName("org.bukkit.enchantments.Enchantment");
|
||||
|
||||
@@ -47,6 +47,7 @@ import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IItemDb;
|
||||
import net.ess3.api.IJails;
|
||||
import net.ess3.api.ISettings;
|
||||
import net.ess3.nms.refl.providers.ReflDataWorldInfoProvider;
|
||||
import net.ess3.nms.refl.providers.ReflFormattedCommandAliasProvider;
|
||||
import net.ess3.nms.refl.providers.ReflKnownCommandsProvider;
|
||||
import net.ess3.nms.refl.providers.ReflOnlineModeProvider;
|
||||
@@ -57,25 +58,34 @@ import net.ess3.nms.refl.providers.ReflSpawnerBlockProvider;
|
||||
import net.ess3.nms.refl.providers.ReflSyncCommandsProvider;
|
||||
import net.ess3.provider.ContainerProvider;
|
||||
import net.ess3.provider.FormattedCommandAliasProvider;
|
||||
import net.ess3.provider.ItemUnbreakableProvider;
|
||||
import net.ess3.provider.KnownCommandsProvider;
|
||||
import net.ess3.provider.MaterialTagProvider;
|
||||
import net.ess3.provider.PersistentDataProvider;
|
||||
import net.ess3.provider.PotionMetaProvider;
|
||||
import net.ess3.provider.SerializationProvider;
|
||||
import net.ess3.provider.ProviderListener;
|
||||
import net.ess3.provider.SerializationProvider;
|
||||
import net.ess3.provider.ServerStateProvider;
|
||||
import net.ess3.provider.SignDataProvider;
|
||||
import net.ess3.provider.SpawnEggProvider;
|
||||
import net.ess3.provider.SpawnerBlockProvider;
|
||||
import net.ess3.provider.SpawnerItemProvider;
|
||||
import net.ess3.provider.SyncCommandsProvider;
|
||||
import net.ess3.provider.WorldInfoProvider;
|
||||
import net.ess3.provider.providers.BaseLoggerProvider;
|
||||
import net.ess3.provider.providers.BasePotionDataProvider;
|
||||
import net.ess3.provider.providers.BlockMetaSpawnerItemProvider;
|
||||
import net.ess3.provider.providers.BukkitMaterialTagProvider;
|
||||
import net.ess3.provider.providers.BukkitSpawnerBlockProvider;
|
||||
import net.ess3.provider.providers.FixedHeightWorldInfoProvider;
|
||||
import net.ess3.provider.providers.FlatSpawnEggProvider;
|
||||
import net.ess3.provider.providers.LegacyItemUnbreakableProvider;
|
||||
import net.ess3.provider.providers.LegacyPotionMetaProvider;
|
||||
import net.ess3.provider.providers.LegacySpawnEggProvider;
|
||||
import net.ess3.provider.providers.ModernDataWorldInfoProvider;
|
||||
import net.ess3.provider.providers.ModernItemUnbreakableProvider;
|
||||
import net.ess3.provider.providers.ModernPersistentDataProvider;
|
||||
import net.ess3.provider.providers.ModernSignDataProvider;
|
||||
import net.ess3.provider.providers.PaperContainerProvider;
|
||||
import net.ess3.provider.providers.PaperKnownCommandsProvider;
|
||||
import net.ess3.provider.providers.PaperMaterialTagProvider;
|
||||
@@ -84,7 +94,6 @@ import net.ess3.provider.providers.PaperSerializationProvider;
|
||||
import net.ess3.provider.providers.PaperServerStateProvider;
|
||||
import net.essentialsx.api.v2.services.BalanceTop;
|
||||
import net.essentialsx.api.v2.services.mail.MailService;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
@@ -103,7 +112,6 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.plugin.InvalidDescriptionException;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
@@ -133,7 +141,8 @@ import java.util.logging.Logger;
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private static final Logger BUKKIT_LOGGER = Logger.getLogger("Essentials");
|
||||
private static Logger LOGGER = null;
|
||||
private final transient TNTExplodeListener tntListener = new TNTExplodeListener(this);
|
||||
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
|
||||
private transient ISettings settings;
|
||||
@@ -167,6 +176,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
private transient SyncCommandsProvider syncCommandsProvider;
|
||||
private transient PersistentDataProvider persistentDataProvider;
|
||||
private transient ReflOnlineModeProvider onlineModeProvider;
|
||||
private transient ItemUnbreakableProvider unbreakableProvider;
|
||||
private transient WorldInfoProvider worldInfoProvider;
|
||||
private transient SignDataProvider signDataProvider;
|
||||
private transient Kits kits;
|
||||
private transient RandomTeleport randomTeleport;
|
||||
private transient UpdateChecker updateChecker;
|
||||
@@ -193,6 +205,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
}
|
||||
|
||||
public void setupForTesting(final Server server) throws IOException, InvalidDescriptionException {
|
||||
LOGGER = new BaseLoggerProvider(this, BUKKIT_LOGGER);
|
||||
final File dataFolder = File.createTempFile("essentialstest", "");
|
||||
if (!dataFolder.delete()) {
|
||||
throw new IOException();
|
||||
@@ -233,9 +246,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
try {
|
||||
if (LOGGER != this.getLogger()) {
|
||||
LOGGER.setParent(this.getLogger());
|
||||
if (BUKKIT_LOGGER != super.getLogger()) {
|
||||
BUKKIT_LOGGER.setParent(super.getLogger());
|
||||
}
|
||||
LOGGER = EssentialsLogger.getLoggerProvider(this);
|
||||
EssentialsLogger.updatePluginLogger(this);
|
||||
|
||||
execTimer = new ExecuteTimer();
|
||||
execTimer.start();
|
||||
i18n = new I18n(this);
|
||||
@@ -251,6 +267,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
case DANGEROUS_FORK:
|
||||
getLogger().severe(tl("serverUnsupportedDangerous"));
|
||||
break;
|
||||
case STUPID_PLUGIN:
|
||||
getLogger().severe(tl("serverUnsupportedDumbPlugins"));
|
||||
break;
|
||||
case UNSTABLE:
|
||||
getLogger().severe(tl("serverUnsupportedMods"));
|
||||
break;
|
||||
@@ -410,6 +429,24 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
onlineModeProvider = new ReflOnlineModeProvider();
|
||||
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01)) {
|
||||
unbreakableProvider = new ModernItemUnbreakableProvider();
|
||||
} else {
|
||||
unbreakableProvider = new LegacyItemUnbreakableProvider();
|
||||
}
|
||||
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_17_1_R01)) {
|
||||
worldInfoProvider = new ModernDataWorldInfoProvider();
|
||||
} else if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_16_5_R01)) {
|
||||
worldInfoProvider = new ReflDataWorldInfoProvider();
|
||||
} else {
|
||||
worldInfoProvider = new FixedHeightWorldInfoProvider();
|
||||
}
|
||||
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_14_4_R01)) {
|
||||
signDataProvider = new ModernSignDataProvider(this);
|
||||
}
|
||||
|
||||
execTimer.mark("Init(Providers)");
|
||||
reload();
|
||||
|
||||
@@ -444,7 +481,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
final String timeroutput = execTimer.end();
|
||||
if (getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Essentials load {0}", timeroutput);
|
||||
LOGGER.log(Level.INFO, "Essentials load " + timeroutput);
|
||||
}
|
||||
} catch (final NumberFormatException ex) {
|
||||
handleCrash(ex);
|
||||
@@ -455,6 +492,15 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
getBackup().setPendingShutdown(false);
|
||||
}
|
||||
|
||||
// Returns our provider logger if available
|
||||
public static Logger getWrappedLogger() {
|
||||
if (LOGGER != null) {
|
||||
return LOGGER;
|
||||
}
|
||||
|
||||
return BUKKIT_LOGGER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveConfig() {
|
||||
// We don't use any of the bukkit config writing, as this breaks our config file formatting.
|
||||
@@ -603,7 +649,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
return completer.onTabComplete(cSender, command, commandLabel, args);
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -684,7 +730,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
try {
|
||||
pc.execute(cSender, commandLabel, args);
|
||||
} catch (final Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
cSender.sendMessage(tl("internalError"));
|
||||
}
|
||||
return true;
|
||||
@@ -704,10 +750,10 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
if (bSenderBlock != null) {
|
||||
if (getSettings().logCommandBlockCommands()) {
|
||||
Bukkit.getLogger().log(Level.INFO, "CommandBlock at {0},{1},{2} issued server command: /{3} {4}", new Object[] {bSenderBlock.getX(), bSenderBlock.getY(), bSenderBlock.getZ(), commandLabel, EssentialsCommand.getFinalArg(args, 0)});
|
||||
LOGGER.log(Level.INFO, "CommandBlock at " + bSenderBlock.getX() + "," + bSenderBlock.getY() + "," + bSenderBlock.getZ() + " issued server command: /" + commandLabel + " " + EssentialsCommand.getFinalArg(args, 0));
|
||||
}
|
||||
} else if (user == null) {
|
||||
Bukkit.getLogger().log(Level.INFO, "{0} issued server command: /{1} {2}", new Object[] {cSender.getName(), commandLabel, EssentialsCommand.getFinalArg(args, 0)});
|
||||
LOGGER.log(Level.INFO, cSender.getName()+ " issued server command: /" + commandLabel + " " + EssentialsCommand.getFinalArg(args, 0));
|
||||
}
|
||||
|
||||
final CommandSource sender = new CommandSource(cSender);
|
||||
@@ -727,7 +773,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
if (getSettings().isCommandDisabled(commandLabel)) {
|
||||
if (getKnownCommandsProvider().getKnownCommands().containsKey(commandLabel)) {
|
||||
final Command newCmd = getKnownCommandsProvider().getKnownCommands().get(commandLabel);
|
||||
if (!(newCmd instanceof PluginIdentifiableCommand) || ((PluginIdentifiableCommand) newCmd).getPlugin() != this) {
|
||||
if (!(newCmd instanceof PluginIdentifiableCommand) || !isEssentialsPlugin(((PluginIdentifiableCommand) newCmd).getPlugin())) {
|
||||
return newCmd.execute(cSender, commandLabel, args);
|
||||
}
|
||||
}
|
||||
@@ -771,14 +817,15 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
} catch (final NoChargeException | QuietAbortException ex) {
|
||||
return true;
|
||||
} catch (final NotEnoughArgumentsException ex) {
|
||||
sender.sendMessage(tl("commandHelpLine1", commandLabel));
|
||||
sender.sendMessage(tl("commandHelpLine2", command.getDescription()));
|
||||
sender.sendMessage(tl("commandHelpLine3"));
|
||||
if (getSettings().isVerboseCommandUsages() && !cmd.getUsageStrings().isEmpty()) {
|
||||
sender.sendMessage(tl("commandHelpLine1", commandLabel));
|
||||
sender.sendMessage(tl("commandHelpLine2", command.getDescription()));
|
||||
sender.sendMessage(tl("commandHelpLine3"));
|
||||
for (Map.Entry<String, String> usage : cmd.getUsageStrings().entrySet()) {
|
||||
sender.sendMessage(tl("commandHelpLineUsage", usage.getKey().replace("<command>", commandLabel), usage.getValue()));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(command.getDescription());
|
||||
sender.sendMessage(command.getUsage().replace("<command>", commandLabel));
|
||||
}
|
||||
if (!ex.getMessage().isEmpty()) {
|
||||
@@ -801,6 +848,10 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEssentialsPlugin(Plugin plugin) {
|
||||
return plugin.getDescription().getMain().contains("com.earth2me.essentials") || plugin.getDescription().getMain().contains("net.essentialsx");
|
||||
}
|
||||
|
||||
public void cleanupOpenInventories() {
|
||||
for (final User user : getOnlineUsers()) {
|
||||
if (user.isRecipeSee()) {
|
||||
@@ -1014,7 +1065,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
if (user == null) {
|
||||
if (getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Constructing new userfile from base player {0}", base.getName());
|
||||
LOGGER.log(Level.INFO, "Constructing new userfile from base player " + base.getName());
|
||||
}
|
||||
user = new User(base, this);
|
||||
} else {
|
||||
@@ -1269,6 +1320,21 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
return onlineModeProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemUnbreakableProvider getItemUnbreakableProvider() {
|
||||
return unbreakableProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldInfoProvider getWorldInfoProvider() {
|
||||
return worldInfoProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignDataProvider getSignDataProvider() {
|
||||
return signDataProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginCommand getPluginCommand(final String cmd) {
|
||||
return this.getCommand(cmd);
|
||||
@@ -1302,25 +1368,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onWorldLoad(final WorldLoadEvent event) {
|
||||
PermissionsDefaults.registerBackDefaultFor(event.getWorld());
|
||||
|
||||
ess.getJails().reloadConfig();
|
||||
ess.getWarps().reloadConfig();
|
||||
for (final IConf iConf : ((Essentials) ess).confList) {
|
||||
if (iConf instanceof IEssentialsModule) {
|
||||
iConf.reloadConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onWorldUnload(final WorldUnloadEvent event) {
|
||||
ess.getJails().reloadConfig();
|
||||
ess.getWarps().reloadConfig();
|
||||
for (final IConf iConf : ((Essentials) ess).confList) {
|
||||
if (iConf instanceof IEssentialsModule) {
|
||||
iConf.reloadConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -42,8 +42,12 @@ public class EssentialsBlockListener implements Listener {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.hasUnlimited(is) && user.getBase().getGameMode() == GameMode.SURVIVAL) {
|
||||
ess.scheduleSyncDelayedTask(() -> {
|
||||
user.getBase().getInventory().addItem(is);
|
||||
user.getBase().updateInventory();
|
||||
if (is != null && is.getType() != null && !MaterialUtil.isAir(is.getType())) {
|
||||
final ItemStack cloneIs = is.clone();
|
||||
cloneIs.setAmount(1);
|
||||
user.getBase().getInventory().addItem(cloneIs);
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,674 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class EssentialsConf extends YamlConfiguration {
|
||||
protected static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
protected static final Charset UTF8 = StandardCharsets.UTF_8;
|
||||
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
|
||||
protected final File configFile;
|
||||
private final AtomicInteger pendingDiskWrites = new AtomicInteger(0);
|
||||
private final AtomicBoolean transaction = new AtomicBoolean(false);
|
||||
private final byte[] bytebuffer = new byte[1024];
|
||||
protected String templateName = null;
|
||||
private Class<?> resourceClass = EssentialsConf.class;
|
||||
|
||||
public EssentialsConf(final File configFile) {
|
||||
super();
|
||||
this.configFile = configFile.getAbsoluteFile();
|
||||
}
|
||||
|
||||
public static BigDecimal toBigDecimal(final String input, final BigDecimal def) {
|
||||
if (input == null || input.isEmpty()) {
|
||||
return def;
|
||||
} else {
|
||||
try {
|
||||
return new BigDecimal(input, MathContext.DECIMAL128);
|
||||
} catch (final NumberFormatException | ArithmeticException e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void load() {
|
||||
if (pendingDiskWrites.get() != 0) {
|
||||
LOGGER.log(Level.INFO, "File {0} not read, because it''s not yet written to disk.", configFile);
|
||||
return;
|
||||
}
|
||||
if (!configFile.getParentFile().exists()) {
|
||||
if (!configFile.getParentFile().mkdirs()) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()));
|
||||
}
|
||||
}
|
||||
// This will delete files where the first character is 0. In most cases they are broken.
|
||||
if (configFile.exists() && configFile.length() != 0) {
|
||||
try {
|
||||
final InputStream input = new FileInputStream(configFile);
|
||||
try {
|
||||
if (input.read() == 0) {
|
||||
input.close();
|
||||
configFile.delete();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
input.close();
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
} catch (final FileNotFoundException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (!configFile.exists()) {
|
||||
if (legacyFileExists()) {
|
||||
convertLegacyFile();
|
||||
} else if (altFileExists()) {
|
||||
convertAltFile();
|
||||
} else if (templateName != null) {
|
||||
LOGGER.log(Level.INFO, tl("creatingConfigFromTemplate", configFile.toString()));
|
||||
createFromTemplate();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
try (final FileInputStream inputStream = new FileInputStream(configFile)) {
|
||||
final long startSize = configFile.length();
|
||||
if (startSize > Integer.MAX_VALUE) {
|
||||
throw new InvalidConfigurationException("File too big");
|
||||
}
|
||||
ByteBuffer buffer = ByteBuffer.allocate((int) startSize);
|
||||
int length;
|
||||
while ((length = inputStream.read(bytebuffer)) != -1) {
|
||||
if (length > buffer.remaining()) {
|
||||
final ByteBuffer resize = ByteBuffer.allocate(buffer.capacity() + length - buffer.remaining());
|
||||
final int resizePosition = buffer.position();
|
||||
// Fix builds compiled against Java 9+ breaking on Java 8
|
||||
((Buffer) buffer).rewind();
|
||||
resize.put(buffer);
|
||||
resize.position(resizePosition);
|
||||
buffer = resize;
|
||||
}
|
||||
buffer.put(bytebuffer, 0, length);
|
||||
}
|
||||
((Buffer) buffer).rewind();
|
||||
final CharBuffer data = CharBuffer.allocate(buffer.capacity());
|
||||
CharsetDecoder decoder = UTF8.newDecoder();
|
||||
CoderResult result = decoder.decode(buffer, data, true);
|
||||
if (result.isError()) {
|
||||
((Buffer) buffer).rewind();
|
||||
((Buffer) data).clear();
|
||||
LOGGER.log(Level.INFO, "File " + configFile.getAbsolutePath() + " is not utf-8 encoded, trying " + Charset.defaultCharset().displayName());
|
||||
decoder = Charset.defaultCharset().newDecoder();
|
||||
result = decoder.decode(buffer, data, true);
|
||||
if (result.isError()) {
|
||||
throw new InvalidConfigurationException("Invalid Characters in file " + configFile.getAbsolutePath());
|
||||
} else {
|
||||
decoder.flush(data);
|
||||
}
|
||||
} else {
|
||||
decoder.flush(data);
|
||||
}
|
||||
final int end = data.position();
|
||||
((Buffer) data).rewind();
|
||||
super.loadFromString(data.subSequence(0, end).toString());
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
} catch (final InvalidConfigurationException ex) {
|
||||
final File broken = new File(configFile.getAbsolutePath() + ".broken." + System.currentTimeMillis());
|
||||
configFile.renameTo(broken);
|
||||
LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), ex.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean legacyFileExists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void convertLegacyFile() {
|
||||
LOGGER.log(Level.SEVERE, "Unable to import legacy config file.");
|
||||
}
|
||||
|
||||
public boolean altFileExists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void convertAltFile() {
|
||||
LOGGER.log(Level.SEVERE, "Unable to import alt config file.");
|
||||
}
|
||||
|
||||
private void createFromTemplate() {
|
||||
InputStream istr = null;
|
||||
OutputStream ostr = null;
|
||||
try {
|
||||
istr = resourceClass.getResourceAsStream(templateName);
|
||||
if (istr == null) {
|
||||
LOGGER.log(Level.SEVERE, tl("couldNotFindTemplate", templateName));
|
||||
return;
|
||||
}
|
||||
ostr = new FileOutputStream(configFile);
|
||||
final byte[] buffer = new byte[1024];
|
||||
int length = 0;
|
||||
length = istr.read(buffer);
|
||||
while (length > 0) {
|
||||
ostr.write(buffer, 0, length);
|
||||
length = istr.read(buffer);
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToWriteConfig", configFile.toString()), ex);
|
||||
} finally {
|
||||
try {
|
||||
if (istr != null) {
|
||||
istr.close();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger(EssentialsConf.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
try {
|
||||
if (ostr != null) {
|
||||
ostr.close();
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCloseConfig", configFile.toString()), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setTemplateName(final String templateName) {
|
||||
this.templateName = templateName;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return configFile;
|
||||
}
|
||||
|
||||
public void setTemplateName(final String templateName, final Class<?> resClass) {
|
||||
this.templateName = templateName;
|
||||
this.resourceClass = resClass;
|
||||
}
|
||||
|
||||
public void startTransaction() {
|
||||
transaction.set(true);
|
||||
}
|
||||
|
||||
public void stopTransaction() {
|
||||
transaction.set(false);
|
||||
save();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
save(configFile);
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveWithError() throws IOException {
|
||||
save(configFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void save(final File file) throws IOException {
|
||||
if (!transaction.get()) {
|
||||
delayedSave(file);
|
||||
}
|
||||
}
|
||||
|
||||
//This may be aborted if there are stagnant requests sitting in queue.
|
||||
//This needs fixed to discard outstanding save requests.
|
||||
public synchronized void forceSave() {
|
||||
try {
|
||||
final Future<?> future = delayedSave(configFile);
|
||||
if (future != null) {
|
||||
future.get();
|
||||
}
|
||||
} catch (final InterruptedException | ExecutionException ex) {
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void cleanup() {
|
||||
forceSave();
|
||||
}
|
||||
|
||||
private Future<?> delayedSave(final File file) {
|
||||
if (file == null) {
|
||||
throw new IllegalArgumentException("File cannot be null");
|
||||
}
|
||||
|
||||
final String data = saveToString();
|
||||
|
||||
if (data.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
pendingDiskWrites.incrementAndGet();
|
||||
|
||||
return EXECUTOR_SERVICE.submit(new WriteRunner(configFile, data, pendingDiskWrites));
|
||||
}
|
||||
|
||||
public boolean hasProperty(final String path) {
|
||||
return isSet(path);
|
||||
}
|
||||
|
||||
public Location getLocation(final String path, final Server server) throws InvalidWorldException {
|
||||
final String worldString = (path == null ? "" : path + ".") + "world";
|
||||
final String worldName = getString(worldString);
|
||||
if (worldName == null || worldName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final World world = server.getWorld(worldName);
|
||||
if (world == null) {
|
||||
throw new InvalidWorldException(worldName);
|
||||
}
|
||||
return new Location(world, getDouble((path == null ? "" : path + ".") + "x", 0), getDouble((path == null ? "" : path + ".") + "y", 0), getDouble((path == null ? "" : path + ".") + "z", 0), (float) getDouble((path == null ? "" : path + ".") + "yaw", 0), (float) getDouble((path == null ? "" : path + ".") + "pitch", 0));
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final Location loc) {
|
||||
set((path == null ? "" : path + ".") + "world", loc.getWorld().getName());
|
||||
set((path == null ? "" : path + ".") + "x", loc.getX());
|
||||
set((path == null ? "" : path + ".") + "y", loc.getY());
|
||||
set((path == null ? "" : path + ".") + "z", loc.getZ());
|
||||
set((path == null ? "" : path + ".") + "yaw", loc.getYaw());
|
||||
set((path == null ? "" : path + ".") + "pitch", loc.getPitch());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(final String path) {
|
||||
final ItemStack stack = new ItemStack(Material.valueOf(getString(path + ".type", "AIR")), getInt(path + ".amount", 1), (short) getInt(path + ".damage", 0));
|
||||
final ConfigurationSection enchants = getConfigurationSection(path + ".enchant");
|
||||
if (enchants != null) {
|
||||
for (final String enchant : enchants.getKeys(false)) {
|
||||
final Enchantment enchantment = Enchantment.getByName(enchant.toUpperCase(Locale.ENGLISH));
|
||||
if (enchantment == null) {
|
||||
continue;
|
||||
}
|
||||
final int level = getInt(path + ".enchant." + enchant, enchantment.getStartLevel());
|
||||
stack.addUnsafeEnchantment(enchantment, level);
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
/*
|
||||
* ,
|
||||
* (byte)getInt(path + ".data", 0)
|
||||
*/
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final ItemStack stack) {
|
||||
final Map<String, Object> map = new HashMap<>();
|
||||
map.put("type", stack.getType().toString());
|
||||
map.put("amount", stack.getAmount());
|
||||
map.put("damage", stack.getDurability());
|
||||
final Map<Enchantment, Integer> enchantments = stack.getEnchantments();
|
||||
if (!enchantments.isEmpty()) {
|
||||
final Map<String, Integer> enchant = new HashMap<>();
|
||||
for (final Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||
enchant.put(entry.getKey().getName().toLowerCase(Locale.ENGLISH), entry.getValue());
|
||||
}
|
||||
map.put("enchant", enchant);
|
||||
}
|
||||
// getData().getData() is broken
|
||||
//map.put("data", stack.getDurability());
|
||||
set(path, map);
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final List object) {
|
||||
set(path, new ArrayList(object));
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final Map object) {
|
||||
set(path, new LinkedHashMap(object));
|
||||
}
|
||||
|
||||
public Object getProperty(final String path) {
|
||||
return get(path);
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final BigDecimal bigDecimal) {
|
||||
set(path, bigDecimal.toString());
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final Object object) {
|
||||
set(path, object);
|
||||
}
|
||||
|
||||
public void removeProperty(final String path) {
|
||||
set(path, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object get(final String path) {
|
||||
return super.get(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object get(final String path, final Object def) {
|
||||
return super.get(path, def);
|
||||
}
|
||||
|
||||
public synchronized BigDecimal getBigDecimal(final String path, final BigDecimal def) {
|
||||
final String input = super.getString(path);
|
||||
return toBigDecimal(input, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean getBoolean(final String path) {
|
||||
return super.getBoolean(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean getBoolean(final String path, final boolean def) {
|
||||
return super.getBoolean(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Boolean> getBooleanList(final String path) {
|
||||
return super.getBooleanList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Byte> getByteList(final String path) {
|
||||
return super.getByteList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Character> getCharacterList(final String path) {
|
||||
return super.getCharacterList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ConfigurationSection getConfigurationSection(final String path) {
|
||||
return super.getConfigurationSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getDouble(final String path) {
|
||||
return super.getDouble(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getDouble(final String path, final double def) {
|
||||
return super.getDouble(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Double> getDoubleList(final String path) {
|
||||
return super.getDoubleList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Float> getFloatList(final String path) {
|
||||
return super.getFloatList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getInt(final String path) {
|
||||
return super.getInt(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getInt(final String path, final int def) {
|
||||
return super.getInt(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Integer> getIntegerList(final String path) {
|
||||
return super.getIntegerList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ItemStack getItemStack(final String path, final ItemStack def) {
|
||||
return super.getItemStack(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Set<String> getKeys(final boolean deep) {
|
||||
return super.getKeys(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<?> getList(final String path) {
|
||||
return super.getList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<?> getList(final String path, final List<?> def) {
|
||||
return super.getList(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long getLong(final String path) {
|
||||
return super.getLong(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long getLong(final String path, final long def) {
|
||||
return super.getLong(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Long> getLongList(final String path) {
|
||||
return super.getLongList(path);
|
||||
}
|
||||
|
||||
public synchronized Map<String, Object> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Map<?, ?>> getMapList(final String path) {
|
||||
return super.getMapList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized OfflinePlayer getOfflinePlayer(final String path) {
|
||||
return super.getOfflinePlayer(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized OfflinePlayer getOfflinePlayer(final String path, final OfflinePlayer def) {
|
||||
return super.getOfflinePlayer(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Short> getShortList(final String path) {
|
||||
return super.getShortList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String getString(final String path) {
|
||||
return super.getString(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String getString(final String path, final String def) {
|
||||
return super.getString(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getStringList(final String path) {
|
||||
return super.getStringList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Map<String, Object> getValues(final boolean deep) {
|
||||
return super.getValues(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Vector getVector(final String path) {
|
||||
return super.getVector(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Vector getVector(final String path, final Vector def) {
|
||||
return super.getVector(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isBoolean(final String path) {
|
||||
return super.isBoolean(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isConfigurationSection(final String path) {
|
||||
return super.isConfigurationSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isDouble(final String path) {
|
||||
return super.isDouble(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isInt(final String path) {
|
||||
return super.isInt(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isItemStack(final String path) {
|
||||
return super.isItemStack(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isList(final String path) {
|
||||
return super.isList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isLong(final String path) {
|
||||
return super.isLong(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isOfflinePlayer(final String path) {
|
||||
return super.isOfflinePlayer(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isSet(final String path) {
|
||||
return super.isSet(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isString(final String path) {
|
||||
return super.isString(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isVector(final String path) {
|
||||
return super.isVector(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void set(final String path, final Object value) {
|
||||
super.set(path, value);
|
||||
}
|
||||
|
||||
private static final class WriteRunner implements Runnable {
|
||||
private final File configFile;
|
||||
private final String data;
|
||||
private final AtomicInteger pendingDiskWrites;
|
||||
|
||||
private WriteRunner(final File configFile, final String data, final AtomicInteger pendingDiskWrites) {
|
||||
this.configFile = configFile;
|
||||
this.data = data;
|
||||
this.pendingDiskWrites = pendingDiskWrites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//long startTime = System.nanoTime();
|
||||
synchronized (configFile) {
|
||||
if (pendingDiskWrites.get() > 1) {
|
||||
// Writes can be skipped, because they are stored in a queue (in the executor).
|
||||
// Only the last is actually written.
|
||||
pendingDiskWrites.decrementAndGet();
|
||||
//LOGGER.log(Level.INFO, configFile + " skipped writing in " + (System.nanoTime() - startTime) + " nsec.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Files.createParentDirs(configFile);
|
||||
|
||||
if (!configFile.exists()) {
|
||||
try {
|
||||
LOGGER.log(Level.INFO, tl("creatingEmptyConfig", configFile.toString()));
|
||||
if (!configFile.createNewFile()) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()));
|
||||
return;
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()), ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try (final FileOutputStream fos = new FileOutputStream(configFile)) {
|
||||
try (final OutputStreamWriter writer = new OutputStreamWriter(fos, UTF8)) {
|
||||
writer.write(data);
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
} finally {
|
||||
//LOGGER.log(Level.INFO, configFile + " written to disk in " + (System.nanoTime() - startTime) + " nsec.");
|
||||
pendingDiskWrites.decrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Location;
|
||||
@@ -29,13 +30,11 @@ 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 static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
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;
|
||||
|
||||
@@ -109,7 +108,7 @@ public class EssentialsEntityListener implements Listener {
|
||||
@Override
|
||||
public void run() {
|
||||
attacker.getBase().chat("/" + command);
|
||||
LOGGER.log(Level.INFO, String.format("[PT] %s issued server command: /%s", attacker.getName(), command));
|
||||
ess.getLogger().log(Level.INFO, String.format("[PT] %s issued server command: /%s", attacker.getName(), command));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +197,7 @@ public class EssentialsEntityListener implements Listener {
|
||||
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 != null && !MaterialUtil.isAir(stack.getType())) {
|
||||
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
|
||||
if (vanish == ISettings.KeepInvPolicy.DELETE) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
@@ -217,10 +216,12 @@ public class EssentialsEntityListener implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now check armor
|
||||
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 != null && !MaterialUtil.isAir(stack.getType())) {
|
||||
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
|
||||
if (vanish == ISettings.KeepInvPolicy.DELETE) {
|
||||
armor[i] = null;
|
||||
@@ -244,6 +245,24 @@ public class EssentialsEntityListener implements Listener {
|
||||
}
|
||||
}
|
||||
event.getEntity().getInventory().setArmorContents(armor);
|
||||
|
||||
// Now check offhand
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01)) {
|
||||
final ItemStack stack = event.getEntity().getInventory().getItemInOffHand();
|
||||
//noinspection ConstantConditions
|
||||
if (stack != null && !MaterialUtil.isAir(stack.getType())) {
|
||||
final boolean isVanish = stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE);
|
||||
final boolean isBind = stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE);
|
||||
if (isVanish || isBind) {
|
||||
event.getEntity().getInventory().setItemInOffHand(null);
|
||||
if ((isVanish && vanish == ISettings.KeepInvPolicy.DROP) || (isBind && bind == ISettings.KeepInvPolicy.DROP)) {
|
||||
if (!event.getDrops().contains(stack)) {
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
import net.ess3.provider.LoggerProvider;
|
||||
import net.ess3.provider.providers.BaseLoggerProvider;
|
||||
import net.ess3.provider.providers.PaperLoggerProvider;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public final class EssentialsLogger {
|
||||
private final static Map<String, LoggerProvider> loggerProviders = new HashMap<>();
|
||||
private final static MethodHandle loggerFieldHandle;
|
||||
|
||||
static {
|
||||
try {
|
||||
final Field loggerField = ReflUtil.getFieldCached(JavaPlugin.class, "logger");
|
||||
//noinspection ConstantConditions
|
||||
loggerFieldHandle = MethodHandles.lookup().unreflectSetter(loggerField);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Failed to get logger field handle", t);
|
||||
}
|
||||
}
|
||||
|
||||
private EssentialsLogger() {
|
||||
}
|
||||
|
||||
public static LoggerProvider getLoggerProvider(final Plugin plugin) {
|
||||
if (loggerProviders.containsKey(plugin.getName())) {
|
||||
return loggerProviders.get(plugin.getName());
|
||||
}
|
||||
|
||||
final Logger parentLogger = Logger.getLogger(plugin.getName());
|
||||
final LoggerProvider provider;
|
||||
if (ReflUtil.getClassCached("io.papermc.paper.adventure.providers.ComponentLoggerProviderImpl") != null) {
|
||||
provider = new PaperLoggerProvider(plugin);
|
||||
provider.setParent(parentLogger);
|
||||
} else {
|
||||
provider = new BaseLoggerProvider(plugin, parentLogger);
|
||||
provider.setParent(parentLogger);
|
||||
}
|
||||
loggerProviders.put(plugin.getName(), provider);
|
||||
return provider;
|
||||
}
|
||||
|
||||
public static void updatePluginLogger(final Plugin plugin) {
|
||||
final LoggerProvider provider = getLoggerProvider(plugin);
|
||||
try {
|
||||
loggerFieldHandle.invoke(plugin, provider);
|
||||
} catch (Throwable e) {
|
||||
provider.log(Level.SEVERE, "Failed to update " + plugin.getName() + " logger", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static LoggerProvider getLoggerProvider(final String pluginName) {
|
||||
if (loggerProviders.containsKey(pluginName)) {
|
||||
return loggerProviders.get(pluginName);
|
||||
}
|
||||
|
||||
final Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName);
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin not found: " + pluginName);
|
||||
}
|
||||
return getLoggerProvider(plugin);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ import com.earth2me.essentials.utils.VersionUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import net.ess3.provider.CommandSendListenerProvider;
|
||||
import net.ess3.provider.providers.BukkitCommandSendListenerProvider;
|
||||
import net.ess3.provider.providers.PaperCommandSendListenerProvider;
|
||||
import net.essentialsx.api.v2.events.AsyncUserDataLoadEvent;
|
||||
import org.bukkit.BanEntry;
|
||||
import org.bukkit.BanList;
|
||||
@@ -37,7 +40,6 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.event.player.PlayerCommandSendEvent;
|
||||
import org.bukkit.event.player.PlayerEggThrowEvent;
|
||||
import org.bukkit.event.player.PlayerFishEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
@@ -68,14 +70,13 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private final transient IEssentials ess;
|
||||
private final ConcurrentHashMap<UUID, Integer> pendingMotdTasks = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -101,6 +102,15 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPaperCommandSendEvent() {
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent");
|
||||
return true;
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isArrowPickupEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerPickupArrowEvent");
|
||||
@@ -123,8 +133,10 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
ess.getServer().getPluginManager().registerEvents(new PickupListenerPre1_12(), ess);
|
||||
}
|
||||
|
||||
if (isCommandSendEvent()) {
|
||||
ess.getServer().getPluginManager().registerEvents(new CommandSendListener(), ess);
|
||||
if (isPaperCommandSendEvent()) {
|
||||
ess.getServer().getPluginManager().registerEvents(new PaperCommandSendListenerProvider(new CommandSendFilter()), ess);
|
||||
} else if (isCommandSendEvent()) {
|
||||
ess.getServer().getPluginManager().registerEvents(new BukkitCommandSendListenerProvider(new CommandSendFilter()), ess);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +164,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
user.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
|
||||
LOGGER.info(tl("mutedUserSpeaks", user.getName(), event.getMessage()));
|
||||
ess.getLogger().info(tl("mutedUserSpeaks", user.getName(), event.getMessage()));
|
||||
}
|
||||
try {
|
||||
final Iterator<Player> it = event.getRecipients().iterator();
|
||||
@@ -184,7 +196,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
event.getHandlers().unregister(this);
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Unregistering move listener");
|
||||
ess.getLogger().log(Level.INFO, "Unregistering move listener");
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -203,7 +215,11 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
to.setY(from.getY());
|
||||
to.setZ(from.getZ());
|
||||
try {
|
||||
event.setTo(LocationUtil.getSafeDestination(to));
|
||||
if (event.getPlayer().getAllowFlight()) {
|
||||
// Don't teleport to a safe location here, they are either a god or flying
|
||||
throw new Exception();
|
||||
}
|
||||
event.setTo(LocationUtil.getSafeDestination(ess, to));
|
||||
} catch (final Exception ex) {
|
||||
event.setTo(to);
|
||||
}
|
||||
@@ -244,6 +260,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
user.setGodModeEnabled(false);
|
||||
}
|
||||
if (user.isVanished()) {
|
||||
user.setLeavingHidden(true);
|
||||
user.setVanished(false);
|
||||
}
|
||||
user.setLogoutLocation();
|
||||
@@ -318,6 +335,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
user.setLastLogin(currentTime);
|
||||
user.setDisplayNick();
|
||||
updateCompass(user);
|
||||
user.setLeavingHidden(false);
|
||||
|
||||
// Check for new username. If they don't want the message, let's just say it's false.
|
||||
final boolean newUsername = ess.getSettings().isCustomNewUsernameMessage() && lastAccountName != null && !lastAccountName.equals(user.getBase().getName());
|
||||
@@ -398,7 +416,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
|
||||
if (user.isAuthorized("essentials.fly.safelogin")) {
|
||||
user.getBase().setFallDistance(0);
|
||||
if (LocationUtil.shouldFly(user.getLocation())) {
|
||||
if (LocationUtil.shouldFly(ess, user.getLocation())) {
|
||||
user.getBase().setAllowFlight(true);
|
||||
user.getBase().setFlying(true);
|
||||
if (ess.getSettings().isSendFlyEnableOnJoin()) {
|
||||
@@ -446,9 +464,9 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
tempInput = new TextInput(user.getSource(), "motd", true, ess);
|
||||
} catch (final IOException ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.WARNING, ex.getMessage(), ex);
|
||||
ess.getLogger().log(Level.WARNING, ex.getMessage(), ex);
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, ex.getMessage());
|
||||
ess.getLogger().log(Level.WARNING, ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -521,21 +539,16 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onPlayerTeleport(final PlayerTeleportEvent event) {
|
||||
final boolean backListener = ess.getSettings().registerBackInListener();
|
||||
final boolean teleportInvulnerability = ess.getSettings().isTeleportInvulnerability();
|
||||
if (backListener || teleportInvulnerability) {
|
||||
final Player player = event.getPlayer();
|
||||
if (player.hasMetadata("NPC")) {
|
||||
return;
|
||||
}
|
||||
final User user = ess.getUser(player);
|
||||
//There is TeleportCause.COMMMAND but plugins have to actively pass the cause in on their teleports.
|
||||
if (user.isAuthorized("essentials.back.onteleport") && backListener && (event.getCause() == TeleportCause.PLUGIN || event.getCause() == TeleportCause.COMMAND)) {
|
||||
user.setLastLocation();
|
||||
}
|
||||
if (teleportInvulnerability && (event.getCause() == TeleportCause.PLUGIN || event.getCause() == TeleportCause.COMMAND)) {
|
||||
user.enableInvulnerabilityAfterTeleport();
|
||||
}
|
||||
final Player player = event.getPlayer();
|
||||
if (player.hasMetadata("NPC") || !(event.getCause() == TeleportCause.PLUGIN || event.getCause() == TeleportCause.COMMAND)) {
|
||||
return;
|
||||
}
|
||||
final User user = ess.getUser(player);
|
||||
if (ess.getSettings().registerBackInListener() && user.isAuthorized("essentials.back.onteleport")) {
|
||||
user.setLastLocation();
|
||||
}
|
||||
if (ess.getSettings().isTeleportInvulnerability()) {
|
||||
user.enableInvulnerabilityAfterTeleport();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,7 +626,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
} else {
|
||||
player.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
LOGGER.info(tl("mutedUserSpeaks", player.getName(), event.getMessage()));
|
||||
ess.getLogger().info(tl("mutedUserSpeaks", player.getName(), event.getMessage()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -738,6 +751,9 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
switch (event.getAction()) {
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
if (!event.isCancelled() && MaterialUtil.isBed(event.getClickedBlock().getType()) && ess.getSettings().getUpdateBedAtDaytime()) {
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_13_2_R01) && ((org.bukkit.block.data.type.Bed) event.getClickedBlock().getBlockData()).isOccupied()) {
|
||||
break;
|
||||
}
|
||||
final User player = ess.getUser(event.getPlayer());
|
||||
if (player.isAuthorized("essentials.sethome.bed") && player.getWorld().getEnvironment().equals(World.Environment.NORMAL)) {
|
||||
player.getBase().setBedSpawnLocation(event.getClickedBlock().getLocation());
|
||||
@@ -798,7 +814,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
ess.scheduleSyncDelayedTask(new DelayedClickJumpTask());
|
||||
} catch (final Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.WARNING, ex.getMessage(), ex);
|
||||
ess.getLogger().log(Level.WARNING, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -822,7 +838,7 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
@Override
|
||||
public void run() {
|
||||
user.getBase().chat("/" + command);
|
||||
LOGGER.log(Level.INFO, String.format("[PT] %s issued server command: /%s", user.getName(), command));
|
||||
ess.getLogger().log(Level.INFO, String.format("[PT] %s issued server command: /%s", user.getName(), command));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,15 +988,14 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
}
|
||||
}
|
||||
|
||||
private final class CommandSendListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onCommandSend(final PlayerCommandSendEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
|
||||
private final class CommandSendFilter implements CommandSendListenerProvider.Filter {
|
||||
@Override
|
||||
public Predicate<String> apply(Player player) {
|
||||
final User user = ess.getUser(player);
|
||||
final Set<PluginCommand> checked = new HashSet<>();
|
||||
final Set<PluginCommand> toRemove = new HashSet<>();
|
||||
|
||||
event.getCommands().removeIf(label -> {
|
||||
return label -> {
|
||||
if (isEssentialsCommand(label)) {
|
||||
final PluginCommand command = ess.getServer().getPluginCommand(label);
|
||||
if (!checked.contains(command)) {
|
||||
@@ -992,25 +1007,21 @@ public class EssentialsPlayerListener implements Listener, FakeAccessor {
|
||||
return toRemove.contains(command);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Removed commands: " + toRemove.toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all of the following are true:
|
||||
* - The command is a plugin command
|
||||
* - The plugin command is from a plugin in an essentials-controlled package
|
||||
* - The plugin command is from an official EssentialsX plugin or addon
|
||||
* - There is no known alternative OR the alternative is overridden by Essentials
|
||||
*/
|
||||
private boolean isEssentialsCommand(final String label) {
|
||||
final PluginCommand command = ess.getServer().getPluginCommand(label);
|
||||
|
||||
return command != null
|
||||
&& (command.getPlugin() == ess || command.getPlugin().getClass().getName().startsWith("com.earth2me.essentials"))
|
||||
&& (ess.getSettings().isCommandOverridden(label) || (ess.getAlternativeCommandsHandler().getAlternative(label) == null));
|
||||
&& (command.getPlugin() == ess || command.getPlugin().getClass().getName().startsWith("com.earth2me.essentials") || command.getPlugin().getClass().getName().startsWith("net.essentialsx"))
|
||||
&& (ess.getSettings().isCommandOverridden(label) || (ess.getAlternativeCommandsHandler().getAlternative(label) == null));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,14 +47,12 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class EssentialsUpgrade {
|
||||
private final static Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private static final FileFilter YML_FILTER = pathname -> pathname.isFile() && pathname.getName().endsWith(".yml");
|
||||
private static final String PATTERN_CONFIG_UUID_REGEX = "(?mi)^uuid:\\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\s*$";
|
||||
private static final Pattern PATTERN_CONFIG_UUID = Pattern.compile(PATTERN_CONFIG_UUID_REGEX);
|
||||
@@ -186,13 +184,13 @@ public class EssentialsUpgrade {
|
||||
config.blockingSave();
|
||||
}
|
||||
} catch (RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file);
|
||||
ess.getLogger().log(Level.INFO, "File: " + file);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateUsersMailList", true);
|
||||
doneFile.save();
|
||||
LOGGER.info("Done converting mail list.");
|
||||
ess.getLogger().info("Done converting mail list.");
|
||||
}
|
||||
|
||||
public void convertStupidCamelCaseUserdataKeys() {
|
||||
@@ -200,7 +198,7 @@ public class EssentialsUpgrade {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("Attempting to migrate legacy userdata keys to Configurate");
|
||||
ess.getLogger().info("Attempting to migrate legacy userdata keys to Configurate");
|
||||
|
||||
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdataFolder.exists() || !userdataFolder.isDirectory()) {
|
||||
@@ -241,13 +239,13 @@ public class EssentialsUpgrade {
|
||||
}
|
||||
config.blockingSave();
|
||||
} catch (final RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file);
|
||||
ess.getLogger().log(Level.INFO, "File: " + file);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateUsersStupidLegacyPathNames", true);
|
||||
doneFile.save();
|
||||
LOGGER.info("Done converting legacy userdata keys to Configurate.");
|
||||
ess.getLogger().info("Done converting legacy userdata keys to Configurate.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,31 +288,31 @@ public class EssentialsUpgrade {
|
||||
}
|
||||
final File backupFolder = new File(ess.getDataFolder(), "userdata-npc-backup");
|
||||
if (backupFolder.exists()) {
|
||||
LOGGER.info("NPC backup folder already exists; skipping NPC purge.");
|
||||
LOGGER.info("To finish purging broken NPC accounts, rename the \"plugins/Essentials/userdata-npc-backup\" folder and restart your server.");
|
||||
ess.getLogger().info("NPC backup folder already exists; skipping NPC purge.");
|
||||
ess.getLogger().info("To finish purging broken NPC accounts, rename the \"plugins/Essentials/userdata-npc-backup\" folder and restart your server.");
|
||||
return;
|
||||
} else if (!backupFolder.mkdir()) {
|
||||
LOGGER.info("Skipping NPC purge due to error creating backup folder.");
|
||||
ess.getLogger().info("Skipping NPC purge due to error creating backup folder.");
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("#===========================================================================#");
|
||||
LOGGER.info(" EssentialsX will now purge any NPC accounts which were incorrectly created.");
|
||||
LOGGER.info(" Only NPC accounts with the default starting balance will be deleted. If");
|
||||
LOGGER.info(" they turn out to be valid NPC accounts, they will be re-created as needed.");
|
||||
LOGGER.info(" Any files deleted here will be backed up to the ");
|
||||
LOGGER.info(" \"plugins/Essentials/userdata-npc-backup\" folder. If you notice any files");
|
||||
LOGGER.info(" have been purged incorrectly, you should restore it from the backup and");
|
||||
LOGGER.info(" report it to us on GitHub:");
|
||||
LOGGER.info(" https://github.com/EssentialsX/Essentials/issues/new/choose");
|
||||
LOGGER.info("");
|
||||
LOGGER.info(" NOTE: This is a one-time process and will take several minutes if you have");
|
||||
LOGGER.info(" a lot of userdata files! If you interrupt this process, EssentialsX will");
|
||||
LOGGER.info(" skip the process until you rename or remove the backup folder.");
|
||||
LOGGER.info("#===========================================================================#");
|
||||
ess.getLogger().info("#===========================================================================#");
|
||||
ess.getLogger().info(" EssentialsX will now purge any NPC accounts which were incorrectly created.");
|
||||
ess.getLogger().info(" Only NPC accounts with the default starting balance will be deleted. If");
|
||||
ess.getLogger().info(" they turn out to be valid NPC accounts, they will be re-created as needed.");
|
||||
ess.getLogger().info(" Any files deleted here will be backed up to the ");
|
||||
ess.getLogger().info(" \"plugins/Essentials/userdata-npc-backup\" folder. If you notice any files");
|
||||
ess.getLogger().info(" have been purged incorrectly, you should restore it from the backup and");
|
||||
ess.getLogger().info(" report it to us on GitHub:");
|
||||
ess.getLogger().info(" https://github.com/EssentialsX/Essentials/issues/new/choose");
|
||||
ess.getLogger().info("");
|
||||
ess.getLogger().info(" NOTE: This is a one-time process and will take several minutes if you have");
|
||||
ess.getLogger().info(" a lot of userdata files! If you interrupt this process, EssentialsX will");
|
||||
ess.getLogger().info(" skip the process until you rename or remove the backup folder.");
|
||||
ess.getLogger().info("#===========================================================================#");
|
||||
|
||||
final int totalUserFiles = userFiles.length;
|
||||
LOGGER.info("Found ~" + totalUserFiles + " files under \"plugins/Essentials/userdata\"...");
|
||||
ess.getLogger().info("Found ~" + totalUserFiles + " files under \"plugins/Essentials/userdata\"...");
|
||||
|
||||
final AtomicInteger movedAccounts = new AtomicInteger(0);
|
||||
final AtomicInteger totalAccounts = new AtomicInteger(0);
|
||||
@@ -324,7 +322,7 @@ public class EssentialsUpgrade {
|
||||
|
||||
final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
||||
final ScheduledFuture<?> feedbackTask = executor.scheduleWithFixedDelay(
|
||||
() -> LOGGER.info("Scanned " + totalAccounts.get() + "/" + totalUserFiles + " accounts; moved " + movedAccounts.get() + " accounts"),
|
||||
() -> ess.getLogger().info("Scanned " + totalAccounts.get() + "/" + totalUserFiles + " accounts; moved " + movedAccounts.get() + " accounts"),
|
||||
5, feedbackInterval, TimeUnit.SECONDS);
|
||||
|
||||
for (final File file : userFiles) {
|
||||
@@ -358,10 +356,10 @@ public class EssentialsUpgrade {
|
||||
Files.move(file, new File(backupFolder, file.getName()));
|
||||
movedAccounts.incrementAndGet();
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, "Error while moving NPC file", e);
|
||||
ess.getLogger().log(Level.SEVERE, "Error while moving NPC file", e);
|
||||
}
|
||||
} catch (final RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file);
|
||||
ess.getLogger().log(Level.INFO, "File: " + file);
|
||||
feedbackTask.cancel(false);
|
||||
executor.shutdown();
|
||||
throw ex;
|
||||
@@ -372,18 +370,18 @@ public class EssentialsUpgrade {
|
||||
doneFile.setProperty("updatePurgeBrokenNpcAccounts", true);
|
||||
doneFile.save();
|
||||
|
||||
LOGGER.info("#===========================================================================#");
|
||||
LOGGER.info(" EssentialsX has finished purging NPC accounts.");
|
||||
LOGGER.info("");
|
||||
LOGGER.info(" Deleted accounts: " + movedAccounts);
|
||||
LOGGER.info(" Total accounts processed: " + totalAccounts);
|
||||
LOGGER.info("");
|
||||
LOGGER.info(" Purged accounts have been backed up to");
|
||||
LOGGER.info(" \"plugins/Essentials/userdata-npc-backup\", and can be restored from there");
|
||||
LOGGER.info(" if needed. Please report any files which have been incorrectly deleted");
|
||||
LOGGER.info(" to us on GitHub:");
|
||||
LOGGER.info(" https://github.com/EssentialsX/Essentials/issues/new/choose");
|
||||
LOGGER.info("#===========================================================================#");
|
||||
ess.getLogger().info("#===========================================================================#");
|
||||
ess.getLogger().info(" EssentialsX has finished purging NPC accounts.");
|
||||
ess.getLogger().info("");
|
||||
ess.getLogger().info(" Deleted accounts: " + movedAccounts);
|
||||
ess.getLogger().info(" Total accounts processed: " + totalAccounts);
|
||||
ess.getLogger().info("");
|
||||
ess.getLogger().info(" Purged accounts have been backed up to");
|
||||
ess.getLogger().info(" \"plugins/Essentials/userdata-npc-backup\", and can be restored from there");
|
||||
ess.getLogger().info(" if needed. Please report any files which have been incorrectly deleted");
|
||||
ess.getLogger().info(" to us on GitHub:");
|
||||
ess.getLogger().info(" https://github.com/EssentialsX/Essentials/issues/new/choose");
|
||||
ess.getLogger().info("#===========================================================================#");
|
||||
}
|
||||
|
||||
public void convertIgnoreList() {
|
||||
@@ -392,7 +390,7 @@ public class EssentialsUpgrade {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("Attempting to migrate ignore list to UUIDs");
|
||||
ess.getLogger().info("Attempting to migrate ignore list to UUIDs");
|
||||
|
||||
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdataFolder.exists() || !userdataFolder.isDirectory()) {
|
||||
@@ -414,7 +412,7 @@ public class EssentialsUpgrade {
|
||||
continue;
|
||||
}
|
||||
if (pattern.matcher(name.trim()).matches()) {
|
||||
LOGGER.info("Detected already migrated ignore list!");
|
||||
ess.getLogger().info("Detected already migrated ignore list!");
|
||||
return;
|
||||
}
|
||||
final User user = ess.getOfflineUser(name);
|
||||
@@ -427,41 +425,41 @@ public class EssentialsUpgrade {
|
||||
config.blockingSave();
|
||||
}
|
||||
} catch (final RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file);
|
||||
ess.getLogger().log(Level.INFO, "File: " + file);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateUsersIgnoreListUUID", true);
|
||||
doneFile.save();
|
||||
LOGGER.info("Done converting ignore list.");
|
||||
ess.getLogger().info("Done converting ignore list.");
|
||||
}
|
||||
|
||||
public void convertKits() {
|
||||
final Kits kits = ess.getKits();
|
||||
final EssentialsConfiguration config = kits.getConfig();
|
||||
final EssentialsConfiguration config = kits.getRootConfig();
|
||||
if (doneFile.getBoolean("kitsyml", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("Attempting to convert old kits in config.yml to new kits.yml");
|
||||
ess.getLogger().info("Attempting to convert old kits in config.yml to new kits.yml");
|
||||
|
||||
final CommentedConfigurationNode section = ess.getSettings().getKitSection();
|
||||
if (section == null) {
|
||||
LOGGER.info("No kits found to migrate.");
|
||||
ess.getLogger().info("No kits found to migrate.");
|
||||
return;
|
||||
}
|
||||
|
||||
final Map<String, Object> legacyKits = ConfigurateUtil.getRawMap(section);
|
||||
|
||||
for (final Map.Entry<String, Object> entry : legacyKits.entrySet()) {
|
||||
LOGGER.info("Converting " + entry.getKey());
|
||||
ess.getLogger().info("Converting " + entry.getKey());
|
||||
config.setRaw("kits." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
config.save();
|
||||
doneFile.setProperty("kitsyml", true);
|
||||
doneFile.save();
|
||||
LOGGER.info("Done converting kits.");
|
||||
ess.getLogger().info("Done converting kits.");
|
||||
}
|
||||
|
||||
private void moveMotdRulesToFile(final String name) {
|
||||
@@ -494,7 +492,7 @@ public class EssentialsUpgrade {
|
||||
doneFile.setProperty("move" + name + "ToFile", true);
|
||||
doneFile.save();
|
||||
} catch (final IOException e) {
|
||||
LOGGER.log(Level.SEVERE, tl("upgradingFilesError"), e);
|
||||
ess.getLogger().log(Level.SEVERE, tl("upgradingFilesError"), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +570,7 @@ public class EssentialsUpgrade {
|
||||
config.blockingSave();
|
||||
}
|
||||
} catch (final RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file);
|
||||
ess.getLogger().log(Level.INFO, "File: " + file);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@@ -628,7 +626,7 @@ public class EssentialsUpgrade {
|
||||
}
|
||||
|
||||
} catch (final RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file);
|
||||
ess.getLogger().log(Level.INFO, "File: " + file);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@@ -657,15 +655,15 @@ public class EssentialsUpgrade {
|
||||
final File tmpFile = new File(listOfFile.getParentFile(), sanitizedFilename + ".tmp");
|
||||
final File newFile = new File(listOfFile.getParentFile(), sanitizedFilename);
|
||||
if (!listOfFile.renameTo(tmpFile)) {
|
||||
LOGGER.log(Level.WARNING, tl("userdataMoveError", filename, sanitizedFilename));
|
||||
ess.getLogger().log(Level.WARNING, tl("userdataMoveError", filename, sanitizedFilename));
|
||||
continue;
|
||||
}
|
||||
if (newFile.exists()) {
|
||||
LOGGER.log(Level.WARNING, tl("duplicatedUserdata", filename, sanitizedFilename));
|
||||
ess.getLogger().log(Level.WARNING, tl("duplicatedUserdata", filename, sanitizedFilename));
|
||||
continue;
|
||||
}
|
||||
if (!tmpFile.renameTo(newFile)) {
|
||||
LOGGER.log(Level.WARNING, tl("userdataMoveBackError", sanitizedFilename, sanitizedFilename));
|
||||
ess.getLogger().log(Level.WARNING, tl("userdataMoveBackError", sanitizedFilename, sanitizedFilename));
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("sanitizeAllUserFilenames", true);
|
||||
@@ -722,7 +720,7 @@ public class EssentialsUpgrade {
|
||||
doneFile.setProperty("deleteOldItemsCsv", true);
|
||||
doneFile.save();
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
ess.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -748,7 +746,7 @@ public class EssentialsUpgrade {
|
||||
config.blockingSave();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
ess.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateSpawnsToNewSpawnsConfig", true);
|
||||
@@ -776,7 +774,7 @@ public class EssentialsUpgrade {
|
||||
config.blockingSave();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
ess.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateJailsToNewJailsConfig", true);
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
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 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;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ 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 {
|
||||
@@ -89,7 +88,7 @@ public class I18n implements net.ess3.api.II18n {
|
||||
}
|
||||
} catch (final MissingResourceException ex) {
|
||||
if (ess == null || ess.getSettings().isDebug()) {
|
||||
Logger.getLogger("Essentials").log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), localeBundle.getLocale().toString()), ex);
|
||||
ess.getLogger().log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), localeBundle.getLocale().toString()), ex);
|
||||
}
|
||||
return defaultBundle.getString(string);
|
||||
}
|
||||
@@ -126,7 +125,7 @@ public class I18n implements net.ess3.api.II18n {
|
||||
}
|
||||
ResourceBundle.clearCache();
|
||||
messageFormatCache = new HashMap<>();
|
||||
Logger.getLogger("Essentials").log(Level.INFO, String.format("Using locale %s", currentLocale.toString()));
|
||||
ess.getLogger().log(Level.INFO, String.format("Using locale %s", currentLocale.toString()));
|
||||
|
||||
try {
|
||||
localeBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new UTF8PropertiesControl());
|
||||
|
||||
@@ -10,14 +10,17 @@ import com.earth2me.essentials.updatecheck.UpdateChecker;
|
||||
import net.ess3.nms.refl.providers.ReflOnlineModeProvider;
|
||||
import net.ess3.provider.ContainerProvider;
|
||||
import net.ess3.provider.FormattedCommandAliasProvider;
|
||||
import net.ess3.provider.ItemUnbreakableProvider;
|
||||
import net.ess3.provider.KnownCommandsProvider;
|
||||
import net.ess3.provider.MaterialTagProvider;
|
||||
import net.ess3.provider.PersistentDataProvider;
|
||||
import net.ess3.provider.ServerStateProvider;
|
||||
import net.ess3.provider.SerializationProvider;
|
||||
import net.ess3.provider.ServerStateProvider;
|
||||
import net.ess3.provider.SignDataProvider;
|
||||
import net.ess3.provider.SpawnerBlockProvider;
|
||||
import net.ess3.provider.SpawnerItemProvider;
|
||||
import net.ess3.provider.SyncCommandsProvider;
|
||||
import net.ess3.provider.WorldInfoProvider;
|
||||
import net.essentialsx.api.v2.services.BalanceTop;
|
||||
import net.essentialsx.api.v2.services.mail.MailService;
|
||||
import org.bukkit.Server;
|
||||
@@ -159,5 +162,11 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
ReflOnlineModeProvider getOnlineModeProvider();
|
||||
|
||||
ItemUnbreakableProvider getItemUnbreakableProvider();
|
||||
|
||||
WorldInfoProvider getWorldInfoProvider();
|
||||
|
||||
SignDataProvider getSignDataProvider();
|
||||
|
||||
PluginCommand getPluginCommand(String cmd);
|
||||
}
|
||||
@@ -46,6 +46,12 @@ public interface ISettings extends IConf {
|
||||
|
||||
char getChatQuestion();
|
||||
|
||||
boolean isShoutDefault();
|
||||
|
||||
boolean isPersistShout();
|
||||
|
||||
boolean isChatQuestionEnabled();
|
||||
|
||||
BigDecimal getCommandCost(IEssentialsCommand cmd);
|
||||
|
||||
BigDecimal getCommandCost(String label);
|
||||
@@ -228,6 +234,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isWorldHomePermissions();
|
||||
|
||||
int getMaxTreeCommandRange();
|
||||
|
||||
boolean registerBackInListener();
|
||||
|
||||
boolean getDisableItemPickupWhileAfk();
|
||||
@@ -238,6 +246,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
long getTpaAcceptCancellation();
|
||||
|
||||
int getTpaMaxRequests();
|
||||
|
||||
long getTeleportInvulnerability();
|
||||
|
||||
boolean isTeleportInvulnerability();
|
||||
|
||||
@@ -12,13 +12,16 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -61,8 +64,11 @@ public interface IUser {
|
||||
/**
|
||||
* Returns whether this user has an outstanding teleport request to deal with.
|
||||
*
|
||||
* @deprecated The teleport request system has been moved into a multi-user teleport request queue.
|
||||
* @see IUser#hasPendingTpaRequests(boolean, boolean)
|
||||
* @return whether there is a teleport request
|
||||
*/
|
||||
@Deprecated
|
||||
boolean hasOutstandingTeleportRequest();
|
||||
|
||||
/**
|
||||
@@ -88,6 +94,15 @@ public interface IUser {
|
||||
*/
|
||||
boolean isHidden();
|
||||
|
||||
/**
|
||||
* Whether the user was hidden before leaving the server.
|
||||
*
|
||||
* @return true if the user was hidden.
|
||||
*/
|
||||
boolean isLeavingHidden();
|
||||
|
||||
void setLeavingHidden(boolean leavingHidden);
|
||||
|
||||
void setHidden(boolean vanish);
|
||||
|
||||
boolean isGodModeEnabled();
|
||||
@@ -98,6 +113,11 @@ public interface IUser {
|
||||
|
||||
boolean canBuild();
|
||||
|
||||
/**
|
||||
* @deprecated The teleport request system has been moved into a multi-user teleport request queue.
|
||||
* @see IUser#getNextTpaRequest(boolean, boolean, boolean)
|
||||
*/
|
||||
@Deprecated
|
||||
long getTeleportRequestTime();
|
||||
|
||||
void enableInvulnerabilityAfterTeleport();
|
||||
@@ -205,6 +225,8 @@ public interface IUser {
|
||||
|
||||
String getName();
|
||||
|
||||
UUID getUUID();
|
||||
|
||||
String getDisplayName();
|
||||
|
||||
String getFormattedNickname();
|
||||
@@ -238,4 +260,74 @@ public interface IUser {
|
||||
void setToggleShout(boolean toggleShout);
|
||||
|
||||
boolean isToggleShout();
|
||||
|
||||
/**
|
||||
* Gets information about the most-recently-made, non-expired TPA request in the tpa queue of this {@link IUser}.
|
||||
* <p>
|
||||
* The TPA Queue is Last-In-First-Out queue which stores all the active pending teleport
|
||||
* requests of this {@link IUser}. Timeout calculations are also done during the
|
||||
* iteration process of this method, ensuring that teleport requests made past the timeout
|
||||
* period are removed from queue and therefore not returned here. The maximum size of this
|
||||
* queue is determined by {@link ISettings#getTpaMaxRequests()}.
|
||||
*
|
||||
* @param inform true if the underlying {@link IUser} should be informed if a request expires during iteration.
|
||||
* @param ignoreExpirations true if this method should not process expirations for the entire queue and stop execution on the first unexpired request.
|
||||
* @param excludeHere true if /tphere requests should be ignored in fetching the next tpa request.
|
||||
* @return A {@link TpaRequest} corresponding to the next available request or null if no valid request is present.
|
||||
*/
|
||||
@Nullable TpaRequest getNextTpaRequest(boolean inform, boolean ignoreExpirations, boolean excludeHere);
|
||||
|
||||
/**
|
||||
* Whether or not this {@link IUser} has any valid TPA requests in queue.
|
||||
*
|
||||
* @param inform true if the user should be informed if a request expires during iteration.
|
||||
* @param excludeHere true if /tpahere requests should be ignored in checking if a tpa request is available.
|
||||
* @return true if the user has an available pending request in queue.
|
||||
*/
|
||||
boolean hasPendingTpaRequests(boolean inform, boolean excludeHere);
|
||||
|
||||
class TpaRequest {
|
||||
private final String name;
|
||||
private final UUID requesterUuid;
|
||||
private boolean here;
|
||||
private Location location;
|
||||
private long time;
|
||||
|
||||
public TpaRequest(String name, UUID requesterUuid) {
|
||||
this.name = name;
|
||||
this.requesterUuid = requesterUuid;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public UUID getRequesterUuid() {
|
||||
return requesterUuid;
|
||||
}
|
||||
|
||||
public boolean isHere() {
|
||||
return here;
|
||||
}
|
||||
|
||||
public void setHere(boolean here) {
|
||||
this.here = here;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,12 +34,10 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Jails implements net.ess3.api.IJails {
|
||||
private static final transient Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private static transient boolean enabled = false;
|
||||
private final IEssentials ess;
|
||||
private final EssentialsConfiguration config;
|
||||
@@ -76,7 +74,7 @@ public class Jails implements net.ess3.api.IJails {
|
||||
final JailListener blockListener = new JailListener();
|
||||
pluginManager.registerEvents(blockListener, ess);
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Registering Jail listener");
|
||||
ess.getLogger().log(Level.INFO, "Registering Jail listener");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +266,9 @@ public class Jails implements net.ess3.api.IJails {
|
||||
event.setRespawnLocation(getJail(user.getJail()));
|
||||
} catch (final Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
ess.getLogger().log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
ess.getLogger().log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,9 +284,9 @@ public class Jails implements net.ess3.api.IJails {
|
||||
event.setTo(getJail(user.getJail()));
|
||||
} catch (final Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
ess.getLogger().log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
ess.getLogger().log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
}
|
||||
}
|
||||
user.sendMessage(tl("jailMessage"));
|
||||
@@ -306,9 +304,9 @@ public class Jails implements net.ess3.api.IJails {
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
future.exceptionally(ex -> {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
ess.getLogger().log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
ess.getLogger().log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -4,84 +4,106 @@ import com.earth2me.essentials.config.ConfigurateUtil;
|
||||
import com.earth2me.essentials.config.EssentialsConfiguration;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import org.spongepowered.configurate.CommentedConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
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.capitalCase;
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Kits implements IConf {
|
||||
private final EssentialsConfiguration config;
|
||||
private CommentedConfigurationNode kits;
|
||||
private final IEssentials ess;
|
||||
private final EssentialsConfiguration rootConfig;
|
||||
private final Map<String, EssentialsConfiguration> kitToConfigMap = new HashMap<>();
|
||||
private final Map<String, Map<String, Object>> kitMap = new HashMap<>();
|
||||
|
||||
public Kits(final IEssentials essentials) {
|
||||
config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "kits.yml"), "/kits.yml");
|
||||
this.ess = essentials;
|
||||
this.rootConfig = new EssentialsConfiguration(new File(essentials.getDataFolder(), "kits.yml"), "/kits.yml");
|
||||
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
config.load();
|
||||
kits = _getKits();
|
||||
rootConfig.load();
|
||||
parseKits();
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return config.getFile();
|
||||
return rootConfig.getFile();
|
||||
}
|
||||
|
||||
private CommentedConfigurationNode _getKits() {
|
||||
final CommentedConfigurationNode section = config.getSection("kits");
|
||||
if (section != null) {
|
||||
final CommentedConfigurationNode newSection = config.newSection();
|
||||
for (final String kitItem : ConfigurateUtil.getKeys(section)) {
|
||||
final CommentedConfigurationNode kitSection = section.node(kitItem);
|
||||
if (kitSection.isMap()) {
|
||||
try {
|
||||
newSection.node(kitItem.toLowerCase(Locale.ENGLISH)).set(kitSection);
|
||||
} catch (SerializationException e) {
|
||||
e.printStackTrace();
|
||||
private void parseKit(final String kitName, final CommentedConfigurationNode kitSection, final EssentialsConfiguration parentConfig) {
|
||||
if (kitSection.isMap()) {
|
||||
final String effectiveKitName = kitName.toLowerCase(Locale.ENGLISH);
|
||||
kitToConfigMap.put(effectiveKitName, parentConfig);
|
||||
kitMap.put(effectiveKitName, ConfigurateUtil.getRawMap(kitSection));
|
||||
}
|
||||
}
|
||||
|
||||
private void parseKits() {
|
||||
kitToConfigMap.clear();
|
||||
kitMap.clear();
|
||||
|
||||
// Kits from kits.yml file
|
||||
final CommentedConfigurationNode fileKits = rootConfig.getSection("kits");
|
||||
if (fileKits != null) {
|
||||
for (final Map.Entry<String, CommentedConfigurationNode> kitEntry : ConfigurateUtil.getMap(fileKits).entrySet()) {
|
||||
parseKit(kitEntry.getKey(), kitEntry.getValue(), rootConfig);
|
||||
}
|
||||
}
|
||||
|
||||
// Kits from kits subdirectory
|
||||
final File kitsFolder = new File(this.ess.getDataFolder(), "kits");
|
||||
if (!kitsFolder.exists() || !kitsFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final File[] kitsFiles = kitsFolder.listFiles();
|
||||
|
||||
//noinspection ConstantConditions - will not be null, conditions checked above.
|
||||
for (final File kitFile : kitsFiles) {
|
||||
if (kitFile.getName().endsWith(".yml")) {
|
||||
final EssentialsConfiguration kitConfig = new EssentialsConfiguration(kitFile);
|
||||
kitConfig.load();
|
||||
final CommentedConfigurationNode kits = kitConfig.getSection("kits");
|
||||
if (kits != null) {
|
||||
for (final Map.Entry<String, CommentedConfigurationNode> kitEntry : ConfigurateUtil.getMap(kits).entrySet()) {
|
||||
parseKit(kitEntry.getKey(), kitEntry.getValue(), kitConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newSection;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public EssentialsConfiguration getConfig() {
|
||||
return config;
|
||||
/**
|
||||
* Should be used for EssentialsUpgrade conversions <b>only</b>.
|
||||
*/
|
||||
public EssentialsConfiguration getRootConfig() {
|
||||
return rootConfig;
|
||||
}
|
||||
|
||||
public CommentedConfigurationNode getKits() {
|
||||
return kits;
|
||||
public Set<String> getKitKeys() {
|
||||
return kitMap.keySet();
|
||||
}
|
||||
|
||||
public Map<String, Object> getKit(String name) {
|
||||
name = name.replace('.', '_').replace('/', '_');
|
||||
if (getKits() != null) {
|
||||
final CommentedConfigurationNode kits = getKits();
|
||||
// Other parts of the codebase/3rd party plugins expect us to lowercase kit names here.
|
||||
// This isn't strictly needed for the future of Essentials, but for compatibility it's here.
|
||||
final CommentedConfigurationNode kitSection = kits.node(name.toLowerCase());
|
||||
if (!kitSection.virtual() && kitSection.isMap()) {
|
||||
return ConfigurateUtil.getRawMap(kitSection);
|
||||
}
|
||||
public Map<String, Object> getKit(final String name) {
|
||||
if (name != null) {
|
||||
return kitMap.get(name.replace('.', '_').replace('/', '_'));
|
||||
}
|
||||
|
||||
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) {
|
||||
final CommentedConfigurationNode section = config.getSection("kits");
|
||||
if (section != null) {
|
||||
for (final String kitName : ConfigurateUtil.getKeys(section)) {
|
||||
if (name != null) {
|
||||
for (final String kitName : kitMap.keySet()) {
|
||||
if (kitName.equalsIgnoreCase(name)) {
|
||||
return kitName;
|
||||
}
|
||||
@@ -90,25 +112,32 @@ public class Kits implements IConf {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addKit(final String name, final List<String> lines, final long delay) {
|
||||
public void addKit(String name, final List<String> lines, final long delay) {
|
||||
name = name.replace('.', '_').replace('/', '_').toLowerCase(Locale.ENGLISH);
|
||||
// Will overwrite but w/e
|
||||
config.setProperty("kits." + name + ".delay", delay);
|
||||
config.setProperty("kits." + name + ".items", lines);
|
||||
kits = _getKits();
|
||||
config.save();
|
||||
rootConfig.setProperty("kits." + name + ".delay", delay);
|
||||
rootConfig.setProperty("kits." + name + ".items", lines);
|
||||
parseKits();
|
||||
rootConfig.save();
|
||||
}
|
||||
|
||||
public void removeKit(final String name) {
|
||||
public void removeKit(String name) {
|
||||
name = name.replace('.', '_').replace('/', '_').toLowerCase(Locale.ENGLISH);
|
||||
if (!kitToConfigMap.containsKey(name) || !kitMap.containsKey(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final EssentialsConfiguration config = kitToConfigMap.get(name);
|
||||
config.removeProperty("kits." + name);
|
||||
kits = _getKits();
|
||||
config.save();
|
||||
|
||||
config.blockingSave();
|
||||
parseKits();
|
||||
}
|
||||
|
||||
public String listKits(final net.ess3.api.IEssentials ess, final User user) throws Exception {
|
||||
try {
|
||||
final CommentedConfigurationNode kits = config.getSection("kits");
|
||||
final StringBuilder list = new StringBuilder();
|
||||
for (final String kitItem : ConfigurateUtil.getKeys(kits)) {
|
||||
for (final String kitItem : kitMap.keySet()) {
|
||||
if (user == null) {
|
||||
list.append(" ").append(capitalCase(kitItem));
|
||||
} else if (user.isAuthorized("essentials.kits." + kitItem.toLowerCase(Locale.ENGLISH))) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
@@ -38,7 +37,7 @@ public class ManagedFile {
|
||||
throw new IOException("Could not delete file " + file.toString());
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +45,7 @@ public class ManagedFile {
|
||||
try {
|
||||
copyResourceAscii("/" + filename, file);
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, tl("itemsCsvNotLoaded", filename), ex);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, tl("itemsCsvNotLoaded", filename), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +112,7 @@ public class ManagedFile {
|
||||
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.");
|
||||
Essentials.getWrappedLogger().warning("File " + file.toString() + " has been modified by user and file version differs, please update the file manually.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +146,7 @@ public class ManagedFile {
|
||||
return lines;
|
||||
}
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.base.Joiner;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.FireworkEffect;
|
||||
@@ -33,7 +33,6 @@ import org.bukkit.potion.Potion;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -48,9 +47,6 @@ import static com.earth2me.essentials.I18n.tl;
|
||||
public class MetaItemStack {
|
||||
private static final Map<String, DyeColor> colorMap = new HashMap<>();
|
||||
private static final Map<String, FireworkEffect.Type> fireworkShape = new HashMap<>();
|
||||
private static int bukkitUnbreakableSupport = -1;
|
||||
private static Method spigotMethod;
|
||||
private static Method setUnbreakableMethod;
|
||||
private static boolean useNewSkullMethod = true;
|
||||
|
||||
static {
|
||||
@@ -212,9 +208,9 @@ public class MetaItemStack {
|
||||
stack.setItemMeta(meta);
|
||||
} else if (split[0].equalsIgnoreCase("unbreakable") && hasMetaPermission(sender, "unbreakable", false, true, ess)) {
|
||||
final boolean value = split.length <= 1 || Boolean.parseBoolean(split[1]);
|
||||
setUnbreakable(stack, value);
|
||||
setUnbreakable(ess, stack, value);
|
||||
} else if (split.length > 1 && (split[0].equalsIgnoreCase("player") || split[0].equalsIgnoreCase("owner")) && hasMetaPermission(sender, "head", false, true, ess)) {
|
||||
if (MaterialUtil.isPlayerHead(stack.getType(), stack.getDurability())) {
|
||||
if (MaterialUtil.isPlayerHead(stack)) {
|
||||
final String owner = split[1];
|
||||
setSkullOwner(ess, stack, owner);
|
||||
} else {
|
||||
@@ -529,14 +525,14 @@ public class MetaItemStack {
|
||||
}
|
||||
pmeta.addCustomEffect(pEffect, true);
|
||||
stack.setItemMeta(pmeta);
|
||||
if (ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_9_R1)) {
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01)) {
|
||||
if (isSplashPotion && stack.getType() != Material.SPLASH_POTION) {
|
||||
stack.setType(Material.SPLASH_POTION);
|
||||
} else if (!isSplashPotion && stack.getType() != Material.POTION) {
|
||||
stack.setType(Material.POTION);
|
||||
}
|
||||
} else {
|
||||
final Potion potion = Potion.fromItemStack(stack);
|
||||
final Potion potion = Potion.fromDamage(stack.getDurability());
|
||||
potion.setSplash(isSplashPotion);
|
||||
potion.apply(stack);
|
||||
}
|
||||
@@ -686,35 +682,9 @@ public class MetaItemStack {
|
||||
}
|
||||
}
|
||||
|
||||
private void setUnbreakable(final ItemStack is, final boolean unbreakable) {
|
||||
private void setUnbreakable(final IEssentials ess, final ItemStack is, final boolean unbreakable) {
|
||||
final ItemMeta meta = is.getItemMeta();
|
||||
try {
|
||||
if (bukkitUnbreakableSupport == -1) {
|
||||
try {
|
||||
ItemMeta.class.getDeclaredMethod("setUnbreakable", boolean.class);
|
||||
bukkitUnbreakableSupport = 1;
|
||||
} catch (final NoSuchMethodException | SecurityException ex) {
|
||||
bukkitUnbreakableSupport = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bukkitUnbreakableSupport == 1) {
|
||||
meta.setUnbreakable(unbreakable);
|
||||
} else {
|
||||
if (spigotMethod == null) {
|
||||
spigotMethod = meta.getClass().getDeclaredMethod("spigot");
|
||||
spigotMethod.setAccessible(true);
|
||||
}
|
||||
final Object itemStackSpigot = spigotMethod.invoke(meta);
|
||||
if (setUnbreakableMethod == null) {
|
||||
setUnbreakableMethod = itemStackSpigot.getClass().getDeclaredMethod("setUnbreakable", Boolean.TYPE);
|
||||
setUnbreakableMethod.setAccessible(true);
|
||||
}
|
||||
setUnbreakableMethod.invoke(itemStackSpigot, unbreakable);
|
||||
}
|
||||
is.setItemMeta(meta);
|
||||
} catch (final Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
ess.getItemUnbreakableProvider().setUnbreakable(meta, unbreakable);
|
||||
is.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ 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;
|
||||
|
||||
@@ -105,9 +104,13 @@ public enum Mob {
|
||||
AXOLOTL("Axolotl", Enemies.FRIENDLY, "AXOLOTL"),
|
||||
GOAT("Goat", Enemies.NEUTRAL, "GOAT"),
|
||||
GLOW_SQUID("GlowSquid", Enemies.FRIENDLY, "GLOW_SQUID"),
|
||||
ALLAY("Allay", Enemies.FRIENDLY, "ALLAY"),
|
||||
FROG("Frog", Enemies.FRIENDLY, "FROG"),
|
||||
TADPOLE("Tadpole", Enemies.FRIENDLY, "TADPOLE"),
|
||||
WARDEN("Warden", Enemies.ENEMY, "WARDEN"),
|
||||
CHEST_BOAT("ChestBoat", Enemies.NEUTRAL, "CHEST_BOAT"),
|
||||
;
|
||||
|
||||
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<>();
|
||||
|
||||
@@ -166,7 +169,7 @@ public enum Mob {
|
||||
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"));
|
||||
Essentials.getWrappedLogger().log(Level.WARNING, tl("unableToSpawnMob"));
|
||||
throw new MobException();
|
||||
}
|
||||
return entity;
|
||||
|
||||
@@ -3,10 +3,13 @@ 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.TreeSpecies;
|
||||
import org.bukkit.entity.Axolotl;
|
||||
import org.bukkit.entity.Boat;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Fox;
|
||||
import org.bukkit.entity.Frog;
|
||||
import org.bukkit.entity.Llama;
|
||||
import org.bukkit.entity.MushroomCow;
|
||||
import org.bukkit.entity.Ocelot;
|
||||
@@ -37,6 +40,7 @@ public final class MobCompat {
|
||||
public static final EntityType PHANTOM = getEntityType("PHANTOM");
|
||||
public static final EntityType AXOLOTL = getEntityType("AXOLOTL");
|
||||
public static final EntityType GOAT = getEntityType("GOAT");
|
||||
public static final EntityType FROG = getEntityType("FROG");
|
||||
|
||||
// Constants for mobs that have changed since earlier versions
|
||||
public static final EntityType CAT = getEntityType("CAT", "OCELOT");
|
||||
@@ -164,6 +168,33 @@ public final class MobCompat {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setFrogVariant(final Entity entity, final String variant) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_19_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Frog) {
|
||||
((Frog) entity).setVariant(Frog.Variant.valueOf(variant));
|
||||
}
|
||||
}
|
||||
|
||||
public static void setBoatVariant(final Entity entity, final BoatVariant variant) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
|
||||
return;
|
||||
}
|
||||
final Boat boat;
|
||||
if (entity instanceof Boat) {
|
||||
boat = (Boat) entity;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_19_R01)) {
|
||||
//noinspection deprecation
|
||||
boat.setWoodType(TreeSpecies.valueOf(variant.getTreeSpecies()));
|
||||
} else {
|
||||
boat.setBoatType(Boat.Type.valueOf(variant.getBoatType()));
|
||||
}
|
||||
}
|
||||
|
||||
public enum CatType {
|
||||
// These are (loosely) Mojang names for the cats
|
||||
SIAMESE("SIAMESE", "SIAMESE_CAT"),
|
||||
@@ -228,4 +259,34 @@ public final class MobCompat {
|
||||
}
|
||||
}
|
||||
|
||||
public enum BoatVariant {
|
||||
// Mappings for TreeSpecies names
|
||||
ACACIA("ACACIA", "ACACIA"),
|
||||
BIRCH("BIRCH", "BIRCH"),
|
||||
DARKOAK("DARK_OAK", "DARK_OAK"),
|
||||
GENERIC("GENERIC", "OAK"),
|
||||
JUNGLE("JUNGLE", "JUNGLE"),
|
||||
REDWOOD("REDWOOD", "SPRUCE"),
|
||||
// Mappings for Boat.Type names (falling back to GENERIC where undefined)
|
||||
OAK("GENERIC", "OAK"),
|
||||
SPRUCE("REDWOOD", "SPRUCE"),
|
||||
MANGROVE("GENERIC", "MANGROVE"),
|
||||
;
|
||||
|
||||
private final String treeSpecies;
|
||||
private final String boatType;
|
||||
|
||||
BoatVariant(final String treeSpecies, final String boatType) {
|
||||
this.treeSpecies = treeSpecies;
|
||||
this.boatType = boatType;
|
||||
}
|
||||
|
||||
public String getTreeSpecies() {
|
||||
return treeSpecies;
|
||||
}
|
||||
|
||||
public String getBoatType() {
|
||||
return boatType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.Boat;
|
||||
import org.bukkit.entity.ChestedHorse;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -35,7 +36,6 @@ 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;
|
||||
@@ -197,9 +197,20 @@ public enum MobData {
|
||||
CYAN_AXOLOTL("cyan", MobCompat.AXOLOTL, "axolotl:CYAN", true),
|
||||
BLUE_AXOLOTL("blue", MobCompat.AXOLOTL, "axolotl:BLUE", true),
|
||||
SCREAMING_GOAT("screaming", MobCompat.GOAT, Data.GOAT_SCREAMING, true),
|
||||
TEMPERATE_FROG("temperate", MobCompat.FROG, "frog:TEMPERATE", true),
|
||||
WARM_FROG("warm", MobCompat.FROG, "frog:WARM", true),
|
||||
COLD_FROG("cold", MobCompat.FROG, "frog:COLD", true),
|
||||
ACACIA_BOAT("acacia", Boat.class, MobCompat.BoatVariant.ACACIA, true),
|
||||
BIRCH_BOAT("birch", Boat.class, MobCompat.BoatVariant.BIRCH, true),
|
||||
DARK_OAK_BOAT("darkoak", Boat.class, MobCompat.BoatVariant.DARKOAK, true),
|
||||
GENERIC_BOAT("generic", Boat.class, MobCompat.BoatVariant.GENERIC, true),
|
||||
JUNGLE_BOAT("jungle", Boat.class, MobCompat.BoatVariant.JUNGLE, true),
|
||||
REDWOOD_BOAT("redwood", Boat.class, MobCompat.BoatVariant.REDWOOD, true),
|
||||
MANGROVE_BOAT("mangrove", Boat.class, MobCompat.BoatVariant.MANGROVE, true),
|
||||
OAK_BOAT("oak", Boat.class, MobCompat.BoatVariant.OAK, true),
|
||||
SPRUCE_BOAT("spruce", Boat.class, MobCompat.BoatVariant.SPRUCE, true),
|
||||
;
|
||||
|
||||
public static final Logger logger = Logger.getLogger("Essentials");
|
||||
final private String nickname;
|
||||
final private List<String> suggestions;
|
||||
final private Object type;
|
||||
@@ -376,6 +387,8 @@ public enum MobData {
|
||||
}
|
||||
} else if (this.value.equals(Data.GOAT_SCREAMING)) {
|
||||
((Goat) spawned).setScreaming(true);
|
||||
} else if (this.value instanceof MobCompat.BoatVariant) {
|
||||
MobCompat.setBoatVariant(spawned, (MobCompat.BoatVariant) this.value);
|
||||
} else if (this.value instanceof String) {
|
||||
final String[] split = ((String) this.value).split(":");
|
||||
switch (split[0]) {
|
||||
@@ -403,13 +416,15 @@ public enum MobData {
|
||||
case "fox":
|
||||
MobCompat.setFoxType(spawned, split[1]);
|
||||
break;
|
||||
case "axolotl": {
|
||||
case "axolotl":
|
||||
MobCompat.setAxolotlVariant(spawned, split[1]);
|
||||
break;
|
||||
}
|
||||
case "frog":
|
||||
MobCompat.setFrogVariant(spawned, split[1]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
logger.warning("Unknown mob data type: " + this.toString());
|
||||
Essentials.getWrappedLogger().warning("Unknown mob data type: " + this.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public final class PlayerList {
|
||||
|
||||
final String strippedNick = FormatUtil.stripFormat(user.getNickname());
|
||||
if (ess.getSettings().realNamesOnList() && strippedNick != null && !strippedNick.equals(user.getName())) {
|
||||
groupString.append(" (").append(user.getName()).append(")");
|
||||
groupString.append(" ").append(tl("listRealName",user.getName()));
|
||||
}
|
||||
groupString.append(ChatColor.WHITE.toString());
|
||||
}
|
||||
|
||||
@@ -22,12 +22,12 @@ 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 IEssentials ess;
|
||||
private final EssentialsConfiguration config;
|
||||
private final ConcurrentLinkedQueue<Location> cachedLocations = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public RandomTeleport(final IEssentials essentials) {
|
||||
this.essentials = essentials;
|
||||
this.ess = essentials;
|
||||
config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "tpr.yml"), "/tpr.yml",
|
||||
"Configuration for the random teleport command.\nSome settings may be defaulted, and can be changed via the /settpr command in-game.");
|
||||
reloadConfig();
|
||||
@@ -47,8 +47,8 @@ public class RandomTeleport implements IConf {
|
||||
}
|
||||
} catch (final InvalidWorldException ignored) {
|
||||
}
|
||||
final Location center = essentials.getServer().getWorlds().get(0).getWorldBorder().getCenter();
|
||||
center.setY(center.getWorld().getHighestBlockYAt(center) + 1);
|
||||
final Location center = ess.getServer().getWorlds().get(0).getWorldBorder().getCenter();
|
||||
center.setY(center.getWorld().getHighestBlockYAt(center) + HIGHEST_BLOCK_Y_OFFSET);
|
||||
setCenter(center);
|
||||
return center;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ public class RandomTeleport implements IConf {
|
||||
|
||||
// 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, () -> {
|
||||
ess.getServer().getScheduler().scheduleSyncDelayedTask(ess, () -> {
|
||||
for (int i = 0; i < this.getFindAttempts(); ++i) {
|
||||
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> {
|
||||
if (isValidRandomLocation(location)) {
|
||||
@@ -177,7 +177,7 @@ public class RandomTeleport implements IConf {
|
||||
final Location location = new Location(
|
||||
center.getWorld(),
|
||||
center.getX() + offsetX,
|
||||
center.getWorld().getMaxHeight(),
|
||||
ess.getWorldInfoProvider().getMaxHeight(center.getWorld()),
|
||||
center.getZ() + offsetZ,
|
||||
360 * RANDOM.nextFloat() - 180,
|
||||
0
|
||||
@@ -195,8 +195,8 @@ public class RandomTeleport implements IConf {
|
||||
|
||||
// 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())) {
|
||||
for (int y = 32; y < ess.getWorldInfoProvider().getMaxHeight(location.getWorld()); ++y) {
|
||||
if (!LocationUtil.isBlockUnsafe(ess, location.getWorld(), location.getBlockX(), y, location.getBlockZ())) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
@@ -204,6 +204,10 @@ public class RandomTeleport implements IConf {
|
||||
}
|
||||
|
||||
private boolean isValidRandomLocation(final Location location) {
|
||||
return location.getBlockY() > 0 && !this.getExcludedBiomes().contains(location.getBlock().getBiome());
|
||||
return location.getBlockY() > ess.getWorldInfoProvider().getMinHeight(location.getWorld()) && !this.getExcludedBiomes().contains(location.getBlock().getBiome());
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return config.getFile();
|
||||
}
|
||||
}
|
||||
@@ -40,14 +40,12 @@ import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Settings implements net.ess3.api.ISettings {
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
private static final BigDecimal DEFAULT_MAX_MONEY = new BigDecimal("10000000000000");
|
||||
private static final BigDecimal DEFAULT_MIN_MONEY = new BigDecimal("-10000000000000");
|
||||
private final transient EssentialsConfiguration config;
|
||||
@@ -226,6 +224,21 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return chatQuestion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShoutDefault() {
|
||||
return config.getBoolean("chat.shout-default", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistShout() {
|
||||
return config.getBoolean("chat.persist-shout", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChatQuestionEnabled() {
|
||||
return config.getBoolean("chat.question-enabled", true);
|
||||
}
|
||||
|
||||
public boolean _isTeleportSafetyEnabled() {
|
||||
return config.getBoolean("teleport-safety", true);
|
||||
}
|
||||
@@ -671,7 +684,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
boolean mapModified = false;
|
||||
if (!disabledBukkitCommands.isEmpty()) {
|
||||
if (isDebug()) {
|
||||
logger.log(Level.INFO, "Re-adding " + disabledBukkitCommands.size() + " disabled commands!");
|
||||
ess.getLogger().log(Level.INFO, "Re-adding " + disabledBukkitCommands.size() + " disabled commands!");
|
||||
}
|
||||
ess.getKnownCommandsProvider().getKnownCommands().putAll(disabledBukkitCommands);
|
||||
disabledBukkitCommands.clear();
|
||||
@@ -683,12 +696,12 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
final Command toDisable = ess.getPluginCommand(effectiveAlias);
|
||||
if (toDisable != null) {
|
||||
if (isDebug()) {
|
||||
logger.log(Level.INFO, "Attempting removal of " + effectiveAlias);
|
||||
ess.getLogger().log(Level.INFO, "Attempting removal of " + effectiveAlias);
|
||||
}
|
||||
final Command removed = ess.getKnownCommandsProvider().getKnownCommands().remove(effectiveAlias);
|
||||
if (removed != null) {
|
||||
if (isDebug()) {
|
||||
logger.log(Level.INFO, "Adding command " + effectiveAlias + " to disabled map!");
|
||||
ess.getLogger().log(Level.INFO, "Adding command " + effectiveAlias + " to disabled map!");
|
||||
}
|
||||
disabledBukkitCommands.put(effectiveAlias, removed);
|
||||
}
|
||||
@@ -705,7 +718,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
|
||||
if (mapModified) {
|
||||
if (isDebug()) {
|
||||
logger.log(Level.INFO, "Syncing commands");
|
||||
ess.getLogger().log(Level.INFO, "Syncing commands");
|
||||
}
|
||||
if (reloadCount.get() < 2) {
|
||||
ess.scheduleSyncDelayedTask(() -> ess.getSyncCommandsProvider().syncCommands());
|
||||
@@ -784,7 +797,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
//noinspection deprecation
|
||||
final IItemDb itemDb = ess.getItemDb();
|
||||
if (itemDb == null || !itemDb.isReady()) {
|
||||
logger.log(Level.FINE, "Skipping item spawn blacklist read; item DB not yet loaded.");
|
||||
ess.getLogger().log(Level.FINE, "Skipping item spawn blacklist read; item DB not yet loaded.");
|
||||
return epItemSpwn;
|
||||
}
|
||||
for (String itemName : config.getString("item-spawn-blacklist", "").split(",")) {
|
||||
@@ -796,7 +809,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
final ItemStack iStack = itemDb.get(itemName);
|
||||
epItemSpwn.add(iStack.getType());
|
||||
} catch (final Exception ex) {
|
||||
logger.log(Level.SEVERE, tl("unknownItemInList", itemName, "item-spawn-blacklist"), ex);
|
||||
ess.getLogger().log(Level.SEVERE, tl("unknownItemInList", itemName, "item-spawn-blacklist"), ex);
|
||||
}
|
||||
}
|
||||
return epItemSpwn;
|
||||
@@ -824,7 +837,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
try {
|
||||
newSigns.add(Signs.valueOf(signName).getSign());
|
||||
} catch (final Exception ex) {
|
||||
logger.log(Level.SEVERE, tl("unknownItemInList", signName, "enabledSigns"));
|
||||
ess.getLogger().log(Level.SEVERE, tl("unknownItemInList", signName, "enabledSigns"));
|
||||
continue;
|
||||
}
|
||||
signsEnabled = true;
|
||||
@@ -938,7 +951,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
}
|
||||
|
||||
if (mat == null) {
|
||||
logger.log(Level.SEVERE, tl("unknownItemInList", itemName, configName));
|
||||
ess.getLogger().log(Level.SEVERE, tl("unknownItemInList", itemName, configName));
|
||||
} else {
|
||||
list.add(mat);
|
||||
}
|
||||
@@ -1212,6 +1225,11 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return registerBackInListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxTreeCommandRange() {
|
||||
return config.getInt("tree-command-range-limit", 300);
|
||||
}
|
||||
|
||||
private boolean _registerBackInListener() {
|
||||
return config.getBoolean("register-back-in-listener", false);
|
||||
}
|
||||
@@ -1264,6 +1282,11 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return config.getLong("tpa-accept-cancellation", 120);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTpaMaxRequests() {
|
||||
return config.getInt("tpa-max-requests", 5);
|
||||
}
|
||||
|
||||
private long _getTeleportInvulnerability() {
|
||||
return config.getLong("teleport-invulnerability", 0) * 1000;
|
||||
}
|
||||
@@ -1670,7 +1693,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
try {
|
||||
newSigns.add(Signs.valueOf(signName).getSign());
|
||||
} catch (final Exception ex) {
|
||||
logger.log(Level.SEVERE, tl("unknownItemInList", signName, "unprotected-sign-names"));
|
||||
ess.getLogger().log(Level.SEVERE, tl("unknownItemInList", signName, "unprotected-sign-names"));
|
||||
}
|
||||
}
|
||||
return newSigns;
|
||||
@@ -1855,7 +1878,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
try {
|
||||
blacklist.add(Pattern.compile(entry).asPredicate());
|
||||
} catch (final PatternSyntaxException e) {
|
||||
logger.warning("Invalid nickname blacklist regex: " + entry);
|
||||
ess.getLogger().warning("Invalid nickname blacklist regex: " + entry);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ public final class SpawnMob {
|
||||
|
||||
// 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);
|
||||
final Location sloc = LocationUtil.getSafeDestination(ess, loc);
|
||||
|
||||
for (final String part : parts) {
|
||||
final Mob mob = Mob.fromName(part);
|
||||
|
||||
@@ -145,7 +145,7 @@ public class Teleport implements ITeleport {
|
||||
teleportee.getBase().eject();
|
||||
}
|
||||
|
||||
if (LocationUtil.isBlockUnsafeForUser(teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
|
||||
if (LocationUtil.isBlockUnsafeForUser(ess, teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
|
||||
if (ess.getSettings().isTeleportSafetyEnabled()) {
|
||||
if (ess.getSettings().isForceDisableTeleportSafety()) {
|
||||
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.earth2me.essentials;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.craftbukkit.SetExpFix;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IUser;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
@@ -21,7 +22,6 @@ 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 static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
@@ -79,7 +79,7 @@ public class Trade {
|
||||
try {
|
||||
fw = new FileWriter(new File(ess.getDataFolder(), "trade.log"), true);
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger("Essentials").log(Level.SEVERE, null, ex);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
@@ -95,8 +95,10 @@ public class Trade {
|
||||
} else {
|
||||
if (charge.getItemStack() != null) {
|
||||
sb.append(charge.getItemStack().getAmount()).append(",");
|
||||
sb.append(charge.getItemStack().getType().toString()).append(",");
|
||||
sb.append(charge.getItemStack().getDurability());
|
||||
sb.append(charge.getItemStack().getType()).append(",");
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
sb.append(charge.getItemStack().getDurability());
|
||||
}
|
||||
}
|
||||
if (charge.getMoney() != null) {
|
||||
sb.append(charge.getMoney()).append(",");
|
||||
@@ -119,8 +121,10 @@ public class Trade {
|
||||
} else {
|
||||
if (pay.getItemStack() != null) {
|
||||
sb.append(pay.getItemStack().getAmount()).append(",");
|
||||
sb.append(pay.getItemStack().getType().toString()).append(",");
|
||||
sb.append(pay.getItemStack().getDurability());
|
||||
sb.append(pay.getItemStack().getType()).append(",");
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
sb.append(pay.getItemStack().getDurability());
|
||||
}
|
||||
}
|
||||
if (pay.getMoney() != null) {
|
||||
sb.append(pay.getMoney()).append(",");
|
||||
@@ -154,7 +158,7 @@ public class Trade {
|
||||
fw.write(sb.toString());
|
||||
fw.flush();
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger("Essentials").log(Level.SEVERE, null, ex);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +167,7 @@ public class Trade {
|
||||
try {
|
||||
fw.close();
|
||||
} catch (final IOException ex) {
|
||||
Logger.getLogger("Essentials").log(Level.SEVERE, null, ex);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
fw = null;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
@@ -90,7 +89,7 @@ public class UUIDMap {
|
||||
}
|
||||
loading = false;
|
||||
} catch (final IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,9 +146,9 @@ public class UUIDMap {
|
||||
Files.move(configFile, new File(endFile.getParentFile(), "usermap.bak.csv"));
|
||||
}
|
||||
} catch (final Exception ex2) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex2.getMessage(), ex2);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, ex2.getMessage(), ex2);
|
||||
}
|
||||
Bukkit.getLogger().log(Level.WARNING, ex.getMessage(), ex);
|
||||
Essentials.getWrappedLogger().log(Level.WARNING, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,54 +28,70 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class User extends UserData implements Comparable<User>, IMessageRecipient, net.ess3.api.IUser {
|
||||
private static final Statistic PLAY_ONE_TICK = EnumUtil.getStatistic("PLAY_ONE_MINUTE", "PLAY_ONE_TICK");
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
|
||||
// User modules
|
||||
private final IMessageRecipient messageRecipient;
|
||||
private transient final AsyncTeleport teleport;
|
||||
private transient final Teleport legacyTeleport;
|
||||
|
||||
// User command confirmation strings
|
||||
private final Map<User, BigDecimal> confirmingPayments = new WeakHashMap<>();
|
||||
private transient UUID teleportRequester;
|
||||
private transient boolean teleportRequestHere;
|
||||
private transient Location teleportLocation;
|
||||
|
||||
// User teleport variables
|
||||
private final transient LinkedHashMap<String, TpaRequest> teleportRequestQueue = new LinkedHashMap<>();
|
||||
|
||||
// User properties
|
||||
private transient boolean vanished;
|
||||
private transient long teleportRequestTime;
|
||||
private transient long lastOnlineActivity;
|
||||
private transient long lastThrottledAction;
|
||||
private transient long lastActivity = System.currentTimeMillis();
|
||||
private boolean hidden = false;
|
||||
private boolean leavingHidden = false;
|
||||
private boolean rightClickJump = false;
|
||||
private transient Location afkPosition = null;
|
||||
private boolean invSee = false;
|
||||
private boolean recipeSee = false;
|
||||
private boolean enderSee = false;
|
||||
private transient long teleportInvulnerabilityTimestamp = 0;
|
||||
private boolean ignoreMsg = false;
|
||||
|
||||
// User afk variables
|
||||
private String afkMessage;
|
||||
private long afkSince;
|
||||
private transient Location afkPosition = null;
|
||||
|
||||
// Misc
|
||||
private transient long lastOnlineActivity;
|
||||
private transient long lastThrottledAction;
|
||||
private transient long lastActivity = System.currentTimeMillis();
|
||||
private transient long teleportInvulnerabilityTimestamp = 0;
|
||||
private String confirmingClearCommand;
|
||||
private long lastNotifiedAboutMailsMs;
|
||||
private String lastHomeConfirmation;
|
||||
private long lastHomeConfirmationTimestamp;
|
||||
private boolean toggleShout = false;
|
||||
private Boolean toggleShout;
|
||||
private transient final List<String> signCopy = Lists.newArrayList("", "", "", "");
|
||||
private transient long lastVanishTime = System.currentTimeMillis();
|
||||
|
||||
public User(final Player base, final IEssentials ess) {
|
||||
super(base, ess);
|
||||
@@ -90,9 +106,12 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
this.messageRecipient = new SimpleMessageRecipient(ess, this);
|
||||
}
|
||||
|
||||
User update(final Player base) {
|
||||
void update(final Player base) {
|
||||
setBase(base);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IEssentials getEssentials() {
|
||||
return ess;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -304,7 +323,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
if (isAuthorized("essentials.itemspawn.item-all") || isAuthorized("essentials.itemspawn.item-" + name))
|
||||
return true;
|
||||
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
final int id = material.getId();
|
||||
if (isAuthorized("essentials.itemspawn.item-" + id)) return true;
|
||||
}
|
||||
@@ -327,44 +346,94 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void requestTeleport(final User player, final boolean here) {
|
||||
teleportRequestTime = System.currentTimeMillis();
|
||||
teleportRequester = player == null ? null : player.getBase().getUniqueId();
|
||||
teleportRequestHere = here;
|
||||
if (player == null) {
|
||||
teleportLocation = null;
|
||||
} else {
|
||||
teleportLocation = here ? player.getLocation() : this.getLocation();
|
||||
final TpaRequest request = teleportRequestQueue.getOrDefault(player.getName(), new TpaRequest(player.getName(), player.getUUID()));
|
||||
request.setTime(System.currentTimeMillis());
|
||||
request.setHere(here);
|
||||
request.setLocation(here ? player.getLocation() : this.getLocation());
|
||||
|
||||
// Handle max queue size
|
||||
teleportRequestQueue.remove(request.getName());
|
||||
if (teleportRequestQueue.size() >= ess.getSettings().getTpaMaxRequests()) {
|
||||
final List<String> keys = new ArrayList<>(teleportRequestQueue.keySet());
|
||||
teleportRequestQueue.remove(keys.get(keys.size() - 1));
|
||||
}
|
||||
|
||||
// Add request to queue
|
||||
teleportRequestQueue.put(request.getName(), request);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean hasOutstandingTeleportRequest() {
|
||||
if (getTeleportRequest() != null) { // Player has outstanding teleport request.
|
||||
final long timeout = ess.getSettings().getTpaAcceptCancellation();
|
||||
if (timeout != 0) {
|
||||
if ((System.currentTimeMillis() - getTeleportRequestTime()) / 1000 <= timeout) { // Player has outstanding request
|
||||
return true;
|
||||
} else { // outstanding request expired.
|
||||
requestTeleport(null, false);
|
||||
return false;
|
||||
return getNextTpaRequest(false, false, false) != null;
|
||||
}
|
||||
|
||||
public Collection<String> getPendingTpaKeys() {
|
||||
return teleportRequestQueue.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPendingTpaRequests(boolean inform, boolean excludeHere) {
|
||||
return getNextTpaRequest(inform, false, excludeHere) != null;
|
||||
}
|
||||
|
||||
public boolean hasOutstandingTpaRequest(String playerUsername, boolean here) {
|
||||
final TpaRequest request = getOutstandingTpaRequest(playerUsername, false);
|
||||
return request != null && request.isHere() == here;
|
||||
}
|
||||
|
||||
public @Nullable TpaRequest getOutstandingTpaRequest(String playerUsername, boolean inform) {
|
||||
if (!teleportRequestQueue.containsKey(playerUsername)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final long timeout = ess.getSettings().getTpaAcceptCancellation();
|
||||
final TpaRequest request = teleportRequestQueue.get(playerUsername);
|
||||
if (timeout < 1 || System.currentTimeMillis() - request.getTime() <= timeout * 1000) {
|
||||
return request;
|
||||
}
|
||||
teleportRequestQueue.remove(playerUsername);
|
||||
if (inform) {
|
||||
sendMessage(tl("requestTimedOutFrom", ess.getUser(request.getRequesterUuid()).getDisplayName()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public TpaRequest removeTpaRequest(String playerUsername) {
|
||||
return teleportRequestQueue.remove(playerUsername);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TpaRequest getNextTpaRequest(boolean inform, boolean ignoreExpirations, boolean excludeHere) {
|
||||
if (teleportRequestQueue.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final long timeout = ess.getSettings().getTpaAcceptCancellation();
|
||||
final List<String> keys = new ArrayList<>(teleportRequestQueue.keySet());
|
||||
Collections.reverse(keys);
|
||||
|
||||
TpaRequest nextRequest = null;
|
||||
for (final String key : keys) {
|
||||
final TpaRequest request = teleportRequestQueue.get(key);
|
||||
if (timeout < 1 || (System.currentTimeMillis() - request.getTime()) <= TimeUnit.SECONDS.toMillis(timeout)) {
|
||||
if (excludeHere && request.isHere()) {
|
||||
continue;
|
||||
}
|
||||
} else { // outstanding request does not expire
|
||||
return true;
|
||||
|
||||
if (ignoreExpirations) {
|
||||
return request;
|
||||
} else if (nextRequest == null) {
|
||||
nextRequest = request;
|
||||
}
|
||||
} else {
|
||||
if (inform) {
|
||||
sendMessage(tl("requestTimedOutFrom", ess.getUser(request.getRequesterUuid()).getDisplayName()));
|
||||
}
|
||||
teleportRequestQueue.remove(key);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public UUID getTeleportRequest() {
|
||||
return teleportRequester;
|
||||
}
|
||||
|
||||
public boolean isTpRequestHere() {
|
||||
return teleportRequestHere;
|
||||
}
|
||||
|
||||
public Location getTpRequestLocation() {
|
||||
return teleportLocation;
|
||||
return nextRequest;
|
||||
}
|
||||
|
||||
public String getNick() {
|
||||
@@ -450,7 +519,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
this.getBase().setPlayerListName(name);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
logger.log(Level.INFO, "Playerlist for " + name + " was not updated. Name clashed with another online player.");
|
||||
ess.getLogger().log(Level.INFO, "Playerlist for " + name + " was not updated. Name clashed with another online player.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -568,7 +637,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return;
|
||||
}
|
||||
|
||||
this.getBase().setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") || set && ess.getSettings().sleepIgnoresAfkPlayers());
|
||||
this.getBase().setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") || (set && ess.getSettings().sleepIgnoresAfkPlayers()));
|
||||
if (set && !isAfk()) {
|
||||
afkPosition = this.getLocation();
|
||||
this.afkSince = System.currentTimeMillis();
|
||||
@@ -613,6 +682,16 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return hidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeavingHidden() {
|
||||
return leavingHidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLeavingHidden(boolean leavingHidden) {
|
||||
this.leavingHidden = leavingHidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHidden(final boolean hidden) {
|
||||
this.hidden = hidden;
|
||||
@@ -823,8 +902,11 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return ess.getPermissionsHandler().canBuild(base, getGroup());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public long getTeleportRequestTime() {
|
||||
return teleportRequestTime;
|
||||
final TpaRequest request = getNextTpaRequest(false, false, false);
|
||||
return request == null ? 0L : request.getTime();
|
||||
}
|
||||
|
||||
public boolean isInvSee() {
|
||||
@@ -892,7 +974,9 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
}
|
||||
setHidden(true);
|
||||
lastVanishTime = System.currentTimeMillis();
|
||||
ess.getVanishedPlayersNew().add(getName());
|
||||
this.getBase().setMetadata("vanished", new FixedMetadataValue(ess, true));
|
||||
if (isAuthorized("essentials.vanish.effect")) {
|
||||
this.getBase().addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 1, false));
|
||||
}
|
||||
@@ -905,6 +989,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
setHidden(false);
|
||||
ess.getVanishedPlayersNew().remove(getName());
|
||||
this.getBase().setMetadata("vanished", new FixedMetadataValue(ess, false));
|
||||
if (isAuthorized("essentials.vanish.effect")) {
|
||||
this.getBase().removePotionEffect(PotionEffectType.INVISIBILITY);
|
||||
}
|
||||
@@ -990,7 +1075,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
return getBase().getUniqueId();
|
||||
return this.getBase().getUniqueId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1116,6 +1201,10 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return isBaltopExcludeCache();
|
||||
}
|
||||
|
||||
public long getLastVanishTime() {
|
||||
return lastVanishTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getTargetBlock(int maxDistance) {
|
||||
final Block block;
|
||||
@@ -1128,10 +1217,16 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
@Override
|
||||
public void setToggleShout(boolean toggleShout) {
|
||||
this.toggleShout = toggleShout;
|
||||
if (ess.getSettings().isPersistShout()) {
|
||||
setShouting(toggleShout);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToggleShout() {
|
||||
return toggleShout;
|
||||
if (ess.getSettings().isPersistShout()) {
|
||||
return toggleShout = isShouting();
|
||||
}
|
||||
return toggleShout == null ? toggleShout = ess.getSettings().isShoutDefault() : toggleShout;
|
||||
}
|
||||
}
|
||||
@@ -85,14 +85,14 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
try {
|
||||
holder = config.getRootNode().get(UserConfigHolder.class);
|
||||
} catch (SerializationException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while reading user config: " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.SEVERE, "Error while reading user config: " + config.getFile().getName(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
config.setSaveHook(() -> {
|
||||
try {
|
||||
config.getRootNode().set(UserConfigHolder.class, holder);
|
||||
} catch (SerializationException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while saving user config: " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.SEVERE, "Error while saving user config: " + config.getFile().getName(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
@@ -722,6 +722,18 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public boolean isShouting() {
|
||||
if (holder.shouting() == null) {
|
||||
holder.shouting(ess.getSettings().isShoutDefault());
|
||||
}
|
||||
return holder.shouting();
|
||||
}
|
||||
|
||||
public void setShouting(boolean shouting) {
|
||||
holder.shouting(shouting);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public UUID getConfigUUID() {
|
||||
return config.getUuid();
|
||||
}
|
||||
|
||||
@@ -16,12 +16,10 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
private final Map<StringIgnoreCase, EssentialsConfiguration> warpPoints = new HashMap<>();
|
||||
private final File warpsFolder;
|
||||
|
||||
@@ -38,6 +36,11 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
return warpPoints.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWarp(String name) {
|
||||
return warpPoints.containsKey(new StringIgnoreCase(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getList() {
|
||||
final List<String> keys = new ArrayList<>();
|
||||
@@ -130,7 +133,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
warpPoints.put(new StringIgnoreCase(name), conf);
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
logger.log(Level.WARNING, tl("loadWarpError", filename), ex);
|
||||
Essentials.getWrappedLogger().log(Level.WARNING, tl("loadWarpError", filename), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,13 +30,15 @@ public class Worth implements IConf {
|
||||
* @return The price from the config.
|
||||
*/
|
||||
public BigDecimal getPrice(final IEssentials ess, final ItemStack itemStack) {
|
||||
BigDecimal result;
|
||||
BigDecimal result = BigDecimal.ONE.negate();
|
||||
|
||||
final String itemname = itemStack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
|
||||
|
||||
// Check for matches with data value from stack
|
||||
// Note that we always default to BigDecimal.ONE.negate(), equivalent to -1
|
||||
result = config.getBigDecimal("worth." + itemname + "." + itemStack.getDurability(), BigDecimal.ONE.negate());
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
// 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) {
|
||||
@@ -140,7 +142,7 @@ public class Worth implements IConf {
|
||||
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) {
|
||||
if (VersionUtil.PRE_FLATTENING && itemStack.getType().getData() == null) {
|
||||
// Bukkit-bug: getDurability still contains the correct value, while getData().getData() is 0.
|
||||
path = path + "." + itemStack.getDurability();
|
||||
}
|
||||
@@ -149,6 +151,10 @@ public class Worth implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return config.getFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
config.load();
|
||||
|
||||
@@ -17,14 +17,12 @@ import java.math.MathContext;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* You should use Vault instead of directly using this class.
|
||||
*/
|
||||
public class Economy {
|
||||
public static final MathContext MATH_CONTEXT = MathContext.DECIMAL128;
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private static IEssentials ess;
|
||||
|
||||
private static final String WARN_CALL_BEFORE_LOAD = "Essentials API is called before Essentials is loaded.";
|
||||
@@ -54,8 +52,8 @@ public class Economy {
|
||||
final UUID npcUUID = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
final File npcFile = new File(folder, npcUUID + ".yml");
|
||||
if (npcFile.exists()) {
|
||||
LOGGER.log(Level.SEVERE, MessageFormat.format(WARN_NPC_RECREATE_1, name, npcUUID.toString()), new RuntimeException());
|
||||
LOGGER.log(Level.SEVERE, WARN_NPC_RECREATE_2);
|
||||
ess.getLogger().log(Level.SEVERE, MessageFormat.format(WARN_NPC_RECREATE_1, name, npcUUID.toString()), new RuntimeException());
|
||||
ess.getLogger().log(Level.SEVERE, WARN_NPC_RECREATE_2);
|
||||
}
|
||||
final EssentialsUserConfiguration npcConfig = new EssentialsUserConfiguration(name, npcUUID, npcFile);
|
||||
npcConfig.load();
|
||||
@@ -90,7 +88,7 @@ public class Economy {
|
||||
if (player != null) {
|
||||
user = ess.getUser(player.getUniqueId());
|
||||
if (user != null) {
|
||||
LOGGER.log(Level.INFO, MessageFormat.format(WARN_PLAYER_UUID_NO_NAME, name, player.getUniqueId().toString()), new RuntimeException());
|
||||
ess.getLogger().log(Level.INFO, MessageFormat.format(WARN_PLAYER_UUID_NO_NAME, name, player.getUniqueId().toString()), new RuntimeException());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,7 +188,7 @@ public class Economy {
|
||||
try {
|
||||
setMoney(name, BigDecimal.valueOf(balance));
|
||||
} catch (final ArithmeticException e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to set balance of " + name + " to " + balance + ": " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.WARNING, "Failed to set balance of " + name + " to " + balance + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +266,7 @@ public class Economy {
|
||||
try {
|
||||
add(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to add " + amount + " to balance of " + name + ": " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.WARNING, "Failed to add " + amount + " to balance of " + name + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +338,7 @@ public class Economy {
|
||||
try {
|
||||
substract(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to subtract " + amount + " of balance of " + name + ": " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.WARNING, "Failed to subtract " + amount + " of balance of " + name + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,7 +408,7 @@ public class Economy {
|
||||
try {
|
||||
divide(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to divide balance of " + name + " by " + amount + ": " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.WARNING, "Failed to divide balance of " + name + " by " + amount + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +480,7 @@ public class Economy {
|
||||
try {
|
||||
multiply(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to multiply balance of " + name + " by " + amount + ": " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.WARNING, "Failed to multiply balance of " + name + " by " + amount + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,7 +601,7 @@ public class Economy {
|
||||
try {
|
||||
return hasEnough(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -664,7 +662,7 @@ public class Economy {
|
||||
try {
|
||||
return hasMore(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -726,7 +724,7 @@ public class Economy {
|
||||
try {
|
||||
return hasLess(name, BigDecimal.valueOf(amount));
|
||||
} catch (final ArithmeticException e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -833,7 +831,7 @@ public class Economy {
|
||||
try {
|
||||
return format(BigDecimal.valueOf(amount));
|
||||
} catch (final NumberFormatException e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to display " + amount + ": " + e.getMessage(), e);
|
||||
ess.getLogger().log(Level.WARNING, "Failed to display " + amount + ": " + e.getMessage(), e);
|
||||
return "NaN";
|
||||
}
|
||||
}
|
||||
@@ -900,7 +898,7 @@ public class Economy {
|
||||
createNPCFile(name);
|
||||
return true;
|
||||
}
|
||||
LOGGER.log(Level.WARNING, MessageFormat.format(WARN_EXISTING_NPC_CREATE, name, user.getConfigUUID()), new RuntimeException());
|
||||
ess.getLogger().log(Level.WARNING, MessageFormat.format(WARN_EXISTING_NPC_CREATE, name, user.getConfigUUID()), new RuntimeException());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,14 @@ public interface IWarps extends IConf {
|
||||
*/
|
||||
Location getWarp(String warp) throws WarpNotFoundException, net.ess3.api.InvalidWorldException;
|
||||
|
||||
/**
|
||||
* Checks if the provided name is a warp.
|
||||
*
|
||||
* @param name The warp name.
|
||||
* @return true if a warp by that name exists.
|
||||
*/
|
||||
boolean isWarp(String name);
|
||||
|
||||
/**
|
||||
* Gets a list of warps
|
||||
*
|
||||
|
||||
@@ -32,7 +32,7 @@ public class Commandbigtree extends EssentialsCommand {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final Location loc = LocationUtil.getTarget(user.getBase()).add(0, 1, 0);
|
||||
final Location loc = LocationUtil.getTarget(user.getBase(), ess.getSettings().getMaxTreeCommandRange()).add(0, 1, 0);
|
||||
if (loc.getBlock().getType().isSolid()) {
|
||||
throw new Exception(tl("bigTreeFailure"));
|
||||
}
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
} else {
|
||||
for (final Item item : items) {
|
||||
final ItemStack stack = new ItemStack(item.getMaterial());
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
stack.setDurability(item.getData());
|
||||
}
|
||||
// amount -1 means all items will be cleared
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.earth2me.essentials.ChargeException;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.Trade.OverflowType;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
@@ -161,8 +162,7 @@ public class Commandcondense extends EssentialsCommand {
|
||||
iter.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inputSlot.getDurability() == Short.MAX_VALUE) {
|
||||
if (VersionUtil.PRE_FLATTENING && inputSlot.getDurability() == Short.MAX_VALUE) {
|
||||
inputSlot.setDurability((short) 0);
|
||||
}
|
||||
if (!inputSlot.isSimilar(stack)) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.Kit;
|
||||
import com.earth2me.essentials.config.ConfigurateUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
|
||||
@@ -38,7 +37,7 @@ public class Commanddelkit extends EssentialsCommand {
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList(ConfigurateUtil.getKeys(ess.getKits().getKits()));
|
||||
return Lists.newArrayList(ess.getKits().getKitKeys());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -23,8 +23,14 @@ public class Commanddelwarp extends EssentialsCommand {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
//Check if warp exists before calling the event
|
||||
final Location location = ess.getWarps().getWarp(args[0]);
|
||||
if (location != null) {
|
||||
if (ess.getWarps().isWarp(args[0])) {
|
||||
Location location;
|
||||
try {
|
||||
location = ess.getWarps().getWarp(args[0]);
|
||||
} catch (Exception ignored) {
|
||||
// World is unloaded/deleted
|
||||
location = null;
|
||||
}
|
||||
final WarpModifyEvent event = new WarpModifyEvent(sender.getUser(this.ess), args[0], location, null, WarpModifyEvent.WarpModifyCause.DELETE);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.UserMap;
|
||||
import com.earth2me.essentials.economy.EconomyLayer;
|
||||
import com.earth2me.essentials.economy.EconomyLayers;
|
||||
import com.earth2me.essentials.utils.CommandMapUtil;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.FloatUtil;
|
||||
@@ -25,6 +26,7 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
@@ -42,6 +44,7 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -76,7 +79,12 @@ public class Commandessentials extends EssentialsCommand {
|
||||
"PermissionsEx", // permissions (unsupported)
|
||||
"GroupManager", // permissions (unsupported)
|
||||
"bPermissions", // permissions (unsupported)
|
||||
"DiscordSRV" // potential for issues if EssentialsXDiscord is installed
|
||||
"DiscordSRV", // potential for issues if EssentialsXDiscord is installed
|
||||
|
||||
// Chat signing bypass plugins that can potentially break EssentialsChat
|
||||
"AntiPopup",
|
||||
"NoChatReports",
|
||||
"NoEncryption"
|
||||
);
|
||||
private static final List<String> officialPlugins = Arrays.asList(
|
||||
"EssentialsAntiBuild",
|
||||
@@ -90,7 +98,11 @@ public class Commandessentials extends EssentialsCommand {
|
||||
private static final List<String> warnPlugins = Arrays.asList(
|
||||
"PermissionsEx",
|
||||
"GroupManager",
|
||||
"bPermissions"
|
||||
"bPermissions",
|
||||
|
||||
// Brain-dead chat signing bypass that break EssentialsChat
|
||||
"NoChatReports",
|
||||
"NoEncryption"
|
||||
);
|
||||
private transient TuneRunnable currentTune = null;
|
||||
|
||||
@@ -258,6 +270,10 @@ public class Commandessentials extends EssentialsCommand {
|
||||
files.add(new PasteUtil.PasteFile("dump.json", dump.toString()));
|
||||
|
||||
final Plugin essDiscord = Bukkit.getPluginManager().getPlugin("EssentialsDiscord");
|
||||
final Plugin essSpawn = Bukkit.getPluginManager().getPlugin("EssentialsSpawn");
|
||||
|
||||
final Map<String, Command> knownCommandsCopy = new HashMap<>(ess.getKnownCommandsProvider().getKnownCommands());
|
||||
final Map<String, String> disabledCommandsCopy = new HashMap<>(ess.getAlternativeCommandsHandler().disabledCommands());
|
||||
|
||||
// Further operations will be heavy IO
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
@@ -265,12 +281,20 @@ public class Commandessentials extends EssentialsCommand {
|
||||
boolean discord = false;
|
||||
boolean kits = false;
|
||||
boolean log = false;
|
||||
boolean worth = false;
|
||||
boolean tpr = false;
|
||||
boolean spawns = false;
|
||||
boolean commands = false;
|
||||
for (final String arg : args) {
|
||||
if (arg.equals("*")) {
|
||||
if (arg.equals("*") || arg.equalsIgnoreCase("all")) {
|
||||
config = true;
|
||||
discord = true;
|
||||
kits = true;
|
||||
log = true;
|
||||
worth = true;
|
||||
tpr = true;
|
||||
spawns = true;
|
||||
commands = true;
|
||||
break;
|
||||
} else if (arg.equalsIgnoreCase("config")) {
|
||||
config = true;
|
||||
@@ -280,6 +304,14 @@ public class Commandessentials extends EssentialsCommand {
|
||||
kits = true;
|
||||
} else if (arg.equalsIgnoreCase("log")) {
|
||||
log = true;
|
||||
} else if (arg.equalsIgnoreCase("worth")) {
|
||||
worth = true;
|
||||
} else if (arg.equalsIgnoreCase("tpr")) {
|
||||
tpr = true;
|
||||
} else if (arg.equalsIgnoreCase("spawns")) {
|
||||
spawns = true;
|
||||
} else if (arg.equalsIgnoreCase("commands")) {
|
||||
commands = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,11 +323,11 @@ public class Commandessentials extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
if (discord && essDiscord != null && essDiscord.isEnabled()) {
|
||||
if (discord && essDiscord != null) {
|
||||
try {
|
||||
files.add(new PasteUtil.PasteFile("discord-config.yml",
|
||||
new String(Files.readAllBytes(essDiscord.getDataFolder().toPath().resolve("config.yml")), StandardCharsets.UTF_8)
|
||||
.replaceAll("[MN][A-Za-z\\d]{23}\\.[\\w-]{6}\\.[\\w-]{27}", "<censored token>")));
|
||||
.replaceAll("[A-Za-z\\d]{24}\\.[\\w-]{6}\\.[\\w-]{27}", "<censored token>")));
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(tl("dumpErrorUpload", "discord-config.yml", e.getMessage()));
|
||||
}
|
||||
@@ -319,6 +351,40 @@ public class Commandessentials extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
if (worth) {
|
||||
try {
|
||||
files.add(new PasteUtil.PasteFile("worth.yml", new String(Files.readAllBytes(ess.getWorth().getFile().toPath()), StandardCharsets.UTF_8)));
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(tl("dumpErrorUpload", "worth.yml", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
if (tpr) {
|
||||
try {
|
||||
files.add(new PasteUtil.PasteFile("tpr.yml", new String(Files.readAllBytes(ess.getRandomTeleport().getFile().toPath()), StandardCharsets.UTF_8)));
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(tl("dumpErrorUpload", "tpr.yml", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
if (spawns && essSpawn != null) {
|
||||
try {
|
||||
files.add(new PasteUtil.PasteFile("spawn.yml", new String(Files.readAllBytes(ess.getDataFolder().toPath().resolve("spawn.yml")), StandardCharsets.UTF_8)));
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(tl("dumpErrorUpload", "spawn.yml", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
if (commands) {
|
||||
try {
|
||||
files.add(new PasteUtil.PasteFile("commands.yml", new String(Files.readAllBytes(Paths.get("commands.yml")), StandardCharsets.UTF_8)));
|
||||
files.add(new PasteUtil.PasteFile("commandmap.json", CommandMapUtil.toJsonPretty(ess, knownCommandsCopy)));
|
||||
files.add(new PasteUtil.PasteFile("commandoverride.json", disabledCommandsCopy.toString()));
|
||||
} catch (IOException e) {
|
||||
sender.sendMessage(tl("dumpErrorUpload", "commands.yml", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
final CompletableFuture<PasteUtil.PasteResult> future = PasteUtil.createPaste(files);
|
||||
future.thenAccept(result -> {
|
||||
if (result != null) {
|
||||
@@ -375,7 +441,7 @@ public class Commandessentials extends EssentialsCommand {
|
||||
private void runMoo(final Server server, final CommandSource sender, final String command, final String[] args) {
|
||||
if (args.length == 2 && args[1].equals("moo")) {
|
||||
for (final String s : CONSOLE_MOO) {
|
||||
logger.info(s);
|
||||
ess.getLogger().info(s);
|
||||
}
|
||||
for (final Player player : ess.getOnlinePlayers()) {
|
||||
player.sendMessage(PLAYER_MOO);
|
||||
@@ -646,6 +712,9 @@ public class Commandessentials extends EssentialsCommand {
|
||||
case DANGEROUS_FORK:
|
||||
sender.sendMessage(ChatColor.DARK_RED + tl("serverUnsupportedDangerous"));
|
||||
break;
|
||||
case STUPID_PLUGIN:
|
||||
sender.sendMessage(ChatColor.DARK_RED + tl("serverUnsupportedDumbPlugins"));
|
||||
break;
|
||||
case UNSTABLE:
|
||||
sender.sendMessage(ChatColor.DARK_RED + tl("serverUnsupportedMods"));
|
||||
break;
|
||||
@@ -719,9 +788,9 @@ public class Commandessentials extends EssentialsCommand {
|
||||
}
|
||||
break;
|
||||
case "dump":
|
||||
final List<String> list = Lists.newArrayList("config", "kits", "log", "discord", "*");
|
||||
final List<String> list = Lists.newArrayList("config", "kits", "log", "discord", "worth", "tpr", "spawns", "commands", "all");
|
||||
for (String arg : args) {
|
||||
if (arg.equals("*")) {
|
||||
if (arg.equals("*") || arg.equalsIgnoreCase("all")) {
|
||||
list.clear();
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Server;
|
||||
@@ -57,7 +56,7 @@ public class Commandgc extends EssentialsCommand {
|
||||
tileEntities += chunk.getTileEntities().length;
|
||||
}
|
||||
} catch (final java.lang.ClassCastException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Corrupted chunk data on world " + w, ex);
|
||||
ess.getLogger().log(Level.SEVERE, "Corrupted chunk data on world " + w, ex);
|
||||
}
|
||||
|
||||
sender.sendMessage(tl("gcWorld", worldType, w.getName(), w.getLoadedChunks().length, w.getEntities().size(), tileEntities));
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
@@ -37,7 +38,7 @@ public class Commandgive extends EssentialsLoopCommand {
|
||||
}
|
||||
|
||||
try {
|
||||
if (args.length > 3 && NumberUtil.isInt(args[2]) && NumberUtil.isInt(args[3])) {
|
||||
if (args.length > 3 && VersionUtil.PRE_FLATTENING && NumberUtil.isInt(args[2]) && NumberUtil.isInt(args[3])) {
|
||||
stack.setAmount(Integer.parseInt(args[2]));
|
||||
stack.setDurability(Short.parseShort(args[3]));
|
||||
} else if (args.length > 2 && Integer.parseInt(args[2]) > 0) {
|
||||
|
||||
@@ -40,7 +40,7 @@ public class Commandice extends EssentialsLoopCommand {
|
||||
@Override
|
||||
protected void updatePlayer(Server server, CommandSource sender, User user, String[] args) throws NotEnoughArgumentsException, PlayerExemptException, ChargeException, MaxMoneyException {
|
||||
freezePlayer(user);
|
||||
user.sendMessage(tl("iceOther", user.getDisplayName()));
|
||||
sender.sendMessage(tl("iceOther", user.getDisplayName()));
|
||||
}
|
||||
|
||||
private void freezePlayer(final IUser user) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Material;
|
||||
@@ -36,7 +37,7 @@ public class Commanditemdb extends EssentialsCommand {
|
||||
|
||||
String itemId = "none";
|
||||
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
itemId = itemStack.getType().getId() + ":" + itemStack.getDurability();
|
||||
}
|
||||
|
||||
@@ -49,7 +50,7 @@ public class Commanditemdb extends EssentialsCommand {
|
||||
|
||||
if (itemHeld && itemStack.getType() != Material.AIR) {
|
||||
final int maxuses = itemStack.getType().getMaxDurability();
|
||||
final int durability = (maxuses + 1) - itemStack.getDurability();
|
||||
final int durability = (maxuses + 1) - MaterialUtil.getDamage(itemStack);
|
||||
if (maxuses != 0) {
|
||||
sender.sendMessage(tl("durability", Integer.toString(durability)));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.Kit;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.config.ConfigurateUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
@@ -101,7 +100,7 @@ public class Commandkit extends EssentialsCommand {
|
||||
if (args.length == 1) {
|
||||
final List<String> options = new ArrayList<>();
|
||||
// TODO: Move all of this to its own method
|
||||
for (final String kitName : ConfigurateUtil.getKeys(ess.getKits().getKits())) {
|
||||
for (final String kitName : ess.getKits().getKitKeys()) {
|
||||
if (!user.isAuthorized("essentials.kits." + kitName)) { // Only check perm, not time or money
|
||||
continue;
|
||||
}
|
||||
@@ -118,7 +117,7 @@ public class Commandkit extends EssentialsCommand {
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return new ArrayList<>(ConfigurateUtil.getKeys(ess.getKits().getKits())); // TODO: Move this to its own method
|
||||
return new ArrayList<>(ess.getKits().getKitKeys()); // TODO: Move this to its own method
|
||||
} else if (args.length == 2) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.config.ConfigurateUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -59,7 +58,7 @@ public class Commandkitreset extends EssentialsCommand {
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return new ArrayList<>(ConfigurateUtil.getKeys(ess.getKits().getKits()));
|
||||
return new ArrayList<>(ess.getKits().getKitKeys());
|
||||
} else if (args.length == 2 && sender.isAuthorized("essentials.kitreset.others", ess)) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
|
||||
@@ -152,7 +152,19 @@ public class Commandmail extends EssentialsCommand {
|
||||
if (!user.isAuthorized("essentials.mail.sendall")) {
|
||||
throw new Exception(tl("noPerm", "essentials.mail.sendall"));
|
||||
}
|
||||
ess.runTaskAsynchronously(new SendAll(user, FormatUtil.formatMessage(user, "essentials.mail", StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 1))))));
|
||||
ess.runTaskAsynchronously(new SendAll(user,
|
||||
FormatUtil.formatMessage(user, "essentials.mail",
|
||||
StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 1)))), 0));
|
||||
user.sendMessage(tl("mailSent"));
|
||||
return;
|
||||
}
|
||||
if (args.length >= 3 && "sendtempall".equalsIgnoreCase(args[0])) {
|
||||
if (!user.isAuthorized("essentials.mail.sendtempall")) {
|
||||
throw new Exception(tl("noPerm", "essentials.mail.sendtempall"));
|
||||
}
|
||||
ess.runTaskAsynchronously(new SendAll(user,
|
||||
FormatUtil.formatMessage(user, "essentials.mail",
|
||||
StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 2)))), DateUtil.parseDateDiff(args[1], true)));
|
||||
user.sendMessage(tl("mailSent"));
|
||||
return;
|
||||
}
|
||||
@@ -213,7 +225,12 @@ public class Commandmail extends EssentialsCommand {
|
||||
sender.sendMessage(tl("mailSent"));
|
||||
return;
|
||||
} else if (args.length >= 2 && "sendall".equalsIgnoreCase(args[0])) {
|
||||
ess.runTaskAsynchronously(new SendAll(Console.getInstance(), FormatUtil.replaceFormat(getFinalArg(args, 1))));
|
||||
ess.runTaskAsynchronously(new SendAll(Console.getInstance(), FormatUtil.replaceFormat(getFinalArg(args, 1)), 0));
|
||||
sender.sendMessage(tl("mailSent"));
|
||||
return;
|
||||
} else if (args.length >= 3 && "sendtempall".equalsIgnoreCase(args[0])) {
|
||||
final long dateDiff = DateUtil.parseDateDiff(args[1], true);
|
||||
ess.runTaskAsynchronously(new SendAll(Console.getInstance(), FormatUtil.replaceFormat(getFinalArg(args, 2)), dateDiff));
|
||||
sender.sendMessage(tl("mailSent"));
|
||||
return;
|
||||
} else if (args.length >= 2) {
|
||||
@@ -232,12 +249,14 @@ public class Commandmail extends EssentialsCommand {
|
||||
}
|
||||
|
||||
private class SendAll implements Runnable {
|
||||
IMessageRecipient messageRecipient;
|
||||
String message;
|
||||
private final IMessageRecipient messageRecipient;
|
||||
private final String message;
|
||||
private final long dateDiff;
|
||||
|
||||
SendAll(IMessageRecipient messageRecipient, String message) {
|
||||
SendAll(IMessageRecipient messageRecipient, String message, long dateDiff) {
|
||||
this.messageRecipient = messageRecipient;
|
||||
this.message = message;
|
||||
this.dateDiff = dateDiff;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -245,7 +264,7 @@ public class Commandmail extends EssentialsCommand {
|
||||
for (UUID userid : ess.getUserMap().getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(userid);
|
||||
if (user != null) {
|
||||
user.sendMail(messageRecipient, message);
|
||||
user.sendMail(messageRecipient, message, dateDiff);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,38 +283,47 @@ public class Commandmail extends EssentialsCommand {
|
||||
if (user.isAuthorized("essentials.mail.sendall")) {
|
||||
options.add("sendall");
|
||||
}
|
||||
if (user.isAuthorized("essentials.mail.sendtempall")) {
|
||||
options.add("sendtempall");
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2 && ((args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) || (args[0].equalsIgnoreCase("sendtemp") && user.isAuthorized("essentials.mail.sendtemp")))) {
|
||||
return getPlayers(server, user);
|
||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("read")) {
|
||||
final ArrayList<MailMessage> mail = user.getMailMessages();
|
||||
final int pages = mail != null ? (mail.size() / 9 + (mail.size() % 9 > 0 ? 1 : 0)) : 0;
|
||||
if (pages == 0) {
|
||||
return Lists.newArrayList("0");
|
||||
} else {
|
||||
final List<String> options = Lists.newArrayList("1");
|
||||
if (pages > 1) {
|
||||
options.add(String.valueOf(pages));
|
||||
} else if (args.length == 2) {
|
||||
if ((args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) || (args[0].equalsIgnoreCase("sendtemp") && user.isAuthorized("essentials.mail.sendtemp"))) {
|
||||
return getPlayers(server, user);
|
||||
} else if (args[0].equalsIgnoreCase("sendtempall") && user.isAuthorized("essentials.mail.sendtempall")) {
|
||||
return COMMON_DATE_DIFFS;
|
||||
} else if (args[0].equalsIgnoreCase("read")) {
|
||||
final ArrayList<MailMessage> mail = user.getMailMessages();
|
||||
final int pages = mail != null ? (mail.size() / 9 + (mail.size() % 9 > 0 ? 1 : 0)) : 0;
|
||||
if (pages == 0) {
|
||||
return Lists.newArrayList("0");
|
||||
} else {
|
||||
final List<String> options = Lists.newArrayList("1");
|
||||
if (pages > 1) {
|
||||
options.add(String.valueOf(pages));
|
||||
}
|
||||
return options;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
} else if (args.length == 3 && args[0].equalsIgnoreCase("sendtemp") && user.isAuthorized("essentials.mail.sendtemp")) {
|
||||
return COMMON_DATE_DIFFS;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("send", "sendall");
|
||||
} else if (args.length == 2 && (args[0].equalsIgnoreCase("send") || args[0].equalsIgnoreCase("sendtemp"))) {
|
||||
return getPlayers(server, sender);
|
||||
return Lists.newArrayList("send", "sendall", "sendtemp", "sendtempall");
|
||||
} else if (args.length == 2) {
|
||||
if (args[0].equalsIgnoreCase("send") || args[0].equalsIgnoreCase("sendtemp")) {
|
||||
return getPlayers(server, sender);
|
||||
} else if (args[0].equalsIgnoreCase("sendtempall")) {
|
||||
return COMMON_DATE_DIFFS;
|
||||
}
|
||||
} else if (args.length == 3 && args[0].equalsIgnoreCase("sendtemp")) {
|
||||
return COMMON_DATE_DIFFS;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import net.essentialsx.api.v2.events.UserActionEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
@@ -44,6 +45,7 @@ public class Commandme extends EssentialsCommand {
|
||||
final String toSend = tl("action", user.getDisplayName(), message);
|
||||
if (radius < 1) {
|
||||
ess.broadcastMessage(user, toSend);
|
||||
ess.getServer().getPluginManager().callEvent(new UserActionEvent(user, message, Collections.unmodifiableCollection(ess.getServer().getOnlinePlayers())));
|
||||
return;
|
||||
}
|
||||
radius *= radius;
|
||||
@@ -86,6 +88,7 @@ public class Commandme extends EssentialsCommand {
|
||||
for (final Player onlinePlayer : outList) {
|
||||
onlinePlayer.sendMessage(toSend);
|
||||
}
|
||||
ess.getServer().getPluginManager().callEvent(new UserActionEvent(user, message, Collections.unmodifiableCollection(outList)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
@@ -109,7 +108,7 @@ public class Commandnear extends EssentialsCommand {
|
||||
if (nearbyPlayer == null) {
|
||||
continue;
|
||||
}
|
||||
output.append(nearbyPlayer.getDisplayName()).append(ChatColor.WHITE + "(" + ChatColor.RED).append((long) nearbyPlayer.getLocation().distance(loc)).append("m" + ChatColor.WHITE + ")");
|
||||
output.append(tl("nearbyPlayersList", nearbyPlayer.getDisplayName(), (long)nearbyPlayer.getLocation().distance(loc)));
|
||||
}
|
||||
|
||||
return output.length() > 1 ? output.toString() : tl("none");
|
||||
|
||||
@@ -24,9 +24,6 @@ public class Commandnick extends EssentialsLoopCommand {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
if (!ess.getSettings().changeDisplayName()) {
|
||||
throw new Exception(tl("nickDisplayName"));
|
||||
}
|
||||
|
||||
if (args.length > 1 && user.isAuthorized("essentials.nick.others")) {
|
||||
loopOfflinePlayers(server, user.getSource(), false, true, args[0], formatNickname(user, args[1]).split(" "));
|
||||
@@ -41,9 +38,6 @@ public class Commandnick extends EssentialsLoopCommand {
|
||||
if (args.length < 2) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
if (!ess.getSettings().changeDisplayName()) {
|
||||
throw new Exception(tl("nickDisplayName"));
|
||||
}
|
||||
loopOfflinePlayers(server, sender, false, true, args[0], formatNickname(null, args[1]).split(" "));
|
||||
sender.sendMessage(tl("nickChanged"));
|
||||
}
|
||||
@@ -59,12 +53,12 @@ public class Commandnick extends EssentialsLoopCommand {
|
||||
if (!target.getDisplayName().equalsIgnoreCase(target.getDisplayName())) {
|
||||
target.sendMessage(tl("nickNoMore"));
|
||||
}
|
||||
target.sendMessage(tl("nickSet", target.getDisplayName()));
|
||||
target.sendMessage(tl("nickSet", ess.getSettings().changeDisplayName() ? target.getDisplayName() : nick));
|
||||
} else if (nickInUse(target, nick)) {
|
||||
throw new NotEnoughArgumentsException(tl("nickInUse"));
|
||||
} else {
|
||||
setNickname(server, sender, target, nick);
|
||||
target.sendMessage(tl("nickSet", target.getDisplayName()));
|
||||
target.sendMessage(tl("nickSet", ess.getSettings().changeDisplayName() ? target.getDisplayName() : nick));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +70,7 @@ public class Commandnick extends EssentialsLoopCommand {
|
||||
throw new Exception(tl("nickTooLong"));
|
||||
} else if (FormatUtil.stripFormat(newNick).length() < 1) {
|
||||
throw new Exception(tl("nickNamesAlpha"));
|
||||
} else if (user != null && user.isAuthorized("essentials.nick.changecolors") && !user.isAuthorized("essentials.nick.changecolors.bypass") && !FormatUtil.stripFormat(newNick).equals(user.getName())) {
|
||||
} else if (user != null && user.isAuthorized("essentials.nick.changecolors") && !user.isAuthorized("essentials.nick.changecolors.bypass") && !FormatUtil.stripFormat(newNick).equals(user.getName()) && !nick.equalsIgnoreCase("off")) {
|
||||
throw new Exception(tl("nickNamesOnlyColorChanges"));
|
||||
} else if (user != null && !user.isAuthorized("essentials.nick.blacklist.bypass") && isNickBanned(newNick)) {
|
||||
throw new Exception(tl("nickNameBlacklist", nick));
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.IUser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.Statistic;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandplaytime extends EssentialsCommand {
|
||||
// For some reason, in 1.13 PLAY_ONE_MINUTE = ticks played = what used to be PLAY_ONE_TICK
|
||||
// https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/b848d8ce633871b52115247b089029749c02f579
|
||||
private static final Statistic PLAY_ONE_TICK = EnumUtil.getStatistic("PLAY_ONE_MINUTE", "PLAY_ONE_TICK");
|
||||
|
||||
public Commandplaytime() {
|
||||
super("playtime");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
|
||||
String displayName;
|
||||
long playtime;
|
||||
final String key;
|
||||
|
||||
if (args.length > 0 && sender.isAuthorized("essentials.playtime.others", ess)) {
|
||||
try {
|
||||
final IUser user = getPlayer(server, sender, args, 0);
|
||||
displayName = user.getDisplayName();
|
||||
playtime = user.getBase().getStatistic(PLAY_ONE_TICK);
|
||||
} catch (PlayerNotFoundException e) {
|
||||
// The ability to get the statistics of offline players is only available in 1.15.2+
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_15_2_R01)) {
|
||||
throw e;
|
||||
}
|
||||
final User user = getPlayer(server, args, 0, true, true);
|
||||
displayName = user.getName(); // Vanished players will have their name as their display name
|
||||
playtime = Bukkit.getOfflinePlayer(user.getBase().getUniqueId()).getStatistic(PLAY_ONE_TICK);
|
||||
if (user.getBase().isOnline() && user.isVanished()) {
|
||||
playtime = playtime - ((System.currentTimeMillis() - user.getLastVanishTime()) / 50L);
|
||||
}
|
||||
}
|
||||
key = "playtimeOther";
|
||||
} else if (sender.isPlayer()) {
|
||||
//noinspection ConstantConditions
|
||||
displayName = sender.getPlayer().getDisplayName();
|
||||
playtime = sender.getPlayer().getStatistic(PLAY_ONE_TICK);
|
||||
key = "playtime";
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final long playtimeMs = System.currentTimeMillis() - (playtime * 50L);
|
||||
sender.sendMessage(tl(key, DateUtil.formatDateDiff(playtimeMs), displayName));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1 && sender.isAuthorized("essentials.playtime.others", ess)) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.Potions;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -42,7 +42,7 @@ public class Commandpotion extends EssentialsCommand {
|
||||
}
|
||||
|
||||
boolean holdingPotion = stack.getType() == Material.POTION;
|
||||
if (!holdingPotion && ReflUtil.getNmsVersionObject().isHigherThanOrEqualTo(ReflUtil.V1_9_R1)) {
|
||||
if (!holdingPotion && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01)) {
|
||||
holdingPotion = stack.getType() == Material.SPLASH_POTION || stack.getType() == Material.LINGERING_POTION;
|
||||
}
|
||||
if (holdingPotion) {
|
||||
|
||||
@@ -117,7 +117,7 @@ public class Commandrecipe extends EssentialsCommand {
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
if (item.getDurability() == Short.MAX_VALUE) {
|
||||
if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) {
|
||||
item.setDurability((short) 0);
|
||||
}
|
||||
view.getTopInventory().setItem(j * 3 + k + 1, item);
|
||||
@@ -159,7 +159,7 @@ public class Commandrecipe extends EssentialsCommand {
|
||||
final InventoryView view = user.getBase().openWorkbench(null, true);
|
||||
for (int i = 0; i < ingredients.size(); i++) {
|
||||
final ItemStack item = ingredients.get(i);
|
||||
if (item.getDurability() == Short.MAX_VALUE) {
|
||||
if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) {
|
||||
item.setDurability((short) 0);
|
||||
}
|
||||
view.setItem(i + 1, item);
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.earth2me.essentials.commands;
|
||||
import com.earth2me.essentials.ChargeException;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -39,7 +40,7 @@ public class Commandrepair extends EssentialsCommand {
|
||||
|
||||
public void repairHand(final User user) throws Exception {
|
||||
final ItemStack item = user.getItemInHand();
|
||||
if (item == null || item.getType().isBlock() || item.getDurability() == 0) {
|
||||
if (item == null || item.getType().isBlock() || MaterialUtil.getDamage(item) == 0) {
|
||||
throw new Exception(tl("repairInvalidType"));
|
||||
}
|
||||
|
||||
@@ -81,16 +82,16 @@ public class Commandrepair extends EssentialsCommand {
|
||||
throw new Exception(tl("repairInvalidType"));
|
||||
}
|
||||
|
||||
if (item.getDurability() == 0) {
|
||||
if (MaterialUtil.getDamage(item) == 0) {
|
||||
throw new Exception(tl("repairAlreadyFixed"));
|
||||
}
|
||||
|
||||
item.setDurability((short) 0);
|
||||
MaterialUtil.setDamage(item, 0);
|
||||
}
|
||||
|
||||
private void repairItems(final ItemStack[] items, final IUser user, final List<String> repaired) throws Exception {
|
||||
private void repairItems(final ItemStack[] items, final IUser user, final List<String> repaired) {
|
||||
for (final ItemStack item : items) {
|
||||
if (item == null || item.getType().isBlock() || item.getDurability() == 0) {
|
||||
if (item == null || item.getType().isBlock() || MaterialUtil.getDamage(item) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -123,7 +124,7 @@ public class Commandrepair extends EssentialsCommand {
|
||||
|
||||
private Trade getCharge(final Material material) {
|
||||
final String itemName = material.toString().toLowerCase(Locale.ENGLISH);
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
final int itemId = material.getId();
|
||||
return new Trade("repair-" + itemName.replace('_', '-'), new Trade("repair-" + itemId, new Trade("repair-item", ess), ess), ess);
|
||||
} else {
|
||||
|
||||
@@ -19,7 +19,7 @@ public class Commandrest extends EssentialsLoopCommand {
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
sender.sendMessage(tl("unsupportedFeature"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,13 +102,16 @@ public class Commandseen extends EssentialsCommand {
|
||||
|
||||
user.setDisplayNick();
|
||||
sender.sendMessage(tl("seenOnline", user.getDisplayName(), DateUtil.formatDateDiff(user.getLastLogin())));
|
||||
sender.sendMessage(tl("whoisUuid", user.getBase().getUniqueId().toString()));
|
||||
|
||||
final List<String> history = ess.getUserMap().getUserHistory(user.getBase().getUniqueId());
|
||||
if (history != null && history.size() > 1) {
|
||||
sender.sendMessage(tl("seenAccounts", StringUtil.joinListSkip(", ", user.getName(), history)));
|
||||
}
|
||||
|
||||
if (sender.isAuthorized("essentials.seen.uuid", ess)) {
|
||||
sender.sendMessage(tl("whoisUuid", user.getBase().getUniqueId().toString()));
|
||||
}
|
||||
|
||||
if (user.isAfk()) {
|
||||
sender.sendMessage(tl("whoisAFK", tl("true")));
|
||||
}
|
||||
@@ -136,16 +139,18 @@ public class Commandseen extends EssentialsCommand {
|
||||
user.setDisplayNick();
|
||||
if (user.getLastLogout() > 0) {
|
||||
sender.sendMessage(tl("seenOffline", user.getName(), DateUtil.formatDateDiff(user.getLastLogout())));
|
||||
sender.sendMessage(tl("whoisUuid", user.getBase().getUniqueId()));
|
||||
final List<String> history = ess.getUserMap().getUserHistory(user.getBase().getUniqueId());
|
||||
if (history != null && history.size() > 1) {
|
||||
sender.sendMessage(tl("seenAccounts", StringUtil.joinListSkip(", ", user.getName(), history)));
|
||||
}
|
||||
|
||||
if (sender.isAuthorized("essentials.seen.uuid", ess)) {
|
||||
sender.sendMessage(tl("whoisUuid", user.getBase().getUniqueId()));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(tl("userUnknown", user.getName()));
|
||||
}
|
||||
|
||||
final List<String> history = ess.getUserMap().getUserHistory(user.getBase().getUniqueId());
|
||||
if (history != null && history.size() > 1) {
|
||||
sender.sendMessage(tl("seenAccounts", StringUtil.joinListSkip(", ", user.getName(), history)));
|
||||
}
|
||||
|
||||
if (BanLookup.isBanned(ess, user)) {
|
||||
final BanEntry banEntry = BanLookup.getBanEntry(ess, user.getName());
|
||||
final String reason = showBan ? banEntry.getReason() : tl("true");
|
||||
|
||||
@@ -117,7 +117,7 @@ public class Commandsell extends EssentialsCommand {
|
||||
Trade.log("Command", "Sell", "Item", user.getName(), new Trade(ris, ess), user.getName(), new Trade(result, ess), user.getLocation(), user.getMoney(), ess);
|
||||
user.giveMoney(result, null, UserBalanceUpdateEvent.Cause.COMMAND_SELL);
|
||||
user.sendMessage(tl("itemSold", NumberUtil.displayCurrency(result, ess), amount, is.getType().toString().toLowerCase(Locale.ENGLISH), NumberUtil.displayCurrency(worth, ess)));
|
||||
logger.log(Level.INFO, tl("itemSoldConsole", user.getName(), is.getType().toString().toLowerCase(Locale.ENGLISH), NumberUtil.displayCurrency(result, ess), amount, NumberUtil.displayCurrency(worth, ess), user.getDisplayName()));
|
||||
ess.getLogger().log(Level.INFO, tl("itemSoldConsole", user.getName(), is.getType().toString().toLowerCase(Locale.ENGLISH), NumberUtil.displayCurrency(result, ess), amount, NumberUtil.displayCurrency(worth, ess), user.getDisplayName()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public class Commandsethome extends EssentialsCommand {
|
||||
}
|
||||
|
||||
final Location location = user.getLocation();
|
||||
if (!ess.getSettings().isTeleportSafetyEnabled() && LocationUtil.isBlockUnsafeForUser(usersHome, location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ())) {
|
||||
if ((!ess.getSettings().isTeleportSafetyEnabled() || !ess.getSettings().isForceDisableTeleportSafety()) && LocationUtil.isBlockUnsafeForUser(ess, usersHome, location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ())) {
|
||||
throw new Exception(tl("unsafeTeleportDestination", location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.Kit;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.config.ConfigurateUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -34,7 +33,7 @@ public class Commandshowkit extends EssentialsCommand {
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return new ArrayList<>(ConfigurateUtil.getKeys(ess.getKits().getKits())); // TODO: Move this to its own method
|
||||
return new ArrayList<>(ess.getKits().getKitKeys()); // TODO: Move this to its own method
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class Commandskull extends EssentialsCommand {
|
||||
final SkullMeta metaSkull;
|
||||
boolean spawn = false;
|
||||
|
||||
if (itemSkull != null && MaterialUtil.isPlayerHead(itemSkull.getType(), itemSkull.getDurability())) {
|
||||
if (itemSkull != null && MaterialUtil.isPlayerHead(itemSkull)) {
|
||||
metaSkull = (SkullMeta) itemSkull.getItemMeta();
|
||||
} else if (user.isAuthorized("essentials.skull.spawn")) {
|
||||
itemSkull = new ItemStack(SKULL_ITEM, 1, (byte) 3);
|
||||
|
||||
@@ -15,6 +15,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
@@ -84,6 +85,10 @@ public class Commandtogglejail extends EssentialsCommand {
|
||||
player.setOnlineJailedTime(ess.getSettings().isJailOnlineTime() ? ((player.getBase().getStatistic(PLAY_ONE_TICK)) + (timeDiff / 50)) : 0);
|
||||
}
|
||||
sender.sendMessage(timeDiff > 0 ? tl("playerJailedFor", player.getName(), DateUtil.formatDateDiff(finalDisplayTime)) : tl("playerJailed", player.getName()));
|
||||
|
||||
final String notifyMessage = timeDiff > 0 ? tl("jailNotifyJailedFor", player.getName(), DateUtil.formatDateDiff(finalDisplayTime), sender.getSender().getName()) : tl("jailNotifyJailed", player.getName(), sender.getSender().getName());
|
||||
server.getLogger().log(Level.INFO, notifyMessage);
|
||||
ess.broadcastMessage("essentials.jail.notify", notifyMessage);
|
||||
}
|
||||
});
|
||||
if (player.getBase().isOnline()) {
|
||||
@@ -107,6 +112,10 @@ public class Commandtogglejail extends EssentialsCommand {
|
||||
player.setJailTimeout(timeDiff);
|
||||
player.setOnlineJailedTime(ess.getSettings().isJailOnlineTime() ? ((player.getBase().getStatistic(PLAY_ONE_TICK)) + (timeDiff / 50)) : 0);
|
||||
sender.sendMessage(tl("jailSentenceExtended", DateUtil.formatDateDiff(displayTimeDiff)));
|
||||
|
||||
final String notifyMessage = tl("jailNotifySentenceExtended", player.getName(), DateUtil.formatDateDiff(displayTimeDiff), sender.getSender().getName());
|
||||
server.getLogger().log(Level.INFO, notifyMessage);
|
||||
ess.broadcastMessage("essentials.jail.notify", notifyMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,13 +22,14 @@ public class Commandtop extends EssentialsCommand {
|
||||
final int topZ = user.getLocation().getBlockZ();
|
||||
final float pitch = user.getLocation().getPitch();
|
||||
final float yaw = user.getLocation().getYaw();
|
||||
final Location loc = LocationUtil.getSafeDestination(new Location(user.getWorld(), topX, user.getWorld().getMaxHeight(), topZ, yaw, pitch));
|
||||
final Location unsafe = new Location(user.getWorld(), topX, ess.getWorldInfoProvider().getMaxHeight(user.getWorld()), topZ, yaw, pitch);
|
||||
final Location safe = LocationUtil.getSafeDestination(ess, unsafe);
|
||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
user.sendMessage(tl("teleportTop", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
user.sendMessage(tl("teleportTop", safe.getWorld().getName(), safe.getBlockX(), safe.getBlockY(), safe.getBlockZ()));
|
||||
}
|
||||
});
|
||||
user.getAsyncTeleport().teleport(loc, new Trade(this.getName(), ess), TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel));
|
||||
user.getAsyncTeleport().teleport(safe, new Trade(this.getName(), ess), TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel));
|
||||
}
|
||||
}
|
||||
@@ -37,11 +37,12 @@ public class Commandtpa extends EssentialsCommand {
|
||||
if (user.getWorld() != player.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + player.getWorld().getName())) {
|
||||
throw new Exception(tl("noPerm", "essentials.worlds." + player.getWorld().getName()));
|
||||
}
|
||||
|
||||
// Don't let sender request teleport twice to the same player.
|
||||
if (user.getConfigUUID().equals(player.getTeleportRequest()) && player.hasOutstandingTeleportRequest() // Check timeout
|
||||
&& !player.isTpRequestHere()) { // Make sure the last teleport request was actually tpa and not tpahere
|
||||
if (player.hasOutstandingTpaRequest(user.getName(), false)) {
|
||||
throw new Exception(tl("requestSentAlready", player.getDisplayName()));
|
||||
}
|
||||
|
||||
if (player.isAutoTeleportEnabled() && !player.isIgnoredPlayer(user)) {
|
||||
final Trade charge = new Trade(this.getName(), ess);
|
||||
final AsyncTeleport teleport = user.getAsyncTeleport();
|
||||
@@ -54,7 +55,7 @@ public class Commandtpa extends EssentialsCommand {
|
||||
user.sendMessage(tl("requestAcceptedFromAuto", player.getDisplayName()));
|
||||
}
|
||||
});
|
||||
return;
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
if (!player.isIgnoredPlayer(user)) {
|
||||
@@ -71,6 +72,7 @@ public class Commandtpa extends EssentialsCommand {
|
||||
player.sendMessage(tl("teleportRequestTimeoutInfo", ess.getSettings().getTpaAcceptCancellation()));
|
||||
}
|
||||
}
|
||||
|
||||
user.sendMessage(tl("requestSent", player.getDisplayName()));
|
||||
if (user.isAuthorized("essentials.tpacancel")) {
|
||||
user.sendMessage(tl("typeTpacancel"));
|
||||
|
||||
@@ -19,17 +19,17 @@ public class Commandtpaall extends EssentialsCommand {
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
if (sender.isPlayer()) {
|
||||
teleportAAllPlayers(server, sender, ess.getUser(sender.getPlayer()));
|
||||
tpaAll(sender, ess.getUser(sender.getPlayer()));
|
||||
return;
|
||||
}
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final User target = getPlayer(server, sender, args, 0);
|
||||
teleportAAllPlayers(server, sender, target);
|
||||
tpaAll(sender, target);
|
||||
}
|
||||
|
||||
private void teleportAAllPlayers(final Server server, final CommandSource sender, final User target) {
|
||||
private void tpaAll(final CommandSource sender, final User target) {
|
||||
sender.sendMessage(tl("teleportAAll"));
|
||||
for (final User player : ess.getOnlineUsers()) {
|
||||
if (target == player) {
|
||||
@@ -41,6 +41,7 @@ public class Commandtpaall extends EssentialsCommand {
|
||||
if (sender.getSender().equals(target.getBase()) && target.getWorld() != player.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !target.isAuthorized("essentials.worlds." + target.getWorld().getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
final TPARequestEvent tpaEvent = new TPARequestEvent(sender, player, true);
|
||||
ess.getServer().getPluginManager().callEvent(tpaEvent);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
@@ -15,20 +14,12 @@ public class Commandtpacancel extends EssentialsCommand {
|
||||
/**
|
||||
* Cancel {@link User}'s tp request if its {@code requester} is equal to the given {@code requester}.
|
||||
*
|
||||
* @param ess ess instance
|
||||
* @param user user holding tp request
|
||||
* @param requester tp requester
|
||||
* @return whether tp was cancelled
|
||||
*/
|
||||
public static boolean cancelTeleportRequest(final IEssentials ess, final User user, final User requester) throws Exception {
|
||||
if (user.getTeleportRequest() != null) {
|
||||
final User userRequester = ess.getUser(user.getTeleportRequest());
|
||||
if (requester.equals(userRequester)) {
|
||||
user.requestTeleport(null, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public static boolean cancelTeleportRequest(final User user, final User requester) {
|
||||
return user.removeTpaRequest(requester.getName()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,7 +28,7 @@ public class Commandtpacancel extends EssentialsCommand {
|
||||
int cancellations = 0;
|
||||
for (final User onlineUser : ess.getOnlineUsers()) {
|
||||
if (onlineUser == user) continue;
|
||||
if (cancelTeleportRequest(ess, onlineUser, user)) {
|
||||
if (cancelTeleportRequest(onlineUser, user)) {
|
||||
cancellations++;
|
||||
}
|
||||
}
|
||||
@@ -48,7 +39,7 @@ public class Commandtpacancel extends EssentialsCommand {
|
||||
}
|
||||
} else {
|
||||
final User targetPlayer = getPlayer(server, user, args, 0);
|
||||
if (cancelTeleportRequest(ess, targetPlayer, user)) {
|
||||
if (cancelTeleportRequest(targetPlayer, user)) {
|
||||
user.sendMessage(tl("teleportRequestSpecificCancelled", targetPlayer.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.AsyncTeleport;
|
||||
import com.earth2me.essentials.IUser;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import net.essentialsx.api.v2.events.TeleportRequestResponseEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
@@ -18,36 +24,87 @@ public class Commandtpaccept extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final User requester;
|
||||
try {
|
||||
requester = ess.getUser(user.getTeleportRequest());
|
||||
} catch (final Exception ex) {
|
||||
final boolean acceptAll;
|
||||
if (args.length > 0) {
|
||||
acceptAll = args[0].equals("*") || args[0].equalsIgnoreCase("all");
|
||||
} else {
|
||||
acceptAll = false;
|
||||
}
|
||||
|
||||
if (!user.hasPendingTpaRequests(true, acceptAll)) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (args.length > 0) {
|
||||
if (acceptAll) {
|
||||
acceptAllRequests(user, commandLabel);
|
||||
throw new NoChargeException();
|
||||
}
|
||||
user.sendMessage(tl("requestAccepted"));
|
||||
handleTeleport(user, user.getOutstandingTpaRequest(getPlayer(server, user, args, 0).getName(), true), commandLabel);
|
||||
} else {
|
||||
user.sendMessage(tl("requestAccepted"));
|
||||
handleTeleport(user, user.getNextTpaRequest(true, false, false), commandLabel);
|
||||
}
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
private void acceptAllRequests(final User user, final String commandLabel) throws Exception {
|
||||
IUser.TpaRequest request;
|
||||
int count = 0;
|
||||
while ((request = user.getNextTpaRequest(true, true, true)) != null) {
|
||||
try {
|
||||
handleTeleport(user, request, commandLabel);
|
||||
count++;
|
||||
} catch (Exception e) {
|
||||
ess.showError(user.getSource(), e, commandLabel);
|
||||
} finally {
|
||||
user.removeTpaRequest(request.getName());
|
||||
}
|
||||
}
|
||||
user.sendMessage(tl("requestAcceptedAll", count));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
final List<String> options = new ArrayList<>(user.getPendingTpaKeys());
|
||||
options.add("*");
|
||||
return options;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTeleport(final User user, final IUser.TpaRequest request, String commandLabel) throws Exception {
|
||||
if (request == null) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
final User requester = ess.getUser(request.getRequesterUuid());
|
||||
|
||||
if (!requester.getBase().isOnline()) {
|
||||
user.removeTpaRequest(request.getName());
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (user.isTpRequestHere() && ((!requester.isAuthorized("essentials.tpahere") && !requester.isAuthorized("essentials.tpaall")) || (user.getWorld() != requester.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + user.getWorld().getName())))) {
|
||||
if (request.isHere() && ((!requester.isAuthorized("essentials.tpahere") && !requester.isAuthorized("essentials.tpaall")) || (user.getWorld() != requester.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + user.getWorld().getName())))) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (!user.isTpRequestHere() && (!requester.isAuthorized("essentials.tpa") || (user.getWorld() != requester.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + requester.getWorld().getName())))) {
|
||||
if (!request.isHere() && (!requester.isAuthorized("essentials.tpa") || (user.getWorld() != requester.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + requester.getWorld().getName())))) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (args.length > 0 && !requester.getName().contains(args[0])) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (!user.hasOutstandingTeleportRequest()) {
|
||||
user.requestTeleport(null, false);
|
||||
throw new Exception(tl("requestTimedOut"));
|
||||
final TeleportRequestResponseEvent event = new TeleportRequestResponseEvent(user, requester, request, true);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("TPA accept cancelled by API for " + user.getName() + " (requested by " + requester.getName() + ")");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final Trade charge = new Trade(this.getName(), ess);
|
||||
user.sendMessage(tl("requestAccepted"));
|
||||
requester.sendMessage(tl("requestAcceptedFrom", user.getDisplayName()));
|
||||
|
||||
final CompletableFuture<Boolean> future = getNewExceptionFuture(requester.getSource(), commandLabel);
|
||||
@@ -55,8 +112,8 @@ public class Commandtpaccept extends EssentialsCommand {
|
||||
user.sendMessage(tl("pendingTeleportCancelled"));
|
||||
return false;
|
||||
});
|
||||
if (user.isTpRequestHere()) {
|
||||
final Location loc = user.getTpRequestLocation();
|
||||
if (request.isHere()) {
|
||||
final Location loc = request.getLocation();
|
||||
final AsyncTeleport teleport = requester.getAsyncTeleport();
|
||||
teleport.setTpType(AsyncTeleport.TeleportType.TPA);
|
||||
future.thenAccept(success -> {
|
||||
@@ -64,14 +121,12 @@ public class Commandtpaccept extends EssentialsCommand {
|
||||
requester.sendMessage(tl("teleporting", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
}
|
||||
});
|
||||
teleport.teleportPlayer(user, user.getTpRequestLocation(), charge, TeleportCause.COMMAND, future);
|
||||
teleport.teleportPlayer(user, loc, charge, TeleportCause.COMMAND, future);
|
||||
} else {
|
||||
final AsyncTeleport teleport = requester.getAsyncTeleport();
|
||||
teleport.setTpType(AsyncTeleport.TeleportType.TPA);
|
||||
teleport.teleport(user.getBase(), charge, TeleportCause.COMMAND, future);
|
||||
}
|
||||
user.requestTeleport(null, false);
|
||||
throw new NoChargeException();
|
||||
user.removeTpaRequest(request.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,11 +33,12 @@ public class Commandtpahere extends EssentialsCommand {
|
||||
if (user.getWorld() != player.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + user.getWorld().getName())) {
|
||||
throw new Exception(tl("noPerm", "essentials.worlds." + user.getWorld().getName()));
|
||||
}
|
||||
|
||||
// Don't let sender request teleport twice to the same player.
|
||||
if (user.getConfigUUID().equals(player.getTeleportRequest()) && player.hasOutstandingTeleportRequest() // Check timeout
|
||||
&& player.isTpRequestHere()) { // Make sure the last teleport request was actually tpahere and not tpa
|
||||
if (player.hasOutstandingTpaRequest(user.getName(), true)) {
|
||||
throw new Exception(tl("requestSentAlready", player.getDisplayName()));
|
||||
}
|
||||
|
||||
if (!player.isIgnoredPlayer(user)) {
|
||||
final TPARequestEvent tpaEvent = new TPARequestEvent(user.getSource(), player, true);
|
||||
ess.getServer().getPluginManager().callEvent(tpaEvent);
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.IUser;
|
||||
import com.earth2me.essentials.User;
|
||||
import net.essentialsx.api.v2.events.TeleportRequestResponseEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandtpdeny extends EssentialsCommand {
|
||||
@@ -12,16 +19,84 @@ public class Commandtpdeny extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (user.getTeleportRequest() == null) {
|
||||
final boolean denyAll;
|
||||
if (args.length > 0) {
|
||||
denyAll = args[0].equals("*") || args[0].equalsIgnoreCase("all");
|
||||
} else {
|
||||
denyAll = false;
|
||||
}
|
||||
|
||||
if (!user.hasPendingTpaRequests(false, false)) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
final User player = ess.getUser(user.getTeleportRequest());
|
||||
if (player == null) {
|
||||
|
||||
final IUser.TpaRequest denyRequest;
|
||||
if (args.length > 0) {
|
||||
if (denyAll) {
|
||||
denyAllRequests(user);
|
||||
return;
|
||||
}
|
||||
denyRequest = user.getOutstandingTpaRequest(getPlayer(server, user, args, 0).getName(), false);
|
||||
} else {
|
||||
denyRequest = user.getNextTpaRequest(false, true, false);
|
||||
}
|
||||
|
||||
if (denyRequest == null) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
final User player = ess.getUser(denyRequest.getRequesterUuid());
|
||||
if (player == null || !player.getBase().isOnline()) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (sendEvent(user, player, denyRequest)) {
|
||||
return;
|
||||
}
|
||||
|
||||
user.sendMessage(tl("requestDenied"));
|
||||
player.sendMessage(tl("requestDeniedFrom", user.getDisplayName()));
|
||||
user.requestTeleport(null, false);
|
||||
user.removeTpaRequest(denyRequest.getName());
|
||||
}
|
||||
|
||||
private void denyAllRequests(User user) {
|
||||
IUser.TpaRequest request;
|
||||
int count = 0;
|
||||
while ((request = user.getNextTpaRequest(false, true, false)) != null) {
|
||||
final User player = ess.getUser(request.getRequesterUuid());
|
||||
|
||||
if (sendEvent(user, player, request)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player != null && player.getBase().isOnline()) {
|
||||
player.sendMessage(tl("requestDeniedFrom", user.getDisplayName()));
|
||||
}
|
||||
|
||||
user.removeTpaRequest(request.getName());
|
||||
count++;
|
||||
}
|
||||
user.sendMessage(tl("requestDeniedAll", count));
|
||||
}
|
||||
|
||||
private boolean sendEvent(User user, User player, IUser.TpaRequest request) {
|
||||
final TeleportRequestResponseEvent event = new TeleportRequestResponseEvent(user, player, request, false);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
final boolean cancelled = event.isCancelled();
|
||||
if (cancelled && ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("TPA deny cancelled by API for " + user.getName() + " (requested by " + player.getName() + ")");
|
||||
}
|
||||
return event.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
final List<String> options = new ArrayList<>(user.getPendingTpaKeys());
|
||||
options.add("*");
|
||||
return options;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,9 @@ public class Commandtppos extends EssentialsCommand {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final double x = args[0].startsWith("~") ? user.getLocation().getX() + (args[0].length() > 1 ? Integer.parseInt(args[0].substring(1)) : 0) : Integer.parseInt(args[0]);
|
||||
final double y = args[1].startsWith("~") ? user.getLocation().getY() + (args[1].length() > 1 ? Integer.parseInt(args[1].substring(1)) : 0) : Integer.parseInt(args[1]);
|
||||
final double z = args[2].startsWith("~") ? user.getLocation().getZ() + (args[2].length() > 1 ? Integer.parseInt(args[2].substring(1)) : 0) : Integer.parseInt(args[2]);
|
||||
final double x = args[0].startsWith("~") ? user.getLocation().getX() + (args[0].length() > 1 ? Double.parseDouble(args[0].substring(1)) : 0) : Double.parseDouble(args[0]);
|
||||
final double y = args[1].startsWith("~") ? user.getLocation().getY() + (args[1].length() > 1 ? Double.parseDouble(args[1].substring(1)) : 0) : Double.parseDouble(args[1]);
|
||||
final double z = args[2].startsWith("~") ? user.getLocation().getZ() + (args[2].length() > 1 ? Double.parseDouble(args[2].substring(1)) : 0) : Double.parseDouble(args[2]);
|
||||
final Location loc = new Location(user.getWorld(), x, y, z, user.getLocation().getYaw(), user.getLocation().getPitch());
|
||||
if (args.length == 4) {
|
||||
final World w = ess.getWorld(args[3]);
|
||||
|
||||
@@ -38,7 +38,7 @@ public class Commandtree extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
final Location loc = LocationUtil.getTarget(user.getBase()).add(0, 1, 0);
|
||||
final Location loc = LocationUtil.getTarget(user.getBase(), ess.getSettings().getMaxTreeCommandRange()).add(0, 1, 0);
|
||||
if (loc.getBlock().getType().isSolid()) {
|
||||
throw new Exception(tl("treeFailure"));
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
@@ -87,7 +88,7 @@ public class Commandworth extends EssentialsCommand {
|
||||
}
|
||||
|
||||
final BigDecimal result = worth.multiply(BigDecimal.valueOf(amount));
|
||||
sender.sendMessage(is.getDurability() != 0 ? tl("worthMeta", is.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", ""), is.getDurability(), NumberUtil.displayCurrency(result, ess), amount, NumberUtil.displayCurrency(worth, ess)) : tl("worth", is.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", ""), NumberUtil.displayCurrency(result, ess), amount, NumberUtil.displayCurrency(worth, ess)));
|
||||
sender.sendMessage(MaterialUtil.getDamage(is) != 0 ? tl("worthMeta", is.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", ""), MaterialUtil.getDamage(is), NumberUtil.displayCurrency(result, ess), amount, NumberUtil.displayCurrency(worth, ess)) : tl("worth", is.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", ""), NumberUtil.displayCurrency(result, ess), amount, NumberUtil.displayCurrency(worth, ess)));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,14 +26,12 @@ import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public abstract class EssentialsCommand implements IEssentialsCommand {
|
||||
protected static final Logger logger = Logger.getLogger("Essentials");
|
||||
/**
|
||||
* Common time durations (in seconds), for use in tab completion.
|
||||
*/
|
||||
@@ -112,11 +110,15 @@ public abstract class EssentialsCommand implements IEssentialsCommand {
|
||||
|
||||
// Get online players - only show vanished if source has permission
|
||||
protected User getPlayer(final Server server, final CommandSource sender, final String[] args, final int pos) throws PlayerNotFoundException, NotEnoughArgumentsException {
|
||||
return getPlayer(server, sender, args, pos, false);
|
||||
}
|
||||
|
||||
protected User getPlayer(final Server server, final CommandSource sender, final String[] args, final int pos, final boolean getOffline) throws PlayerNotFoundException, NotEnoughArgumentsException {
|
||||
if (sender.isPlayer()) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
return getPlayer(server, user, args, pos);
|
||||
return getPlayer(server, user, args, pos, getOffline);
|
||||
}
|
||||
return getPlayer(server, args, pos, true, false);
|
||||
return getPlayer(server, args, pos, true, getOffline);
|
||||
}
|
||||
|
||||
// Get online players - only show vanished if source has permission
|
||||
@@ -130,7 +132,11 @@ public abstract class EssentialsCommand implements IEssentialsCommand {
|
||||
|
||||
// Get online players - only show vanished if source has permission
|
||||
protected User getPlayer(final Server server, final User user, final String[] args, final int pos) throws PlayerNotFoundException, NotEnoughArgumentsException {
|
||||
return getPlayer(server, user, args, pos, user.canInteractVanished(), false);
|
||||
return getPlayer(server, user, args, pos, false);
|
||||
}
|
||||
|
||||
protected User getPlayer(final Server server, final User user, final String[] args, final int pos, final boolean getOffline) throws PlayerNotFoundException, NotEnoughArgumentsException {
|
||||
return getPlayer(server, user, args, pos, user.canInteractVanished(), getOffline);
|
||||
}
|
||||
|
||||
// Get online or offline players, this method allows for raw access
|
||||
@@ -326,7 +332,7 @@ public abstract class EssentialsCommand implements IEssentialsCommand {
|
||||
public void showError(final CommandSender sender, final Throwable throwable, final String commandLabel) {
|
||||
sender.sendMessage(tl("errorWithMessage", throwable.getMessage()));
|
||||
if (ess.getSettings().isDebug()) {
|
||||
logger.log(Level.INFO, tl("errorCallingCommand", commandLabel), throwable);
|
||||
ess.getLogger().log(Level.INFO, tl("errorCallingCommand", commandLabel), throwable);
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.earth2me.essentials.config;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import org.spongepowered.configurate.CommentedConfigurationNode;
|
||||
import org.spongepowered.configurate.ConfigurateException;
|
||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||
@@ -7,8 +8,6 @@ import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.earth2me.essentials.config.EssentialsConfiguration.LOGGER;
|
||||
|
||||
public class ConfigurationSaveTask implements Runnable {
|
||||
private final YamlConfigurationLoader loader;
|
||||
private final CommentedConfigurationNode node;
|
||||
@@ -32,7 +31,7 @@ public class ConfigurationSaveTask implements Runnable {
|
||||
try {
|
||||
loader.save(node);
|
||||
} catch (ConfigurateException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
} finally {
|
||||
pendingWrites.decrementAndGet();
|
||||
}
|
||||
|
||||
+14
-15
@@ -1,5 +1,6 @@
|
||||
package com.earth2me.essentials.config;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.config.annotations.DeleteIfIncomplete;
|
||||
import com.earth2me.essentials.config.annotations.DeleteOnEmpty;
|
||||
import com.earth2me.essentials.config.entities.CommandCooldown;
|
||||
@@ -44,12 +45,10 @@ import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class EssentialsConfiguration {
|
||||
protected static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
|
||||
private static final ObjectMapper.Factory MAPPER_FACTORY = ObjectMapper.factoryBuilder()
|
||||
.addProcessor(DeleteOnEmpty.class, (data, value) -> new DeleteOnEmptyProcessor())
|
||||
@@ -133,7 +132,7 @@ public class EssentialsConfiguration {
|
||||
try {
|
||||
result.put(entry.getKey().toLowerCase(Locale.ENGLISH), jailNode.get(LazyLocation.class));
|
||||
} catch (SerializationException e) {
|
||||
LOGGER.log(Level.WARNING, "Error serializing key " + entry.getKey(), e);
|
||||
Essentials.getWrappedLogger().log(Level.WARNING, "Error serializing key " + entry.getKey(), e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -147,7 +146,7 @@ public class EssentialsConfiguration {
|
||||
try {
|
||||
toSplitRoot(path, configurationNode).set(type, list);
|
||||
} catch (SerializationException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +162,7 @@ public class EssentialsConfiguration {
|
||||
}
|
||||
return list;
|
||||
} catch (SerializationException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
@@ -301,7 +300,7 @@ public class EssentialsConfiguration {
|
||||
try {
|
||||
node.set(null);
|
||||
} catch (SerializationException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,7 +309,7 @@ public class EssentialsConfiguration {
|
||||
try {
|
||||
toSplitRoot(path, configurationNode).set(value);
|
||||
} catch (SerializationException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,13 +335,13 @@ public class EssentialsConfiguration {
|
||||
|
||||
public synchronized void load() {
|
||||
if (pendingWrites.get() != 0) {
|
||||
LOGGER.log(Level.INFO, "Parsing config file {0} has been aborted due to {1} current pending write(s).", new Object[]{configFile, pendingWrites.get()});
|
||||
Essentials.getWrappedLogger().log(Level.INFO, "Parsing config file {0} has been aborted due to {1} current pending write(s).", new Object[]{configFile, pendingWrites.get()});
|
||||
return;
|
||||
}
|
||||
|
||||
if (configFile.getParentFile() != null && !configFile.getParentFile().exists()) {
|
||||
if (!configFile.getParentFile().mkdirs()) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()));
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -354,10 +353,10 @@ public class EssentialsConfiguration {
|
||||
convertAltFile();
|
||||
} else if (templateName != null) {
|
||||
try (final InputStream is = resourceClass.getResourceAsStream(templateName)) {
|
||||
LOGGER.log(Level.INFO, tl("creatingConfigFromTemplate", configFile.toString()));
|
||||
Essentials.getWrappedLogger().log(Level.INFO, tl("creatingConfigFromTemplate", configFile.toString()));
|
||||
Files.copy(is, configFile.toPath());
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToWriteConfig", configFile.toString()), e);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, tl("failedToWriteConfig", configFile.toString()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -367,12 +366,12 @@ public class EssentialsConfiguration {
|
||||
} catch (final ParsingException e) {
|
||||
final File broken = new File(configFile.getAbsolutePath() + ".broken." + System.currentTimeMillis());
|
||||
if (configFile.renameTo(broken)) {
|
||||
LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), e.getCause());
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), e.getCause());
|
||||
return;
|
||||
}
|
||||
LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken. A backup file has failed to be created", e.getCause());
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, "The file " + configFile.toString() + " is broken. A backup file has failed to be created", e.getCause());
|
||||
} catch (final ConfigurateException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
} finally {
|
||||
// Something is wrong! We need a node! I hope the backup worked!
|
||||
if (configurationNode == null) {
|
||||
@@ -435,7 +434,7 @@ public class EssentialsConfiguration {
|
||||
try {
|
||||
delaySave().get();
|
||||
} catch (final InterruptedException | ExecutionException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
Essentials.getWrappedLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
package com.earth2me.essentials.config;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Files;
|
||||
|
||||
@@ -43,7 +44,7 @@ public class EssentialsUserConfiguration extends EssentialsConfiguration {
|
||||
//noinspection UnstableApiUsage
|
||||
Files.move(file, new File(configFile.getParentFile(), uuid + ".yml"));
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "Failed to migrate user: " + username, ex);
|
||||
Essentials.getWrappedLogger().log(Level.WARNING, "Failed to migrate user: " + username, ex);
|
||||
}
|
||||
|
||||
setProperty("last-account-name", username);
|
||||
@@ -68,7 +69,7 @@ public class EssentialsUserConfiguration extends EssentialsConfiguration {
|
||||
//noinspection UnstableApiUsage
|
||||
Files.move(getAltFile(), new File(configFile.getParentFile(), uuid + ".yml"));
|
||||
} catch (final IOException ex) {
|
||||
LOGGER.log(Level.WARNING, "Failed to migrate user: " + username, ex);
|
||||
Essentials.getWrappedLogger().log(Level.WARNING, "Failed to migrate user: " + username, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,6 +322,16 @@ public class UserConfigHolder {
|
||||
this.baltopExempt = value;
|
||||
}
|
||||
|
||||
private @MonotonicNonNull Boolean shouting;
|
||||
|
||||
public Boolean shouting() {
|
||||
return shouting;
|
||||
}
|
||||
|
||||
public void shouting(final Boolean value) {
|
||||
this.shouting = value;
|
||||
}
|
||||
|
||||
private @NonNull Timestamps timestamps = new Timestamps();
|
||||
|
||||
public Timestamps timestamps() {
|
||||
|
||||
+19
-62
@@ -1,5 +1,6 @@
|
||||
package com.earth2me.essentials.craftbukkit;
|
||||
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -15,15 +16,13 @@ import java.util.Map;
|
||||
/*
|
||||
* This class can be removed when https://github.com/Bukkit/CraftBukkit/pull/193 is accepted to CraftBukkit
|
||||
*/
|
||||
|
||||
public final class InventoryWorkaround {
|
||||
/*
|
||||
Spigot 1.9, for whatever reason, decided to merge the armor and main player inventories without providing a way
|
||||
to access the main inventory. There's lots of ugly code in here to work around that.
|
||||
*/
|
||||
private static final int USABLE_PLAYER_INV_SIZE = 36;
|
||||
// Hot-ish code so cache
|
||||
private static Boolean hasMainHandSupport = null;
|
||||
private static final boolean IS_OFFHAND = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01);
|
||||
|
||||
private InventoryWorkaround() {
|
||||
}
|
||||
@@ -201,87 +200,45 @@ public final class InventoryWorkaround {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setItemInMainHand(final Player p, final ItemStack item) {
|
||||
if (hasMainHandSupport == null) {
|
||||
try {
|
||||
p.getInventory().setItemInMainHand(item);
|
||||
hasMainHandSupport = true;
|
||||
} catch (final Throwable e) {
|
||||
p.setItemInHand(item);
|
||||
hasMainHandSupport = false;
|
||||
}
|
||||
if (IS_OFFHAND) {
|
||||
p.getInventory().setItemInMainHand(item);
|
||||
} else {
|
||||
if (hasMainHandSupport) {
|
||||
p.getInventory().setItemInMainHand(item);
|
||||
} else {
|
||||
p.setItemInHand(item);
|
||||
}
|
||||
p.setItemInHand(item);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setItemInMainHand(final EntityEquipment invent, final ItemStack item) {
|
||||
if (hasMainHandSupport == null) {
|
||||
try {
|
||||
invent.setItemInMainHand(item);
|
||||
hasMainHandSupport = true;
|
||||
} catch (final Throwable e) {
|
||||
invent.setItemInHand(item);
|
||||
hasMainHandSupport = false;
|
||||
}
|
||||
if (IS_OFFHAND) {
|
||||
invent.setItemInMainHand(item);
|
||||
} else {
|
||||
if (hasMainHandSupport) {
|
||||
invent.setItemInMainHand(item);
|
||||
} else {
|
||||
invent.setItemInHand(item);
|
||||
}
|
||||
invent.setItemInHand(item);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setItemInMainHandDropChance(final EntityEquipment invent, final float chance) {
|
||||
if (hasMainHandSupport == null) {
|
||||
try {
|
||||
invent.setItemInMainHandDropChance(chance);
|
||||
hasMainHandSupport = true;
|
||||
} catch (final Throwable e) {
|
||||
invent.setItemInHandDropChance(chance);
|
||||
hasMainHandSupport = false;
|
||||
}
|
||||
if (IS_OFFHAND) {
|
||||
invent.setItemInMainHandDropChance(chance);
|
||||
} else {
|
||||
if (hasMainHandSupport) {
|
||||
invent.setItemInMainHandDropChance(chance);
|
||||
} else {
|
||||
invent.setItemInHandDropChance(chance);
|
||||
}
|
||||
invent.setItemInHandDropChance(chance);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setItemInOffHand(final Player p, final ItemStack item) {
|
||||
// This assumes that all builds that support a main hand also support an off hand.
|
||||
if (hasMainHandSupport == null || hasMainHandSupport) {
|
||||
try {
|
||||
p.getInventory().setItemInOffHand(item);
|
||||
hasMainHandSupport = true;
|
||||
} catch (final Throwable e) {
|
||||
hasMainHandSupport = false;
|
||||
}
|
||||
if (IS_OFFHAND) {
|
||||
p.getInventory().setItemInOffHand(item);
|
||||
}
|
||||
}
|
||||
|
||||
public static int clearItemInOffHand(final Player p, final ItemStack item) {
|
||||
// This should be added because if `/clear` itself is not initilized it will return an Error: null.
|
||||
if (hasMainHandSupport == null || hasMainHandSupport) {
|
||||
try {
|
||||
int removedAmount = 0;
|
||||
if (p.getInventory().getItemInOffHand().getType().equals(item.getType())) {
|
||||
removedAmount = p.getInventory().getItemInOffHand().getAmount();
|
||||
p.getInventory().setItemInOffHand(null);
|
||||
}
|
||||
hasMainHandSupport = true;
|
||||
return removedAmount;
|
||||
} catch (final Throwable e) {
|
||||
hasMainHandSupport = false;
|
||||
if (IS_OFFHAND) {
|
||||
int removedAmount = 0;
|
||||
if (p.getInventory().getItemInOffHand().getType().equals(item.getType())) {
|
||||
removedAmount = p.getInventory().getItemInOffHand().getAmount();
|
||||
p.getInventory().setItemInOffHand(null);
|
||||
}
|
||||
return removedAmount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+3
-5
@@ -19,7 +19,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* A goddamn Vault adapter, what more do you want?
|
||||
@@ -29,7 +28,6 @@ import java.util.logging.Logger;
|
||||
* {@link com.earth2me.essentials.User}.
|
||||
*/
|
||||
public class VaultEconomyProvider implements Economy {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private static final String WARN_NPC_RECREATE_1 = "Account creation was requested for NPC user {0}, but an account file with UUID {1} already exists.";
|
||||
private static final String WARN_NPC_RECREATE_2 = "Essentials will create a new account as requested by the other plugin, but this is almost certainly a bug and should be reported.";
|
||||
|
||||
@@ -301,8 +299,8 @@ public class VaultEconomyProvider implements Economy {
|
||||
}
|
||||
final File npcFile = new File(folder, player.getUniqueId() + ".yml");
|
||||
if (npcFile.exists()) {
|
||||
LOGGER.log(Level.SEVERE, MessageFormat.format(WARN_NPC_RECREATE_1, player.getName(), player.getUniqueId().toString()), new RuntimeException());
|
||||
LOGGER.log(Level.SEVERE, WARN_NPC_RECREATE_2);
|
||||
ess.getLogger().log(Level.SEVERE, MessageFormat.format(WARN_NPC_RECREATE_1, player.getName(), player.getUniqueId().toString()), new RuntimeException());
|
||||
ess.getLogger().log(Level.SEVERE, WARN_NPC_RECREATE_2);
|
||||
}
|
||||
final EssentialsUserConfiguration npcConfig = new EssentialsUserConfiguration(player.getName(), player.getUniqueId(), npcFile);
|
||||
npcConfig.load();
|
||||
@@ -317,7 +315,7 @@ public class VaultEconomyProvider implements Economy {
|
||||
// Loading a v4 UUID that we somehow didn't track, mark it as a normal player and hope for the best, vault sucks :/
|
||||
try {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.info("Vault requested a player account creation for a v4 UUID: " + player);
|
||||
ess.getLogger().info("Vault requested a player account creation for a v4 UUID: " + player);
|
||||
}
|
||||
ess.getUserMap().load(player);
|
||||
return true;
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.bukkit.inventory.meta.FireworkEffectMeta;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.potion.Potion;
|
||||
@@ -279,12 +280,22 @@ public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
|
||||
serializeEffectMeta(sb, fireworkEffectMeta.getEffect());
|
||||
}
|
||||
} else if (MaterialUtil.isPotion(material)) {
|
||||
final Potion potion = Potion.fromItemStack(is);
|
||||
for (final PotionEffect e : potion.getEffects()) {
|
||||
// long but needs to be effect:speed power:2 duration:120 in that order.
|
||||
sb.append("splash:").append(potion.isSplash()).append(" ").append("effect:").append(e.getType().getName().toLowerCase()).append(" ").append("power:").append(e.getAmplifier()).append(" ").append("duration:").append(e.getDuration() / 20).append(" ");
|
||||
final boolean splash;
|
||||
final Collection<PotionEffect> effects;
|
||||
if (VersionUtil.PRE_FLATTENING) {
|
||||
final Potion potion = Potion.fromDamage(is.getDurability());
|
||||
splash = potion.isSplash();
|
||||
effects = potion.getEffects();
|
||||
} else {
|
||||
splash = is.getType() == Material.SPLASH_POTION;
|
||||
effects = ((PotionMeta) is.getItemMeta()).getCustomEffects();
|
||||
}
|
||||
} else if (MaterialUtil.isPlayerHead(material, is.getData().getData())) {
|
||||
|
||||
for (final PotionEffect e : effects) {
|
||||
// long but needs to be effect:speed power:2 duration:120 in that order.
|
||||
sb.append("splash:").append(splash).append(" ").append("effect:").append(e.getType().getName().toLowerCase()).append(" ").append("power:").append(e.getAmplifier()).append(" ").append("duration:").append(e.getDuration() / 20).append(" ");
|
||||
}
|
||||
} else if (MaterialUtil.isPlayerHead(is)) {
|
||||
// item stack with meta
|
||||
final SkullMeta skullMeta = (SkullMeta) is.getItemMeta();
|
||||
if (skullMeta != null && skullMeta.hasOwner()) {
|
||||
|
||||
@@ -23,13 +23,11 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class FlatItemDb extends AbstractItemDb {
|
||||
protected static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
// Maps primary name to ItemData
|
||||
@@ -54,7 +52,7 @@ public class FlatItemDb extends AbstractItemDb {
|
||||
}
|
||||
|
||||
this.rebuild();
|
||||
LOGGER.info(String.format("Loaded %s items from items.json.", listNames().size()));
|
||||
ess.getLogger().info(String.format("Loaded %s items from items.json.", listNames().size()));
|
||||
}
|
||||
|
||||
private void rebuild() {
|
||||
@@ -100,7 +98,7 @@ public class FlatItemDb extends AbstractItemDb {
|
||||
if (valid) {
|
||||
allAliases.add(key);
|
||||
} else {
|
||||
LOGGER.warning(String.format("Failed to add item: \"%s\": %s", key, element.toString()));
|
||||
ess.getLogger().warning(String.format("Failed to add item: \"%s\": %s", key, element.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +113,7 @@ public class FlatItemDb extends AbstractItemDb {
|
||||
}
|
||||
|
||||
id = id.toLowerCase();
|
||||
final String[] split = id.split(":");
|
||||
final String[] split = id.split("(?<!^minecraft):");
|
||||
|
||||
final ItemData data = getByName(split[0]);
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ package com.earth2me.essentials.items;
|
||||
import com.earth2me.essentials.ManagedFile;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -17,14 +17,12 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class LegacyItemDb extends AbstractItemDb {
|
||||
protected static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private final transient Map<String, Integer> items = new HashMap<>();
|
||||
private final transient Map<ItemData, List<String>> names = new HashMap<>();
|
||||
private final transient Map<ItemData, String> primaryName = new HashMap<>();
|
||||
@@ -68,10 +66,10 @@ public class LegacyItemDb extends AbstractItemDb {
|
||||
final Matcher matcher = csvSplitPattern.matcher(line);
|
||||
while (matcher.find()) {
|
||||
String match = matcher.group(1);
|
||||
if (StringUtils.stripToNull(match) == null) {
|
||||
if (StringUtil.stripToNull(match) == null) {
|
||||
continue;
|
||||
}
|
||||
match = StringUtils.strip(match.trim(), "\"");
|
||||
match = StringUtil.strip(match.trim(), "\"");
|
||||
switch (col) {
|
||||
case 0:
|
||||
itemName = match.toLowerCase(Locale.ENGLISH);
|
||||
@@ -83,7 +81,7 @@ public class LegacyItemDb extends AbstractItemDb {
|
||||
data = Short.parseShort(match);
|
||||
break;
|
||||
case 3:
|
||||
nbt = StringUtils.stripToNull(match);
|
||||
nbt = StringUtil.stripToNull(match);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
@@ -119,7 +117,7 @@ public class LegacyItemDb extends AbstractItemDb {
|
||||
nameList.sort(LengthCompare.INSTANCE);
|
||||
}
|
||||
|
||||
LOGGER.info(String.format("Loaded %s items from items.csv.", listNames().size()));
|
||||
ess.getLogger().info(String.format("Loaded %s items from items.csv.", listNames().size()));
|
||||
|
||||
ready = true;
|
||||
}
|
||||
@@ -204,7 +202,7 @@ public class LegacyItemDb extends AbstractItemDb {
|
||||
}
|
||||
retval = ess.getSpawnEggProvider().createEggItem(type);
|
||||
} else if (mat.name().endsWith("POTION")
|
||||
&& ReflUtil.getNmsVersionObject().isLowerThan(ReflUtil.V1_11_R1)) { // Only apply this to pre-1.11 as items.csv might only work in 1.11
|
||||
&& VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_11_R01)) { // Only apply this to pre-1.11 as items.csv might only work in 1.11
|
||||
retval = ess.getPotionMetaProvider().createPotionItem(mat, metaData);
|
||||
} else {
|
||||
retval.setDurability(metaData);
|
||||
|
||||
@@ -3,40 +3,32 @@ package com.earth2me.essentials.metrics;
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.economy.EconomyLayer;
|
||||
import com.earth2me.essentials.economy.EconomyLayers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.AdvancedBarChart;
|
||||
import org.bstats.charts.CustomChart;
|
||||
import org.bstats.charts.DrilldownPie;
|
||||
import org.bstats.charts.MultiLineChart;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MetricsWrapper {
|
||||
|
||||
private static final List<String> KNOWN_FORCED_METRICS = ImmutableList.of(
|
||||
"ChatControl",
|
||||
"catserver.server.Metrics");
|
||||
private static boolean hasWarned = false;
|
||||
private final Essentials ess;
|
||||
private final Metrics metrics;
|
||||
private final JavaPlugin plugin;
|
||||
private final Map<String, Boolean> commands = new HashMap<>();
|
||||
private final Plugin plugin;
|
||||
|
||||
public MetricsWrapper(final Plugin plugin, final int pluginId, final boolean includeCommands) {
|
||||
public MetricsWrapper(final JavaPlugin plugin, final int pluginId, final boolean includeCommands) {
|
||||
this.plugin = plugin;
|
||||
this.ess = (Essentials) Bukkit.getPluginManager().getPlugin("Essentials");
|
||||
this.metrics = new Metrics(plugin, pluginId);
|
||||
|
||||
if (metrics.isEnabled()) {
|
||||
plugin.getLogger().info("Starting Metrics. Opt-out using the global bStats config.");
|
||||
} else {
|
||||
plugin.getLogger().info("Metrics disabled per bStats config.");
|
||||
}
|
||||
plugin.getLogger().info("Starting Metrics. Opt-out using the global bStats config.");
|
||||
|
||||
checkForcedMetrics();
|
||||
addPermsChart();
|
||||
addEconomyChart();
|
||||
addReleaseBranchChart();
|
||||
@@ -51,12 +43,12 @@ public class MetricsWrapper {
|
||||
commands.put(command, state);
|
||||
}
|
||||
|
||||
public void addCustomChart(final Metrics.CustomChart chart) {
|
||||
public void addCustomChart(final CustomChart chart) {
|
||||
metrics.addCustomChart(chart);
|
||||
}
|
||||
|
||||
private void addPermsChart() {
|
||||
metrics.addCustomChart(new Metrics.DrilldownPie("permsPlugin", () -> {
|
||||
metrics.addCustomChart(new DrilldownPie("permsPlugin", () -> {
|
||||
final Map<String, Map<String, Integer>> result = new HashMap<>();
|
||||
final String handler = ess.getPermissionsHandler().getName();
|
||||
final Map<String, Integer> backend = new HashMap<>();
|
||||
@@ -67,7 +59,7 @@ public class MetricsWrapper {
|
||||
}
|
||||
|
||||
private void addEconomyChart() {
|
||||
metrics.addCustomChart(new Metrics.DrilldownPie("econPlugin", () -> {
|
||||
metrics.addCustomChart(new DrilldownPie("econPlugin", () -> {
|
||||
final Map<String, Map<String, Integer>> result = new HashMap<>();
|
||||
final Map<String, Integer> backend = new HashMap<>();
|
||||
final EconomyLayer layer = EconomyLayers.getSelectedLayer();
|
||||
@@ -83,7 +75,7 @@ public class MetricsWrapper {
|
||||
}
|
||||
|
||||
private void addVersionHistoryChart() {
|
||||
metrics.addCustomChart(new Metrics.MultiLineChart("versionHistory", () -> {
|
||||
metrics.addCustomChart(new MultiLineChart("versionHistory", () -> {
|
||||
final HashMap<String, Integer> result = new HashMap<>();
|
||||
result.put(plugin.getDescription().getVersion(), 1);
|
||||
return result;
|
||||
@@ -91,7 +83,7 @@ public class MetricsWrapper {
|
||||
}
|
||||
|
||||
private void addReleaseBranchChart() {
|
||||
metrics.addCustomChart(new Metrics.SimplePie("releaseBranch", ess.getUpdateChecker()::getVersionBranch));
|
||||
metrics.addCustomChart(new SimplePie("releaseBranch", ess.getUpdateChecker()::getVersionBranch));
|
||||
}
|
||||
|
||||
private void addCommandsChart() {
|
||||
@@ -99,7 +91,7 @@ public class MetricsWrapper {
|
||||
markCommand(command, false);
|
||||
}
|
||||
|
||||
metrics.addCustomChart(new Metrics.AdvancedBarChart("commands", () -> {
|
||||
metrics.addCustomChart(new AdvancedBarChart("commands", () -> {
|
||||
final Map<String, int[]> result = new HashMap<>();
|
||||
for (final Map.Entry<String, Boolean> entry : commands.entrySet()) {
|
||||
if (entry.getValue()) {
|
||||
@@ -112,75 +104,4 @@ public class MetricsWrapper {
|
||||
}));
|
||||
}
|
||||
|
||||
private boolean isForcedMetricsClass(Class<?> bStatsService) {
|
||||
for (String identifier : KNOWN_FORCED_METRICS) {
|
||||
if (bStatsService.getCanonicalName().contains(identifier)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
final JavaPlugin owningPlugin = getProvidingPlugin(bStatsService);
|
||||
if (owningPlugin != null && KNOWN_FORCED_METRICS.contains(owningPlugin.getName())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkForcedMetrics() {
|
||||
if (hasWarned) return;
|
||||
hasWarned = true;
|
||||
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> {
|
||||
for (final Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Identifies bStats classes
|
||||
|
||||
if (isForcedMetricsClass(service)) {
|
||||
warnForcedMetrics(service);
|
||||
} else {
|
||||
try {
|
||||
service.getDeclaredField("pluginId"); // Only present in recent bStats classes, which should also have the enabled field unless modified
|
||||
} catch (final NoSuchFieldException e) {
|
||||
// Old bStats class found so "enabled" field detection is unreliable.
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
service.getDeclaredField("enabled"); // In some modified forced metrics classes, this will fail
|
||||
} catch (final NoSuchFieldException e) {
|
||||
warnForcedMetrics(service);
|
||||
}
|
||||
}
|
||||
} catch (final NoSuchFieldException ignored) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void warnForcedMetrics(final Class<?> service) {
|
||||
final Plugin servicePlugin = JavaPlugin.getProvidingPlugin(service);
|
||||
plugin.getLogger().severe("WARNING: Potential forced metrics collection by plugin '" + servicePlugin.getName() + "' v" + servicePlugin.getDescription().getVersion());
|
||||
plugin.getLogger().severe("Your server is running a plugin that may not respect bStats' opt-out settings.");
|
||||
plugin.getLogger().severe("This may cause data to be uploaded to bStats.org for plugins that use bStats, even if you've opted out in the bStats config.");
|
||||
plugin.getLogger().severe("Please report this to bStats and to the authors of '" + servicePlugin.getName() + "'. (Offending class: " + service.getName() + ")");
|
||||
}
|
||||
|
||||
private JavaPlugin getProvidingPlugin(final Class<?> clazz) {
|
||||
try {
|
||||
return JavaPlugin.getProvidingPlugin(clazz);
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
|
||||
final ClassLoader parent = clazz.getClassLoader().getParent();
|
||||
if (parent.getClass().getName().equals("org.bukkit.plugin.java.PluginClassLoader")) {
|
||||
try {
|
||||
final Field pluginField = parent.getClass().getDeclaredField("plugin");
|
||||
pluginField.setAccessible(true);
|
||||
return (JavaPlugin) pluginField.get(parent);
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.earth2me.essentials.perm;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.TriState;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -27,11 +29,11 @@ public interface IPermissionsHandler {
|
||||
|
||||
String getSuffix(Player base);
|
||||
|
||||
void registerContext(String context, Function<Player, Iterable<String>> calculator, Supplier<Iterable<String>> suggestions);
|
||||
void registerContext(String context, Function<User, Iterable<String>> calculator, Supplier<Iterable<String>> suggestions);
|
||||
|
||||
void unregisterContexts();
|
||||
|
||||
String getBackendName();
|
||||
|
||||
boolean tryProvider();
|
||||
boolean tryProvider(Essentials ess);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials.perm;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.perm.impl.AbstractVaultHandler;
|
||||
import com.earth2me.essentials.perm.impl.ConfigPermissionsHandler;
|
||||
import com.earth2me.essentials.perm.impl.GenericVaultHandler;
|
||||
@@ -105,7 +106,7 @@ public class PermissionsHandler implements IPermissionsHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerContext(final String context, final Function<Player, Iterable<String>> calculator, final Supplier<Iterable<String>> suggestions) {
|
||||
public void registerContext(final String context, final Function<User, Iterable<String>> calculator, final Supplier<Iterable<String>> suggestions) {
|
||||
handler.registerContext(context, calculator, suggestions);
|
||||
}
|
||||
|
||||
@@ -120,7 +121,7 @@ public class PermissionsHandler implements IPermissionsHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
public boolean tryProvider(Essentials ess) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -135,7 +136,7 @@ public class PermissionsHandler implements IPermissionsHandler {
|
||||
for (final Class<? extends IPermissionsHandler> providerClass : providerClazz) {
|
||||
try {
|
||||
final IPermissionsHandler provider = providerClass.newInstance();
|
||||
if (provider.tryProvider()) {
|
||||
if (provider.tryProvider(ess)) {
|
||||
if (provider.getClass().isInstance(this.handler)) {
|
||||
return;
|
||||
}
|
||||
@@ -170,7 +171,7 @@ public class PermissionsHandler implements IPermissionsHandler {
|
||||
if (enabledPermsPlugin == null) enabledPermsPlugin = "generic";
|
||||
ess.getLogger().info("Using Vault based permissions (" + enabledPermsPlugin + ")");
|
||||
} else if (handler.getClass() == SuperpermsHandler.class) {
|
||||
if (handler.tryProvider()) {
|
||||
if (handler.tryProvider(ess)) {
|
||||
ess.getLogger().warning("Detected supported permissions plugin " +
|
||||
((SuperpermsHandler) handler).getEnabledPermsPlugin() + " without Vault installed.");
|
||||
ess.getLogger().warning("Features such as chat prefixes/suffixes and group-related functionality will not " +
|
||||
@@ -199,11 +200,11 @@ public class PermissionsHandler implements IPermissionsHandler {
|
||||
}
|
||||
|
||||
private void initContexts() {
|
||||
registerContext("essentials:afk", player -> Collections.singleton(String.valueOf(ess.getUser(player).isAfk())), () -> ImmutableSet.of("true", "false"));
|
||||
registerContext("essentials:muted", player -> Collections.singleton(String.valueOf(ess.getUser(player).isMuted())), () -> ImmutableSet.of("true", "false"));
|
||||
registerContext("essentials:vanished", player -> Collections.singleton(String.valueOf(ess.getUser(player).isHidden())), () -> ImmutableSet.of("true", "false"));
|
||||
registerContext("essentials:jailed", player -> Collections.singleton(String.valueOf(ess.getUser(player).isJailed())), () -> ImmutableSet.of("true", "false"));
|
||||
registerContext("essentials:jail", player -> Optional.ofNullable(ess.getUser(player).getJail()).map(Arrays::asList).orElse(Collections.emptyList()), () -> {
|
||||
registerContext("essentials:afk", user -> Collections.singleton(String.valueOf(user.isAfk())), () -> ImmutableSet.of("true", "false"));
|
||||
registerContext("essentials:muted", user -> Collections.singleton(String.valueOf(user.isMuted())), () -> ImmutableSet.of("true", "false"));
|
||||
registerContext("essentials:vanished", user -> Collections.singleton(String.valueOf(user.isHidden())), () -> ImmutableSet.of("true", "false"));
|
||||
registerContext("essentials:jailed", user -> Collections.singleton(String.valueOf(user.isJailed())), () -> ImmutableSet.of("true", "false"));
|
||||
registerContext("essentials:jail", user -> Optional.ofNullable(user.getJail()).map(Arrays::asList).orElse(Collections.emptyList()), () -> {
|
||||
try {
|
||||
return ess.getJails().getList();
|
||||
} catch (final Exception e) {
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
package com.earth2me.essentials.perm.impl;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.utils.TriState;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -35,7 +36,7 @@ public class ConfigPermissionsHandler extends SuperpermsHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
public boolean tryProvider(Essentials ess) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.earth2me.essentials.perm.impl;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
|
||||
public class GenericVaultHandler extends AbstractVaultHandler {
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
public boolean tryProvider(Essentials ess) {
|
||||
return super.canLoad();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.earth2me.essentials.perm.impl;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.User;
|
||||
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.context.ContextCalculator;
|
||||
import net.luckperms.api.context.ContextConsumer;
|
||||
@@ -16,40 +19,75 @@ import java.util.function.Supplier;
|
||||
|
||||
public class LuckPermsHandler extends ModernVaultHandler {
|
||||
private LuckPerms luckPerms;
|
||||
private Set<ContextCalculator<Player>> contextCalculators;
|
||||
private Essentials ess;
|
||||
private CombinedCalculator calculator;
|
||||
|
||||
@Override
|
||||
public void registerContext(final String context, final Function<Player, Iterable<String>> calculator, final Supplier<Iterable<String>> suggestions) {
|
||||
final ContextCalculator<Player> contextCalculator = new ContextCalculator<Player>() {
|
||||
@Override
|
||||
public void calculate(final Player target, final ContextConsumer consumer) {
|
||||
calculator.apply(target).forEach(value -> consumer.accept(context, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextSet estimatePotentialContexts() {
|
||||
final ImmutableContextSet.Builder builder = ImmutableContextSet.builder();
|
||||
suggestions.get().forEach(value -> builder.add(context, value));
|
||||
return builder.build();
|
||||
}
|
||||
};
|
||||
luckPerms.getContextManager().registerCalculator(contextCalculator);
|
||||
contextCalculators.add(contextCalculator);
|
||||
public void registerContext(final String context, final Function<User, Iterable<String>> calculator, final Supplier<Iterable<String>> suggestions) {
|
||||
if (this.calculator == null) {
|
||||
this.calculator = new CombinedCalculator();
|
||||
this.luckPerms.getContextManager().registerCalculator(this.calculator);
|
||||
}
|
||||
this.calculator.calculators.add(new Calculator(context, calculator, suggestions));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterContexts() {
|
||||
contextCalculators.forEach(contextCalculator -> luckPerms.getContextManager().unregisterCalculator(contextCalculator));
|
||||
contextCalculators.clear();
|
||||
if (this.calculator != null) {
|
||||
this.luckPerms.getContextManager().unregisterCalculator(this.calculator);
|
||||
this.calculator = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
public boolean tryProvider(Essentials ess) {
|
||||
final RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
|
||||
if (provider != null) {
|
||||
luckPerms = provider.getProvider();
|
||||
contextCalculators = new HashSet<>();
|
||||
this.luckPerms = provider.getProvider();
|
||||
this.ess = ess;
|
||||
}
|
||||
return luckPerms != null && super.tryProvider(ess);
|
||||
}
|
||||
|
||||
private static final class Calculator {
|
||||
private final String id;
|
||||
private final Function<User, Iterable<String>> function;
|
||||
private final Supplier<Iterable<String>> suggestions;
|
||||
|
||||
private Calculator(String id, Function<User, Iterable<String>> function, Supplier<Iterable<String>> suggestions) {
|
||||
this.id = id;
|
||||
this.function = function;
|
||||
this.suggestions = suggestions;
|
||||
}
|
||||
}
|
||||
|
||||
// By combining all calculators into one, we only need to make one call to ess.getUser().
|
||||
private class CombinedCalculator implements ContextCalculator<Player> {
|
||||
private final Set<Calculator> calculators = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void calculate(final Player target, final ContextConsumer consumer) {
|
||||
// If the player doesn't exist in the UserMap, just skip
|
||||
// Ess will cause performance problems for permissions checks if it attempts to
|
||||
// perform i/o to load the user data otherwise.
|
||||
if (!ess.getUserMap().userExists(target.getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
final User user = ess.getUser(target);
|
||||
for (Calculator calculator : this.calculators) {
|
||||
calculator.function.apply(user).forEach(value -> consumer.accept(calculator.id, value));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextSet estimatePotentialContexts() {
|
||||
final ImmutableContextSet.Builder builder = ImmutableContextSet.builder();
|
||||
for (Calculator calculator : this.calculators) {
|
||||
calculator.suggestions.get().forEach(value -> builder.add(calculator.id, value));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
return luckPerms != null && super.tryProvider();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.earth2me.essentials.perm.impl;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -21,7 +23,7 @@ public class ModernVaultHandler extends AbstractVaultHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
public boolean tryProvider(Essentials ess) {
|
||||
return super.canLoad() && supportedPlugins.contains(getEnabledPermsPlugin());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.earth2me.essentials.perm.impl;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.perm.IPermissionsHandler;
|
||||
import com.earth2me.essentials.utils.TriState;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -124,7 +126,7 @@ public class SuperpermsHandler implements IPermissionsHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerContext(final String context, final Function<Player, Iterable<String>> calculator, final Supplier<Iterable<String>> suggestions) {
|
||||
public void registerContext(final String context, final Function<User, Iterable<String>> calculator, final Supplier<Iterable<String>> suggestions) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,7 +139,7 @@ public class SuperpermsHandler implements IPermissionsHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
public boolean tryProvider(Essentials ess) {
|
||||
return getEnabledPermsPlugin() != null;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
@@ -30,6 +31,7 @@ import java.util.Set;
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class EssentialsSign {
|
||||
private static final String SIGN_OWNER_KEY = "sign-owner";
|
||||
protected static final BigDecimal MINTRANSACTION = new BigDecimal("0.01");
|
||||
private static final Set<Material> EMPTY_SET = new HashSet<>();
|
||||
protected transient final String signName;
|
||||
@@ -60,15 +62,15 @@ public class EssentialsSign {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated, use {@link #isValidSign(IEssentials, ISign)} if possible
|
||||
* @deprecated use {@link #isValidSign(IEssentials, ISign)} if possible
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isValidSign(final ISign sign) {
|
||||
return sign.getLine(0).matches("§1\\[.*\\]");
|
||||
return sign.getLine(0).matches("§1\\[.*]");
|
||||
}
|
||||
|
||||
public static boolean isValidSign(final IEssentials ess, final ISign sign) {
|
||||
if (!sign.getLine(0).matches("§1\\[.*\\]"))
|
||||
if (!sign.getLine(0).matches("§1\\[.*]"))
|
||||
return false;
|
||||
|
||||
// Validate that the sign is actually an essentials sign
|
||||
@@ -119,6 +121,7 @@ public class EssentialsSign {
|
||||
} catch (final ChargeException | SignException ex) {
|
||||
showError(ess, user.getSource(), ex, signName);
|
||||
}
|
||||
setOwnerData(ess, user, sign);
|
||||
// Return true, so the player sees the wrong sign.
|
||||
return true;
|
||||
}
|
||||
@@ -154,6 +157,36 @@ public class EssentialsSign {
|
||||
return user.getName().substring(0, Math.min(user.getName().length(), 13));
|
||||
}
|
||||
|
||||
public void setOwner(final IEssentials ess, final User user, final ISign signProvider, final int nameIndex, final String namePrefix) {
|
||||
setOwnerData(ess, user, signProvider);
|
||||
signProvider.setLine(nameIndex, namePrefix + getUsername(user));
|
||||
}
|
||||
|
||||
public void setOwnerData(final IEssentials ess, final User user, final ISign signProvider) {
|
||||
if (ess.getSignDataProvider() == null) {
|
||||
return;
|
||||
}
|
||||
final Sign sign = (Sign) signProvider.getBlock().getState();
|
||||
ess.getSignDataProvider().setSignData(sign, SIGN_OWNER_KEY, user.getUUID().toString());
|
||||
}
|
||||
|
||||
public boolean isOwner(final IEssentials ess, final User user, final ISign signProvider, final int nameIndex, final String namePrefix) {
|
||||
final Sign sign = (Sign) signProvider.getBlock().getState();
|
||||
if (ess.getSignDataProvider() == null || ess.getSignDataProvider().getSignData(sign, SIGN_OWNER_KEY) == null) {
|
||||
final boolean isLegacyOwner = FormatUtil.stripFormat(signProvider.getLine(nameIndex)).equalsIgnoreCase(getUsername(user));
|
||||
if (ess.getSignDataProvider() != null && isLegacyOwner) {
|
||||
ess.getSignDataProvider().setSignData(sign, SIGN_OWNER_KEY, user.getUUID().toString());
|
||||
}
|
||||
return isLegacyOwner;
|
||||
}
|
||||
|
||||
if (user.getUUID().toString().equals(ess.getSignDataProvider().getSignData(sign, SIGN_OWNER_KEY))) {
|
||||
signProvider.setLine(nameIndex, namePrefix + getUsername(user));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected final boolean onSignInteract(final Block block, final Player player, final IEssentials ess) {
|
||||
final ISign sign = new BlockSign(block);
|
||||
final User user = ess.getUser(player);
|
||||
@@ -392,7 +425,7 @@ public class EssentialsSign {
|
||||
}
|
||||
|
||||
protected final BigDecimal getMoney(final String line, final IEssentials ess) throws SignException {
|
||||
final boolean isMoney = line.matches("^[^0-9-\\.]?[\\.0-9]+[^0-9-\\.]?$");
|
||||
final boolean isMoney = line.matches("^[^0-9-.]?[.0-9]+[^0-9-.]?$");
|
||||
return isMoney ? getBigDecimalPositive(line, ess) : null;
|
||||
}
|
||||
|
||||
@@ -531,6 +564,7 @@ public class EssentialsSign {
|
||||
@Override
|
||||
public final void setLine(final int index, final String text) {
|
||||
sign.setLine(index, text);
|
||||
updateSign();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,10 +23,8 @@ import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class SignBlockListener implements Listener {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private final transient IEssentials ess;
|
||||
|
||||
public SignBlockListener(final IEssentials ess) {
|
||||
@@ -52,7 +50,7 @@ public class SignBlockListener implements Listener {
|
||||
// prevent any signs be broken by destroying the block they are attached to
|
||||
if (EssentialsSign.checkIfBlockBreaksSigns(block)) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Prevented that a block was broken next to a sign.");
|
||||
ess.getLogger().log(Level.INFO, "Prevented that a block was broken next to a sign.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -70,7 +68,7 @@ public class SignBlockListener implements Listener {
|
||||
|
||||
for (final EssentialsSign sign : ess.getSettings().enabledSigns()) {
|
||||
if (sign.areHeavyEventRequired() && sign.getBlocks().contains(block.getType()) && !sign.onBlockBreak(block, player, ess)) {
|
||||
LOGGER.log(Level.INFO, "A block was protected by a sign.");
|
||||
ess.getLogger().log(Level.INFO, "A block was protected by a sign.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.Trade.OverflowType;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
@@ -123,7 +122,7 @@ public class SignProtection extends EssentialsSign {
|
||||
if (user.isAuthorized("essentials.signs.protection.override")) {
|
||||
return SignProtectionState.OWNER;
|
||||
}
|
||||
if (FormatUtil.stripFormat(sign.getLine(3)).equalsIgnoreCase(username)) {
|
||||
if (isOwner(user.getEssentials(), user, sign, 3, "§1")) {
|
||||
return SignProtectionState.OWNER;
|
||||
}
|
||||
for (int i = 1; i <= 2; i++) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.Trade.OverflowType;
|
||||
import com.earth2me.essentials.Trade.TradeType;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
@@ -18,7 +19,7 @@ import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
//TODO: TL exceptions
|
||||
public class SignTrade extends EssentialsSign {
|
||||
private static int MAX_STOCK_LINE_LENGTH = 15;
|
||||
private static final int MAX_STOCK_LINE_LENGTH = 15;
|
||||
|
||||
public SignTrade() {
|
||||
super("Trade");
|
||||
@@ -34,7 +35,7 @@ public class SignTrade extends EssentialsSign {
|
||||
throw new SignException("You cannot trade for the same item type.");
|
||||
}
|
||||
trade.isAffordableFor(player);
|
||||
sign.setLine(3, "§8" + username);
|
||||
setOwner(ess, player, sign, 3, "§8");
|
||||
trade.charge(player);
|
||||
Trade.log("Sign", "Trade", "Create", username, trade, username, null, sign.getBlock().getLocation(), player.getMoney(), ess);
|
||||
return true;
|
||||
@@ -42,7 +43,7 @@ public class SignTrade extends EssentialsSign {
|
||||
|
||||
@Override
|
||||
protected boolean onSignInteract(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException, ChargeException, MaxMoneyException {
|
||||
if (sign.getLine(3).substring(2).equalsIgnoreCase(username)) {
|
||||
if (isOwner(ess, player, sign, 3, "§8")) {
|
||||
final Trade store = rechargeSign(sign, ess, player);
|
||||
final Trade stored;
|
||||
try {
|
||||
@@ -83,7 +84,7 @@ public class SignTrade extends EssentialsSign {
|
||||
|
||||
private Trade rechargeSign(final ISign sign, final IEssentials ess, final User player) throws SignException, ChargeException {
|
||||
final Trade trade = getTrade(sign, 2, AmountType.COST, false, true, ess);
|
||||
if (trade.getItemStack() != null && player.getBase().getItemInHand() != null && trade.getItemStack().getType() == player.getBase().getItemInHand().getType() && trade.getItemStack().getDurability() == player.getBase().getItemInHand().getDurability() && trade.getItemStack().getEnchantments().equals(player.getBase().getItemInHand().getEnchantments())) {
|
||||
if (trade.getItemStack() != null && player.getBase().getItemInHand() != null && trade.getItemStack().getType() == player.getBase().getItemInHand().getType() && MaterialUtil.getDamage(trade.getItemStack()) == MaterialUtil.getDamage(player.getBase().getItemInHand()) && trade.getItemStack().getEnchantments().equals(player.getBase().getItemInHand().getEnchantments())) {
|
||||
final int amount = trade.getItemStack().getAmount();
|
||||
if (player.getBase().getInventory().containsAtLeast(trade.getItemStack(), amount)) {
|
||||
final ItemStack stack = player.getBase().getItemInHand().clone();
|
||||
@@ -101,7 +102,7 @@ public class SignTrade extends EssentialsSign {
|
||||
protected boolean onSignBreak(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException, MaxMoneyException {
|
||||
final String signOwner = sign.getLine(3);
|
||||
|
||||
final boolean isOwner = signOwner.length() > 3 && signOwner.substring(2).equalsIgnoreCase(username);
|
||||
final boolean isOwner = isOwner(ess, player, sign, 3, "§8");
|
||||
final boolean canBreak = isOwner || player.isAuthorized("essentials.signs.trade.override");
|
||||
final boolean canCollect = isOwner || player.isAuthorized("essentials.signs.trade.override.collect");
|
||||
|
||||
@@ -115,8 +116,8 @@ public class SignTrade extends EssentialsSign {
|
||||
return true;
|
||||
}
|
||||
|
||||
final Map<Integer, ItemStack> withdraw1 = stored1.pay(player, OverflowType.RETURN);
|
||||
final Map<Integer, ItemStack> withdraw2 = stored2.pay(player, OverflowType.RETURN);
|
||||
final Map<Integer, ItemStack> withdraw1 = stored1.pay(player, OverflowType.DROP);
|
||||
final Map<Integer, ItemStack> withdraw2 = stored2.pay(player, OverflowType.DROP);
|
||||
|
||||
if (withdraw1 == null && withdraw2 == null) {
|
||||
Trade.log("Sign", "Trade", "Break", signOwner.substring(2), stored2, username, stored1, sign.getBlock().getLocation(), player.getMoney(), ess);
|
||||
@@ -205,7 +206,9 @@ public class SignTrade extends EssentialsSign {
|
||||
if (!(split[1].equalsIgnoreCase("exp") || split[1].equalsIgnoreCase("xp")) && getItemStack(split[1], stackamount, ess).getType() == Material.AIR) {
|
||||
throw new SignException(tl("moreThanZero"));
|
||||
}
|
||||
sign.setLine(index, stackamount + " " + split[1] + ":" + amount);
|
||||
final String newline = stackamount + " " + split[1] + ":" + amount;
|
||||
validateSignLength(newline);
|
||||
sign.setLine(index, newline);
|
||||
return;
|
||||
}
|
||||
throw new SignException(tl("invalidSignLine", index + 1));
|
||||
@@ -235,27 +238,26 @@ public class SignTrade extends EssentialsSign {
|
||||
}
|
||||
|
||||
if (split.length == 3) {
|
||||
final int stackAmount = getIntegerPositive(split[0]);
|
||||
if (split[1].equalsIgnoreCase("exp") || split[1].equalsIgnoreCase("xp")) {
|
||||
final int stackamount = getIntegerPositive(split[0]);
|
||||
int amount = getInteger(split[2]);
|
||||
if (amountType == AmountType.ROUNDED) {
|
||||
amount -= amount % stackamount;
|
||||
amount -= amount % stackAmount;
|
||||
}
|
||||
if (notEmpty && (amount < 1 || stackamount < 1)) {
|
||||
if (notEmpty && (amount < 1 || stackAmount < 1)) {
|
||||
throw new SignException(tl("tradeSignEmpty"));
|
||||
}
|
||||
return new Trade(amountType == AmountType.COST ? stackamount : amount, ess);
|
||||
return new Trade(amountType == AmountType.COST ? stackAmount : amount, ess);
|
||||
} else {
|
||||
final int stackamount = getIntegerPositive(split[0]);
|
||||
final ItemStack item = getItemStack(split[1], stackamount, allowId, ess);
|
||||
final ItemStack item = getItemStack(split[1], stackAmount, allowId, ess);
|
||||
int amount = getInteger(split[2]);
|
||||
if (amountType == AmountType.ROUNDED) {
|
||||
amount -= amount % stackamount;
|
||||
amount -= amount % stackAmount;
|
||||
}
|
||||
if (notEmpty && (amount < 1 || stackamount < 1 || item.getType() == Material.AIR || amount < stackamount)) {
|
||||
if (notEmpty && (amount < 1 || stackAmount < 1 || item.getType() == Material.AIR || amount < stackAmount)) {
|
||||
throw new SignException(tl("tradeSignEmpty"));
|
||||
}
|
||||
item.setAmount(amountType == AmountType.COST ? stackamount : amount);
|
||||
item.setAmount(amountType == AmountType.COST ? stackAmount : amount);
|
||||
return new Trade(item, ess);
|
||||
}
|
||||
}
|
||||
@@ -334,20 +336,18 @@ public class SignTrade extends EssentialsSign {
|
||||
}
|
||||
|
||||
if (split.length == 3) {
|
||||
final int stackAmount = getIntegerPositive(split[0]);
|
||||
if (split[1].equalsIgnoreCase("exp") || split[1].equalsIgnoreCase("xp")) {
|
||||
final int stackamount = getIntegerPositive(split[0]);
|
||||
final String newline = stackamount + " " + split[1] + ":" + value.intValueExact();
|
||||
final String newline = stackAmount + " " + split[1] + ":" + value.intValueExact();
|
||||
validateSignLength(newline);
|
||||
sign.setLine(index, newline);
|
||||
return;
|
||||
} else {
|
||||
final int stackamount = getIntegerPositive(split[0]);
|
||||
getItemStack(split[1], stackamount, ess);
|
||||
final String newline = stackamount + " " + split[1] + ":" + value.intValueExact();
|
||||
getItemStack(split[1], stackAmount, ess);
|
||||
final String newline = stackAmount + " " + split[1] + ":" + value.intValueExact();
|
||||
validateSignLength(newline);
|
||||
sign.setLine(index, newline);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw new SignException(tl("invalidSignLine", index + 1));
|
||||
}
|
||||
|
||||
Loaded 100 of 249 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user