mirror of
https://github.com/EssentialsX/Essentials.git
synced 2026-11-05 01:00:13 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8046b8594a | ||
|
|
6c64aaefec | ||
|
|
07fa87dc6a | ||
|
|
b58c98bea0 | ||
|
|
08e553bd1a | ||
|
|
e35fb82bc2 | ||
|
|
a92ca63ca9 | ||
|
|
cbfad7b320 | ||
|
|
c16987fb87 | ||
|
|
477f5a7841 | ||
|
|
6f149224d1 | ||
|
|
1a6ad2fdb0 | ||
|
|
76e511a774 | ||
|
|
9681933ec2 | ||
|
|
711bfed557 | ||
|
|
016a1b3421 | ||
|
|
01b9ec4a42 | ||
|
|
9b729dd091 | ||
|
|
0a73be2082 | ||
|
|
c668879070 | ||
|
|
c4d318b7d0 | ||
|
|
e7d9dbfbcf | ||
|
|
1be3daf0b5 | ||
|
|
8f86849aec | ||
|
|
0b4ee9e73e | ||
|
|
65f88834ba | ||
|
|
024c56efdd | ||
|
|
9c487b0aac | ||
|
|
d743f928ad | ||
|
|
07e2fe3af1 | ||
|
|
9f384c71f3 | ||
|
|
7a5aea0bcf | ||
|
|
b6c9bc1439 | ||
|
|
b7f38517ef | ||
|
|
60f54ee37d | ||
|
|
adf1273bf9 | ||
|
|
3c79e9e59d | ||
|
|
1ab1b5713e | ||
|
|
edf2f295d1 | ||
|
|
c043416b11 | ||
|
|
4a471f0a93 | ||
|
|
04a1d8197f | ||
|
|
d9bf099c3d | ||
|
|
d2f2140be9 | ||
|
|
04f88e460b | ||
|
|
d64f73e719 | ||
|
|
2ab4dcbc11 | ||
|
|
846043e9a0 | ||
|
|
ea57e4ae01 | ||
|
|
6aa5e5cc4a | ||
|
|
3e5bd4cf09 | ||
|
|
3d096c1f31 | ||
|
|
b5b6bce758 | ||
|
|
46ed8e954f | ||
|
|
cfca2f7550 | ||
|
|
a09df9bf3a | ||
|
|
dc2462c277 | ||
|
|
25c7ebcf39 | ||
|
|
baab65d776 | ||
|
|
9e2b906048 | ||
|
|
9f3c2683ae | ||
|
|
9e01a1a427 | ||
|
|
db729241c9 | ||
|
|
d5d8c80d74 | ||
|
|
4c48ccb422 | ||
|
|
53e7c83254 | ||
|
|
fdef1062f0 | ||
|
|
b9f8fc2e11 | ||
|
|
db410fb3e7 | ||
|
|
500dadc760 | ||
|
|
7d61953753 | ||
|
|
5b9b76d5e7 | ||
|
|
b9804d8980 | ||
|
|
b960ee365a | ||
|
|
302f0acbaa | ||
|
|
8f5b97b9d2 | ||
|
|
6371cf7517 | ||
|
|
e53520aef6 | ||
|
|
d59fd71ba5 | ||
|
|
4b967a749b | ||
|
|
8f88a8dcb3 | ||
|
|
a58ba406eb | ||
|
|
a93ca9b7bc | ||
|
|
02e6b5f1b3 | ||
|
|
63dd5f3f64 | ||
|
|
a3a50e9cd5 | ||
|
|
8e3c1aaa96 | ||
|
|
8b71437264 | ||
|
|
61d0ed3f01 | ||
|
|
fc2b7b63a2 | ||
|
|
96590a3389 | ||
|
|
a043de3e44 | ||
|
|
81d3900ef6 | ||
|
|
fd136384a1 | ||
|
|
dd5fe117b5 | ||
|
|
e9d29f789f | ||
|
|
1bc1f646fd | ||
|
|
8ad55cb634 | ||
|
|
b19dec120a | ||
|
|
283c088b21 | ||
|
|
d5ffed09b4 | ||
|
|
b7eec09307 | ||
|
|
23f0f98af3 | ||
|
|
6bbdbc89a6 | ||
|
|
12c8623666 | ||
|
|
2bd6ebd2b1 | ||
|
|
40fb496052 | ||
|
|
b72d822f94 | ||
|
|
6d92ac9af6 | ||
|
|
47f27a8016 | ||
|
|
849d095e9a | ||
|
|
923f240aa1 | ||
|
|
8655ff2de3 | ||
|
|
6f61010cf9 | ||
|
|
5082badca4 | ||
|
|
307bd2a35f | ||
|
|
a11552f497 | ||
|
|
8556caaeb4 | ||
|
|
7c09012b3d | ||
|
|
eb596caa00 | ||
|
|
ab4501aa4c | ||
|
|
4b766d373d | ||
|
|
e3574edc5d | ||
|
|
dcb69ddc73 | ||
|
|
1d6ad297a4 | ||
|
|
85a5e517c9 | ||
|
|
b08d380643 | ||
|
|
ad98fc4121 | ||
|
|
810689c037 | ||
|
|
c007700c59 | ||
|
|
8cc3f6626b | ||
|
|
a3b8a4adc9 | ||
|
|
8f817c089b | ||
|
|
ed4e7794c3 | ||
|
|
6f732d410e | ||
|
|
6c8da20883 | ||
|
|
c7d9ce7f7f | ||
|
|
4e7f639076 | ||
|
|
b2c3b3a99f | ||
|
|
77338d66dc | ||
|
|
e2130df596 | ||
|
|
2bbe6d6069 | ||
|
|
c8b8e505f3 | ||
|
|
89743f9900 | ||
|
|
dbc0562fb0 | ||
|
|
76f4dff14c | ||
|
|
baa2a2f24f | ||
|
|
2ca02911b3 | ||
|
|
cf48237049 | ||
|
|
adfe2c1975 | ||
|
|
a782043798 | ||
|
|
90c4a2f53c | ||
|
|
338b371e4c | ||
|
|
347179373d | ||
|
|
3bb45b80b1 | ||
|
|
e3ec0f3b9b | ||
|
|
f20572b30c | ||
|
|
2124cce603 | ||
|
|
ebf60c1e70 | ||
|
|
c31b6c3683 | ||
|
|
ffc83343fe | ||
|
|
2554acd304 | ||
|
|
98239114ad | ||
|
|
c10b39c1c7 | ||
|
|
20e11465e4 | ||
|
|
46e1b95b33 | ||
|
|
279d6f16e1 | ||
|
|
a747eccaa3 | ||
|
|
0bafbc3184 | ||
|
|
8069370b8c | ||
|
|
46f4b92ff7 | ||
|
|
d92f5ce71c | ||
|
|
2314bf8bd4 | ||
|
|
7808b21496 | ||
|
|
18ef412211 | ||
|
|
0678328253 | ||
|
|
5503e1e14c | ||
|
|
9e89cfa4ed | ||
|
|
13f454a022 | ||
|
|
129650dade | ||
|
|
6fa5b80c0a | ||
|
|
04dfcd0965 | ||
|
|
2e818ac709 | ||
|
|
32ef61197f | ||
|
|
fa06cd8253 | ||
|
|
5020983af5 | ||
|
|
f4496b6977 | ||
|
|
a1719d651e | ||
|
|
e7be2b68a3 | ||
|
|
552dcb56a1 | ||
|
|
e158a65603 | ||
|
|
b694e8aaa2 | ||
|
|
a2e09121ba | ||
|
|
4ce7dfa8f0 | ||
|
|
1c4ce7b4bd | ||
|
|
8a04c1e232 | ||
|
|
6e5d378324 | ||
|
|
8e1f3617fd | ||
|
|
2549ed830f | ||
|
|
0ebd64d314 | ||
|
|
843ecb4a42 | ||
|
|
a1a0d34940 | ||
|
|
15bb978dab | ||
|
|
6a7cf39548 | ||
|
|
8ccb70d07d | ||
|
|
45461a93b0 | ||
|
|
b3a54a78bc | ||
|
|
a4182b5ff9 | ||
|
|
215dcde4b9 | ||
|
|
67b2a9a4f4 | ||
|
|
3b51b23ac2 | ||
|
|
e0f19f8121 | ||
|
|
e720fb528a | ||
|
|
518a5454c6 | ||
|
|
2d9c846084 | ||
|
|
59e30f05fc | ||
|
|
0f1085a02d | ||
|
|
882699919e | ||
|
|
f6a70a542e | ||
|
|
785b1fe937 | ||
|
|
bae909ba10 | ||
|
|
dbb9757a9f | ||
|
|
deaeb46ce9 | ||
|
|
219012bc35 | ||
|
|
5f9eb22d23 | ||
|
|
2c33fb6834 | ||
|
|
8bcef6022b | ||
|
|
93d36779f0 | ||
|
|
2502f5e6f2 | ||
|
|
95f2852cf3 | ||
|
|
ff9f712d65 | ||
|
|
60c4e75a1c | ||
|
|
ccf7c48bf1 | ||
|
|
65d81eb31e | ||
|
|
b97eb12dfc | ||
|
|
d2724d77df | ||
|
|
119b21ac67 |
No files matched your search
+1
-1
@@ -1,10 +1,10 @@
|
||||
# Currently used
|
||||
patreon: EssentialsX
|
||||
ko_fi: essentialsx
|
||||
|
||||
# Currently not used
|
||||
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
#open_collective: # Replace with a single Open Collective username
|
||||
#ko_fi: # Replace with a single Ko-fi username
|
||||
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
#liberapay: # Replace with a single Liberapay username
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Build EssentialsX
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 2.x
|
||||
- mc/*
|
||||
pull_request:
|
||||
branches:
|
||||
- 2.x
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Git repo
|
||||
uses: actions/checkout@v1
|
||||
- name: Restore Maven cache
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Build with Maven
|
||||
run: mvn package --file pom.xml
|
||||
- name: Copy artifacts
|
||||
run: mkdir -p ./out/ && cp -t ./out/ **/target/Essentials*.jar
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: Plugin jars
|
||||
path: out/
|
||||
+2
-1
@@ -15,4 +15,5 @@
|
||||
|
||||
# Build files
|
||||
target/
|
||||
jars/
|
||||
jars/
|
||||
out/
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
language: java
|
||||
|
||||
jdk:
|
||||
- openjdk8
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- .buildtools
|
||||
- $HOME/.m2
|
||||
|
||||
before_install:
|
||||
- chmod +x scripts/buildtools.sh
|
||||
- scripts/buildtools.sh
|
||||
+35
-35
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>EssentialsXParent</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<version>2.18.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>EssentialsX</artifactId>
|
||||
@@ -49,69 +49,69 @@
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<groupId>com.github.milkbowl</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.luckperms</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>5.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.papermc</groupId>
|
||||
<artifactId>paperlib</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.4</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>NMSProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<artifactId>BaseProviders</artifactId>
|
||||
<version>2.18.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>UpdatedMetaProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8_R1Provider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
<artifactId>NMSReflectionProvider</artifactId>
|
||||
<version>2.18.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8_R2Provider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<artifactId>PaperProvider</artifactId>
|
||||
<version>2.18.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.destroystokyo.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8Provider</artifactId>
|
||||
<version>2.18.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>LegacyProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>ReflectionProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>FlattenedProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -13,6 +13,6 @@ Minecraft colors:
|
||||
&8 &&8 &9 &&9 &a &&a &b &&b
|
||||
&c &&c &d &&d &e &&e &f &&f
|
||||
&0
|
||||
&&k &kMagic&r &&l &lBold
|
||||
&&m &mStrike&r &&n &nUline
|
||||
&&o &oItalic&r &&r &rReset
|
||||
&&k &kMagic&r &&l &lBold&r
|
||||
&&m &mStrike&r &&n &nUline&r
|
||||
&&o &oItalic&r &&r &rReset
|
||||
@@ -46,15 +46,12 @@ public class AlternativeCommandsHandler {
|
||||
continue;
|
||||
}
|
||||
for (String label : labels) {
|
||||
List<PluginCommand> plugincommands = altcommands.get(label.toLowerCase(Locale.ENGLISH));
|
||||
if (plugincommands == null) {
|
||||
plugincommands = new ArrayList<>();
|
||||
altcommands.put(label.toLowerCase(Locale.ENGLISH), plugincommands);
|
||||
}
|
||||
List<PluginCommand> plugincommands = altcommands.computeIfAbsent(label.toLowerCase(Locale.ENGLISH), k -> new ArrayList<>());
|
||||
boolean found = false;
|
||||
for (PluginCommand pc2 : plugincommands) {
|
||||
if (pc2.getPlugin().equals(plugin)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
@@ -68,13 +65,7 @@ public class AlternativeCommandsHandler {
|
||||
final Iterator<Map.Entry<String, List<PluginCommand>>> iterator = altcommands.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final Map.Entry<String, List<PluginCommand>> entry = iterator.next();
|
||||
final Iterator<PluginCommand> pcIterator = entry.getValue().iterator();
|
||||
while (pcIterator.hasNext()) {
|
||||
final PluginCommand pc = pcIterator.next();
|
||||
if (pc.getPlugin() == null || pc.getPlugin().equals(plugin)) {
|
||||
pcIterator.remove();
|
||||
}
|
||||
}
|
||||
entry.getValue().removeIf(pc -> pc.getPlugin() == null || pc.getPlugin().equals(plugin));
|
||||
if (entry.getValue().isEmpty()) {
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,452 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.api.IAsyncTeleport;
|
||||
import com.earth2me.essentials.commands.WarpNotFoundException;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IUser;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import net.ess3.api.events.UserWarpEvent;
|
||||
import net.ess3.api.events.teleport.PreTeleportEvent;
|
||||
import net.ess3.api.events.teleport.TeleportWarmupEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class AsyncTeleport implements IAsyncTeleport {
|
||||
private final IUser teleportOwner;
|
||||
private final IEssentials ess;
|
||||
private AsyncTimedTeleport timedTeleport;
|
||||
|
||||
private TeleportType tpType;
|
||||
|
||||
public AsyncTeleport(IUser user, IEssentials ess) {
|
||||
this.teleportOwner = user;
|
||||
this.ess = ess;
|
||||
tpType = TeleportType.NORMAL;
|
||||
}
|
||||
|
||||
public enum TeleportType {
|
||||
TPA,
|
||||
BACK,
|
||||
NORMAL
|
||||
}
|
||||
|
||||
public void cooldown(boolean check) throws Throwable {
|
||||
CompletableFuture<Boolean> exceptionFuture = new CompletableFuture<>();
|
||||
if (cooldown(check, exceptionFuture)) {
|
||||
try {
|
||||
exceptionFuture.get();
|
||||
} catch (ExecutionException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean cooldown(boolean check, CompletableFuture<Boolean> future) {
|
||||
final Calendar time = new GregorianCalendar();
|
||||
if (teleportOwner.getLastTeleportTimestamp() > 0) {
|
||||
// Take the current time, and remove the delay from it.
|
||||
final double cooldown = ess.getSettings().getTeleportCooldown();
|
||||
final Calendar earliestTime = new GregorianCalendar();
|
||||
earliestTime.add(Calendar.SECOND, -(int) cooldown);
|
||||
earliestTime.add(Calendar.MILLISECOND, -(int) ((cooldown * 1000.0) % 1000.0));
|
||||
// This value contains the most recent time a teleportPlayer could have been used that would allow another use.
|
||||
final long earliestLong = earliestTime.getTimeInMillis();
|
||||
|
||||
// When was the last teleportPlayer used?
|
||||
final long lastTime = teleportOwner.getLastTeleportTimestamp();
|
||||
|
||||
if (lastTime > time.getTimeInMillis()) {
|
||||
// This is to make sure time didn't get messed up on last teleportPlayer use.
|
||||
// If this happens, let's give the user the benifit of the doubt.
|
||||
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
|
||||
return false;
|
||||
} else if (lastTime > earliestLong
|
||||
&& cooldownApplies()) {
|
||||
time.setTimeInMillis(lastTime);
|
||||
time.add(Calendar.SECOND, (int) cooldown);
|
||||
time.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0));
|
||||
future.completeExceptionally(new Exception(tl("timeBeforeTeleport", DateUtil.formatDateDiff(time.getTimeInMillis()))));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// if justCheck is set, don't update lastTeleport; we're just checking
|
||||
if (!check) {
|
||||
teleportOwner.setLastTeleportTimestamp(time.getTimeInMillis());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean cooldownApplies() {
|
||||
boolean applies = true;
|
||||
String globalBypassPerm = "essentials.teleport.cooldown.bypass";
|
||||
switch (tpType) {
|
||||
case NORMAL:
|
||||
applies = !teleportOwner.isAuthorized(globalBypassPerm);
|
||||
break;
|
||||
case BACK:
|
||||
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
|
||||
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.back"));
|
||||
break;
|
||||
case TPA:
|
||||
applies = !(teleportOwner.isAuthorized(globalBypassPerm) &&
|
||||
teleportOwner.isAuthorized("essentials.teleport.cooldown.bypass.tpa"));
|
||||
break;
|
||||
}
|
||||
return applies;
|
||||
}
|
||||
|
||||
private void warnUser(final IUser user, final double delay) {
|
||||
Calendar c = new GregorianCalendar();
|
||||
c.add(Calendar.SECOND, (int) delay);
|
||||
c.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0));
|
||||
user.sendMessage(tl("dontMoveMessage", DateUtil.formatDateDiff(c.getTimeInMillis())));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void now(Location loc, boolean cooldown, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
if (cooldown && cooldown(false, future)) {
|
||||
return;
|
||||
}
|
||||
final ITarget target = new LocationTarget(loc);
|
||||
nowAsync(teleportOwner, target, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void now(Player entity, boolean cooldown, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
if (cooldown && cooldown(false, future)) {
|
||||
future.complete(false);
|
||||
return;
|
||||
}
|
||||
final ITarget target = new PlayerTarget(entity);
|
||||
nowAsync(teleportOwner, target, cause, future);
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void runOnMain(Runnable runnable) throws ExecutionException, InterruptedException {
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
runnable.run();
|
||||
return;
|
||||
}
|
||||
CompletableFuture<Object> taskLock = new CompletableFuture<>();
|
||||
Bukkit.getScheduler().runTask(ess, () -> {
|
||||
runnable.run();
|
||||
taskLock.complete(new Object());
|
||||
});
|
||||
taskLock.get();
|
||||
}
|
||||
|
||||
protected void nowAsync(IUser teleportee, ITarget target, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
cancel(false);
|
||||
|
||||
PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
teleportee.setLastLocation();
|
||||
|
||||
if (!ess.getSettings().isForcePassengerTeleport() && !teleportee.getBase().isEmpty()) {
|
||||
if (!ess.getSettings().isTeleportPassengerDismount()) {
|
||||
future.completeExceptionally(new Exception(tl("passengerTeleportFail")));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
runOnMain(() -> teleportee.getBase().eject()); //EntityDismountEvent requires a sync context.
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
future.completeExceptionally(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
teleportee.setLastLocation();
|
||||
PaperLib.getChunkAtAsync(target.getLocation()).thenAccept(chunk -> {
|
||||
Location loc = target.getLocation();
|
||||
if (LocationUtil.isBlockUnsafeForUser(teleportee, chunk.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
|
||||
if (ess.getSettings().isTeleportSafetyEnabled()) {
|
||||
if (ess.getSettings().isForceDisableTeleportSafety()) {
|
||||
//The chunk we're teleporting to is 100% going to be loaded here, no need to teleport async.
|
||||
teleportee.getBase().teleport(loc, cause);
|
||||
} else {
|
||||
try {
|
||||
//There's a chance the safer location is outside the loaded chunk so still teleport async here.
|
||||
PaperLib.teleportAsync(teleportee.getBase(), LocationUtil.getSafeDestination(ess, teleportee, loc), cause);
|
||||
} catch (Exception e) {
|
||||
future.completeExceptionally(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
future.completeExceptionally(new Exception(tl("unsafeTeleportDestination", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (ess.getSettings().isForceDisableTeleportSafety()) {
|
||||
//The chunk we're teleporting to is 100% going to be loaded here, no need to teleport async.
|
||||
teleportee.getBase().teleport(loc, cause);
|
||||
} else {
|
||||
if (ess.getSettings().isTeleportToCenterLocation()) {
|
||||
loc = LocationUtil.getRoundedDestination(loc);
|
||||
}
|
||||
//There's a *small* chance the rounded destination produces a location outside the loaded chunk so still teleport async here.
|
||||
PaperLib.teleportAsync(teleportee.getBase(), loc, cause);
|
||||
}
|
||||
}
|
||||
future.complete(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(Location loc, Trade chargeFor, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
teleport(teleportOwner, new LocationTarget(loc), chargeFor, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleport(Player entity, Trade chargeFor, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
teleportOwner.sendMessage(tl("teleportToPlayer", entity.getDisplayName()));
|
||||
teleport(teleportOwner, new PlayerTarget(entity), chargeFor, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleportPlayer(IUser otherUser, Location loc, Trade chargeFor, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
teleport(otherUser, new LocationTarget(loc), chargeFor, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleportPlayer(IUser otherUser, Player entity, Trade chargeFor, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
ITarget target = new PlayerTarget(entity);
|
||||
teleport(otherUser, target, chargeFor, cause, future);
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
otherUser.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void teleport(IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
Trade cashCharge = chargeFor;
|
||||
|
||||
if (chargeFor != null) {
|
||||
chargeFor.isAffordableFor(teleportOwner, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world.
|
||||
if (!chargeFor.getCommandCost(teleportOwner).equals(BigDecimal.ZERO)) {
|
||||
//By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport.
|
||||
cashCharge = new Trade(chargeFor.getCommandCost(teleportOwner), ess);
|
||||
}
|
||||
}
|
||||
|
||||
if (cooldown(true, future)) {
|
||||
return;
|
||||
}
|
||||
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass") || teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
|
||||
if (cooldown(false, future)) {
|
||||
return;
|
||||
}
|
||||
nowAsync(teleportee, target, cause, future);
|
||||
if (cashCharge != null) {
|
||||
cashCharge.charge(teleportOwner, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(teleportee, delay);
|
||||
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
|
||||
}
|
||||
|
||||
private void teleportOther(IUser teleporter, IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
Trade cashCharge = chargeFor;
|
||||
|
||||
if (teleporter != null && chargeFor != null) {
|
||||
chargeFor.isAffordableFor(teleporter, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//This code is to make sure that commandcosts are checked in the initial world, and not in the resulting world.
|
||||
if (!chargeFor.getCommandCost(teleporter).equals(BigDecimal.ZERO)) {
|
||||
//By converting a command cost to a regular cost, the command cost permission isn't checked when executing the charge after teleport.
|
||||
cashCharge = new Trade(chargeFor.getCommandCost(teleporter), ess);
|
||||
}
|
||||
}
|
||||
|
||||
if (cooldown(true, future)) {
|
||||
return;
|
||||
}
|
||||
if (delay <= 0 || teleporter == null
|
||||
|| teleporter.isAuthorized("essentials.teleport.timer.bypass")
|
||||
|| teleportOwner.isAuthorized("essentials.teleport.timer.bypass")
|
||||
|| teleportee.isAuthorized("essentials.teleport.timer.bypass")) {
|
||||
if (cooldown(false, future)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nowAsync(teleportee, target, cause, future);
|
||||
if (teleporter != null && cashCharge != null) {
|
||||
cashCharge.charge(teleporter, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(teleportee, delay);
|
||||
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void respawn(Trade chargeFor, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
if (chargeFor != null) {
|
||||
chargeFor.isAffordableFor(teleportOwner, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (cooldown(true, future)) {
|
||||
return;
|
||||
}
|
||||
if (delay <= 0 || teleportOwner.isAuthorized("essentials.teleport.timer.bypass")) {
|
||||
if (cooldown(false, future)) {
|
||||
return;
|
||||
}
|
||||
respawnNow(teleportOwner, cause, future);
|
||||
if (chargeFor != null) {
|
||||
chargeFor.charge(teleportOwner, future);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(false);
|
||||
warnUser(teleportOwner, delay);
|
||||
initTimer((long) (delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
|
||||
}
|
||||
|
||||
void respawnNow(IUser teleportee, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
final Player player = teleportee.getBase();
|
||||
PaperLib.getBedSpawnLocationAsync(player, true).thenAccept(location -> {
|
||||
if (location != null) {
|
||||
nowAsync(teleportee, new LocationTarget(location), cause, future);
|
||||
} else {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Could not find bed spawn, forcing respawn event.");
|
||||
}
|
||||
final PlayerRespawnEvent pre = new PlayerRespawnEvent(player, player.getWorld().getSpawnLocation(), false);
|
||||
ess.getServer().getPluginManager().callEvent(pre);
|
||||
nowAsync(teleportee, new LocationTarget(pre.getRespawnLocation()), cause, future);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warp(IUser otherUser, String warp, Trade chargeFor, TeleportCause cause, CompletableFuture<Boolean> future) {
|
||||
UserWarpEvent event = new UserWarpEvent(otherUser, warp, chargeFor);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
warp = event.getWarp();
|
||||
Location loc;
|
||||
try {
|
||||
loc = ess.getWarps().getWarp(warp);
|
||||
} catch (WarpNotFoundException | InvalidWorldException e) {
|
||||
future.completeExceptionally(e);
|
||||
return;
|
||||
}
|
||||
otherUser.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
if (!otherUser.equals(teleportOwner)) {
|
||||
teleportOwner.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
}
|
||||
teleport(otherUser, new LocationTarget(loc), chargeFor, cause, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void back(Trade chargeFor, CompletableFuture<Boolean> future) {
|
||||
back(teleportOwner, chargeFor, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void back(IUser teleporter, Trade chargeFor, CompletableFuture<Boolean> future) {
|
||||
tpType = TeleportType.BACK;
|
||||
final Location loc = teleportOwner.getLastLocation();
|
||||
teleportOwner.sendMessage(tl("backUsageMsg", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
teleportOther(teleporter, teleportOwner, new LocationTarget(loc), chargeFor, TeleportCause.COMMAND, future);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void back(CompletableFuture<Boolean> future) {
|
||||
nowAsync(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND, future);
|
||||
}
|
||||
|
||||
public void setTpType(TeleportType tpType) {
|
||||
this.tpType = tpType;
|
||||
}
|
||||
|
||||
//If we need to cancelTimer a pending teleportPlayer call this method
|
||||
private void cancel(boolean notifyUser) {
|
||||
if (timedTeleport != null) {
|
||||
timedTeleport.cancelTimer(notifyUser);
|
||||
timedTeleport = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void initTimer(long delay, IUser teleportUser, ITarget target, Trade chargeFor, TeleportCause cause, boolean respawn) {
|
||||
timedTeleport = new AsyncTimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IUser;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class AsyncTimedTeleport implements Runnable {
|
||||
private static final double MOVE_CONSTANT = 0.3;
|
||||
private final IUser teleportOwner;
|
||||
private final IEssentials ess;
|
||||
private final AsyncTeleport teleport;
|
||||
private final UUID timer_teleportee;
|
||||
private int timer_task;
|
||||
private final long timer_started; // time this task was initiated
|
||||
private final long timer_delay; // how long to delay the teleportPlayer
|
||||
private double timer_health;
|
||||
// note that I initially stored a clone of the location for reference, but...
|
||||
// when comparing locations, I got incorrect mismatches (rounding errors, looked like)
|
||||
// so, the X/Y/Z values are stored instead and rounded off
|
||||
private final long timer_initX;
|
||||
private final long timer_initY;
|
||||
private final long timer_initZ;
|
||||
private final ITarget timer_teleportTarget;
|
||||
private final boolean timer_respawn;
|
||||
private final boolean timer_canMove;
|
||||
private final Trade timer_chargeFor;
|
||||
private final TeleportCause timer_cause;
|
||||
|
||||
AsyncTimedTeleport(IUser user, IEssentials ess, AsyncTeleport teleport, long delay, IUser teleportUser, ITarget target, Trade chargeFor, TeleportCause cause, boolean respawn) {
|
||||
this.teleportOwner = user;
|
||||
this.ess = ess;
|
||||
this.teleport = teleport;
|
||||
this.timer_started = System.currentTimeMillis();
|
||||
this.timer_delay = delay;
|
||||
this.timer_health = teleportUser.getBase().getHealth();
|
||||
this.timer_initX = Math.round(teleportUser.getBase().getLocation().getX() * MOVE_CONSTANT);
|
||||
this.timer_initY = Math.round(teleportUser.getBase().getLocation().getY() * MOVE_CONSTANT);
|
||||
this.timer_initZ = Math.round(teleportUser.getBase().getLocation().getZ() * MOVE_CONSTANT);
|
||||
this.timer_teleportee = teleportUser.getBase().getUniqueId();
|
||||
this.timer_teleportTarget = target;
|
||||
this.timer_chargeFor = chargeFor;
|
||||
this.timer_cause = cause;
|
||||
this.timer_respawn = respawn;
|
||||
this.timer_canMove = user.isAuthorized("essentials.teleport.timer.move");
|
||||
|
||||
timer_task = ess.runTaskTimerAsynchronously(this, 20, 20).getTaskId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
if (teleportOwner == null || !teleportOwner.getBase().isOnline() || teleportOwner.getBase().getLocation() == null) {
|
||||
cancelTimer(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final IUser teleportUser = ess.getUser(this.timer_teleportee);
|
||||
|
||||
if (teleportUser == null || !teleportUser.getBase().isOnline()) {
|
||||
cancelTimer(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final Location currLocation = teleportUser.getBase().getLocation();
|
||||
if (currLocation == null) {
|
||||
cancelTimer(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!timer_canMove && (Math.round(currLocation.getX() * MOVE_CONSTANT) != timer_initX || Math.round(currLocation.getY() * MOVE_CONSTANT) != timer_initY || Math.round(currLocation.getZ() * MOVE_CONSTANT) != timer_initZ || teleportUser.getBase().getHealth() < timer_health)) {
|
||||
// user moved, cancelTimer teleportPlayer
|
||||
cancelTimer(true);
|
||||
return;
|
||||
}
|
||||
|
||||
class DelayedTeleportTask implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
timer_health = teleportUser.getBase().getHealth(); // in case user healed, then later gets injured
|
||||
final long now = System.currentTimeMillis();
|
||||
if (now > timer_started + timer_delay) {
|
||||
try {
|
||||
teleport.cooldown(false);
|
||||
} catch (Throwable ex) {
|
||||
teleportOwner.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
|
||||
if (teleportOwner != teleportUser) {
|
||||
teleportUser.sendMessage(tl("cooldownWithMessage", ex.getMessage()));
|
||||
}
|
||||
}
|
||||
try {
|
||||
cancelTimer(false);
|
||||
teleportUser.sendMessage(tl("teleportationCommencing"));
|
||||
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
future.exceptionally(e -> {
|
||||
ess.showError(teleportOwner.getSource(), e, "\\ teleport");
|
||||
return false;
|
||||
});
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
if (timer_respawn) {
|
||||
teleport.respawnNow(teleportUser, timer_cause, future);
|
||||
} else {
|
||||
teleport.nowAsync(teleportUser, timer_teleportTarget, timer_cause, future);
|
||||
}
|
||||
future.thenAccept(success -> {
|
||||
if (timer_chargeFor != null) {
|
||||
try {
|
||||
timer_chargeFor.charge(teleportOwner);
|
||||
} catch (ChargeException ex) {
|
||||
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception ex) {
|
||||
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ess.scheduleSyncDelayedTask(new DelayedTeleportTask());
|
||||
}
|
||||
|
||||
//If we need to cancelTimer a pending teleportPlayer call this method
|
||||
void cancelTimer(boolean notifyUser) {
|
||||
if (timer_task == -1) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ess.getServer().getScheduler().cancelTask(timer_task);
|
||||
if (notifyUser) {
|
||||
teleportOwner.sendMessage(tl("pendingTeleportCancelled"));
|
||||
if (timer_teleportee != null && !timer_teleportee.equals(teleportOwner.getBase().getUniqueId())) {
|
||||
ess.getUser(timer_teleportee).sendMessage(tl("pendingTeleportCancelled"));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
timer_task = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import org.bukkit.command.CommandSender;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -20,17 +22,14 @@ public class Backup implements Runnable {
|
||||
private transient boolean running = false;
|
||||
private transient int taskId = -1;
|
||||
private transient boolean active = false;
|
||||
private final AtomicBoolean pendingShutdown = new AtomicBoolean(false);
|
||||
private transient CompletableFuture<Object> taskLock = null;
|
||||
|
||||
public Backup(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
server = ess.getServer();
|
||||
if (!ess.getOnlinePlayers().isEmpty()) {
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startTask();
|
||||
}
|
||||
});
|
||||
if (!ess.getOnlinePlayers().isEmpty() || ess.getSettings().isAlwaysRunBackup()) {
|
||||
ess.runTaskAsynchronously(this::startTask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,20 +56,30 @@ public class Backup implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<Object> getTaskLock() {
|
||||
return taskLock;
|
||||
}
|
||||
|
||||
public void setPendingShutdown(boolean shutdown) {
|
||||
pendingShutdown.set(shutdown);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
active = true;
|
||||
final String command = ess.getSettings().getBackupCommand();
|
||||
if (command == null || "".equals(command)) {
|
||||
return;
|
||||
}
|
||||
active = true;
|
||||
taskLock = new CompletableFuture<>();
|
||||
if ("save-all".equalsIgnoreCase(command)) {
|
||||
final CommandSender cs = server.getConsoleSender();
|
||||
server.dispatchCommand(cs, "save-all");
|
||||
active = false;
|
||||
taskLock.complete(new Object());
|
||||
return;
|
||||
}
|
||||
LOGGER.log(Level.INFO, tl("backupStarted"));
|
||||
@@ -78,52 +87,44 @@ public class Backup implements Runnable {
|
||||
server.dispatchCommand(cs, "save-all");
|
||||
server.dispatchCommand(cs, "save-off");
|
||||
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final ProcessBuilder childBuilder = new ProcessBuilder(command);
|
||||
childBuilder.redirectErrorStream(true);
|
||||
childBuilder.directory(ess.getDataFolder().getParentFile().getParentFile());
|
||||
final Process child = childBuilder.start();
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(child.getInputStream()));
|
||||
try {
|
||||
String line;
|
||||
do {
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
LOGGER.log(Level.INFO, line);
|
||||
}
|
||||
} while (line != null);
|
||||
} finally {
|
||||
reader.close();
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
final ProcessBuilder childBuilder = new ProcessBuilder(command);
|
||||
childBuilder.redirectErrorStream(true);
|
||||
childBuilder.directory(ess.getDataFolder().getParentFile().getParentFile());
|
||||
final Process child = childBuilder.start();
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
try {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(child.getInputStream()))) {
|
||||
String line;
|
||||
do {
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
LOGGER.log(Level.INFO, line);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
child.waitFor();
|
||||
} catch (InterruptedException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
class BackupEnableSaveTask implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
server.dispatchCommand(cs, "save-on");
|
||||
if (ess.getOnlinePlayers().isEmpty()) {
|
||||
stopTask();
|
||||
}
|
||||
active = false;
|
||||
LOGGER.log(Level.INFO, tl("backupFinished"));
|
||||
} while (line != null);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
});
|
||||
child.waitFor();
|
||||
} catch (InterruptedException | IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
class BackupEnableSaveTask implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
server.dispatchCommand(cs, "save-on");
|
||||
if (!ess.getSettings().isAlwaysRunBackup() && ess.getOnlinePlayers().isEmpty()) {
|
||||
stopTask();
|
||||
}
|
||||
active = false;
|
||||
taskLock.complete(new Object());
|
||||
LOGGER.log(Level.INFO, tl("backupFinished"));
|
||||
}
|
||||
}
|
||||
if (!pendingShutdown.get()) {
|
||||
ess.scheduleSyncDelayedTask(new BackupEnableSaveTask());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ import java.util.Set;
|
||||
|
||||
|
||||
public class Enchantments {
|
||||
private static final Map<String, Enchantment> ENCHANTMENTS = new HashMap<String, Enchantment>();
|
||||
private static final Map<String, Enchantment> ALIASENCHANTMENTS = new HashMap<String, Enchantment>();
|
||||
private static final Map<String, Enchantment> ENCHANTMENTS = new HashMap<>();
|
||||
private static final Map<String, Enchantment> ALIASENCHANTMENTS = new HashMap<>();
|
||||
private static boolean isFlat;
|
||||
|
||||
static {
|
||||
@@ -251,6 +251,15 @@ public class Enchantments {
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
|
||||
try { // 1.16
|
||||
Enchantment soulspeed = Enchantment.getByName("SOUL_SPEED");
|
||||
if (soulspeed != null) {
|
||||
ENCHANTMENTS.put("soulspeed", soulspeed);
|
||||
ALIASENCHANTMENTS.put("soilspeed", soulspeed);
|
||||
ALIASENCHANTMENTS.put("sandspeed", soulspeed);
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
|
||||
try {
|
||||
Class<?> namespacedKeyClass = Class.forName("org.bukkit.NamespacedKey");
|
||||
Class<?> enchantmentClass = Class.forName("org.bukkit.enchantments.Enchantment");
|
||||
|
||||
@@ -19,9 +19,10 @@ package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.commands.*;
|
||||
import com.earth2me.essentials.items.AbstractItemDb;
|
||||
import com.earth2me.essentials.items.CustomItemResolver;
|
||||
import com.earth2me.essentials.items.FlatItemDb;
|
||||
import com.earth2me.essentials.items.LegacyItemDb;
|
||||
import com.earth2me.essentials.metrics.Metrics;
|
||||
import com.earth2me.essentials.metrics.MetricsWrapper;
|
||||
import com.earth2me.essentials.perm.PermissionsHandler;
|
||||
import com.earth2me.essentials.register.payment.Methods;
|
||||
import com.earth2me.essentials.signs.SignBlockListener;
|
||||
@@ -32,35 +33,31 @@ import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
import net.ess3.api.*;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.ISettings;
|
||||
import net.ess3.nms.PotionMetaProvider;
|
||||
import net.ess3.nms.SpawnEggProvider;
|
||||
import net.ess3.nms.SpawnerProvider;
|
||||
import net.ess3.nms.flattened.FlatSpawnEggProvider;
|
||||
import net.ess3.nms.legacy.LegacyPotionMetaProvider;
|
||||
import net.ess3.nms.legacy.LegacySpawnEggProvider;
|
||||
import net.ess3.nms.legacy.LegacySpawnerProvider;
|
||||
import net.ess3.nms.refl.ReflSpawnEggProvider;
|
||||
import net.ess3.nms.updatedmeta.BasePotionDataProvider;
|
||||
import net.ess3.nms.updatedmeta.BlockMetaSpawnerProvider;
|
||||
import net.ess3.nms.v1_8_R1.v1_8_R1SpawnerProvider;
|
||||
import net.ess3.nms.v1_8_R2.v1_8_R2SpawnerProvider;
|
||||
import net.ess3.providers.ProviderFactory;
|
||||
import net.ess3.api.*;
|
||||
import net.ess3.nms.refl.providers.ReflServerStateProvider;
|
||||
import net.ess3.nms.refl.providers.ReflSpawnEggProvider;
|
||||
import net.ess3.provider.PotionMetaProvider;
|
||||
import net.ess3.provider.ProviderListener;
|
||||
import net.ess3.provider.ServerStateProvider;
|
||||
import net.ess3.provider.SpawnEggProvider;
|
||||
import net.ess3.provider.SpawnerProvider;
|
||||
import net.ess3.provider.providers.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
@@ -81,8 +78,10 @@ import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
@@ -97,37 +96,37 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
private transient List<IConf> confList;
|
||||
private transient Backup backup;
|
||||
private transient AbstractItemDb itemDb;
|
||||
private transient CustomItemResolver customItemResolver;
|
||||
private transient final Methods paymentMethod = new Methods();
|
||||
private transient PermissionsHandler permissionsHandler;
|
||||
private transient AlternativeCommandsHandler alternativeCommandsHandler;
|
||||
private transient UserMap userMap;
|
||||
private transient ExecuteTimer execTimer;
|
||||
private transient I18n i18n;
|
||||
private transient Metrics metrics;
|
||||
private transient MetricsWrapper metrics;
|
||||
private transient EssentialsTimer timer;
|
||||
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
|
||||
private transient Method oldGetOnlinePlayers;
|
||||
private transient SpawnerProvider spawnerProvider;
|
||||
private transient SpawnEggProvider spawnEggProvider;
|
||||
private transient PotionMetaProvider potionMetaProvider;
|
||||
private transient ServerStateProvider serverStateProvider;
|
||||
private transient ProviderListener recipeBookEventProvider;
|
||||
private transient Kits kits;
|
||||
private transient RandomTeleport randomTeleport;
|
||||
|
||||
public Essentials() {
|
||||
|
||||
}
|
||||
|
||||
protected Essentials(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
|
||||
super(loader, description, dataFolder, file);
|
||||
}
|
||||
|
||||
public Essentials(final Server server) {
|
||||
super(new JavaPluginLoader(server), new PluginDescriptionFile("Essentials", "", "com.earth2me.essentials.Essentials"), null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void forceLoadClasses() {
|
||||
try {
|
||||
Class.forName(OfflinePlayer.class.getName());
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISettings getSettings() {
|
||||
return settings;
|
||||
@@ -145,7 +144,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
i18n.onEnable();
|
||||
i18n.updateLocale("en");
|
||||
Console.setInstance(this);
|
||||
|
||||
|
||||
LOGGER.log(Level.INFO, tl("usingTempFolderForTesting"));
|
||||
LOGGER.log(Level.INFO, dataFolder.toString());
|
||||
settings = new Settings(this);
|
||||
@@ -169,7 +168,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
i18n = new I18n(this);
|
||||
i18n.onEnable();
|
||||
execTimer.mark("I18n1");
|
||||
|
||||
|
||||
Console.setInstance(this);
|
||||
|
||||
if (!VersionUtil.isServerSupported()) {
|
||||
@@ -190,8 +189,6 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
}
|
||||
}
|
||||
|
||||
forceLoadClasses();
|
||||
|
||||
try {
|
||||
final EssentialsUpgrade upgrade = new EssentialsUpgrade(this);
|
||||
upgrade.beforeSettings();
|
||||
@@ -216,36 +213,75 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
warps = new Warps(getServer(), this.getDataFolder());
|
||||
confList.add(warps);
|
||||
execTimer.mark("Init(Spawn/Warp)");
|
||||
execTimer.mark("Init(Warp)");
|
||||
|
||||
worth = new Worth(this.getDataFolder());
|
||||
confList.add(worth);
|
||||
execTimer.mark("Init(Worth)");
|
||||
|
||||
itemDb = getItemDbFromConfig();
|
||||
confList.add(itemDb);
|
||||
execTimer.mark("Init(Worth/ItemDB)");
|
||||
execTimer.mark("Init(ItemDB)");
|
||||
|
||||
randomTeleport = new RandomTeleport(this);
|
||||
if (randomTeleport.getPreCache()) {
|
||||
randomTeleport.cacheRandomLocations(randomTeleport.getCenter(), randomTeleport.getMinRange(), randomTeleport.getMaxRange());
|
||||
}
|
||||
confList.add(randomTeleport);
|
||||
execTimer.mark("Init(RandomTeleport)");
|
||||
|
||||
customItemResolver = new CustomItemResolver(this);
|
||||
try {
|
||||
itemDb.registerResolver(this, "custom_items", customItemResolver);
|
||||
confList.add(customItemResolver);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
customItemResolver = null;
|
||||
}
|
||||
execTimer.mark("Init(CustomItemResolver)");
|
||||
|
||||
jails = new Jails(this);
|
||||
confList.add(jails);
|
||||
execTimer.mark("Init(Jails)");
|
||||
|
||||
spawnerProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
BlockMetaSpawnerProvider.class,
|
||||
v1_8_R2SpawnerProvider.class,
|
||||
v1_8_R1SpawnerProvider.class,
|
||||
LegacySpawnerProvider.class
|
||||
), "mob spawner").getProvider();
|
||||
spawnEggProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
FlatSpawnEggProvider.class,
|
||||
ReflSpawnEggProvider.class,
|
||||
LegacySpawnEggProvider.class
|
||||
), "spawn egg").getProvider();
|
||||
potionMetaProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
BasePotionDataProvider.class,
|
||||
LegacyPotionMetaProvider.class
|
||||
), "potion meta").getProvider();
|
||||
//Spawner provider only uses one but it's here for legacy...
|
||||
spawnerProvider = new BlockMetaSpawnerProvider();
|
||||
|
||||
//Spawn Egg Providers
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_8_8_R01)) {
|
||||
spawnEggProvider = new LegacySpawnEggProvider();
|
||||
} else if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_12_2_R01)) {
|
||||
spawnEggProvider = new ReflSpawnEggProvider();
|
||||
} else {
|
||||
spawnEggProvider = new FlatSpawnEggProvider();
|
||||
}
|
||||
|
||||
//Potion Meta Provider
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_8_8_R01)) {
|
||||
potionMetaProvider = new LegacyPotionMetaProvider();
|
||||
} else {
|
||||
potionMetaProvider = new BasePotionDataProvider();
|
||||
}
|
||||
|
||||
//Server State Provider
|
||||
if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_2_R01)) {
|
||||
serverStateProvider = new PaperServerStateProvider();
|
||||
} else {
|
||||
serverStateProvider = new ReflServerStateProvider(getLogger());
|
||||
}
|
||||
|
||||
//Event Providers
|
||||
if (PaperLib.isPaper()) {
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent");
|
||||
recipeBookEventProvider = new PaperRecipeBookListener(event -> {
|
||||
if (this.getUser(((PlayerEvent) event).getPlayer()).isRecipeSee()) {
|
||||
((Cancellable) event).setCancelled(true);
|
||||
}
|
||||
});
|
||||
} catch (ClassNotFoundException ignored) {}
|
||||
}
|
||||
|
||||
execTimer.mark("Init(Providers)");
|
||||
reload();
|
||||
|
||||
@@ -265,6 +301,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
permissionsHandler = new PermissionsHandler(this, settings.useBukkitPermissions());
|
||||
alternativeCommandsHandler = new AlternativeCommandsHandler(this);
|
||||
|
||||
// Register hat permissions
|
||||
Commandhat.registerPermissionsIfNecessary(getServer().getPluginManager());
|
||||
|
||||
timer = new EssentialsTimer(this);
|
||||
scheduleSyncRepeatingTask(timer, 1000, 50);
|
||||
|
||||
@@ -274,12 +313,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
for (World w : Bukkit.getWorlds())
|
||||
addDefaultBackPermissionsToWorld(w);
|
||||
|
||||
metrics = new Metrics(this);
|
||||
if (metrics.isEnabled()) {
|
||||
getLogger().info("Starting Metrics. Opt-out using the global bStats config.");
|
||||
} else {
|
||||
getLogger().info("Metrics disabled per bStats config.");
|
||||
}
|
||||
metrics = new MetricsWrapper(this, 858, true);
|
||||
|
||||
final String timeroutput = execTimer.end();
|
||||
if (getSettings().isDebug()) {
|
||||
@@ -291,6 +325,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
handleCrash(ex);
|
||||
throw ex;
|
||||
}
|
||||
getBackup().setPendingShutdown(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -335,25 +370,49 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
pm.registerEvents(tntListener, this);
|
||||
|
||||
if (recipeBookEventProvider != null) {
|
||||
pm.registerEvents(recipeBookEventProvider, this);
|
||||
}
|
||||
|
||||
jails.resetListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
boolean stopping = getServerStateProvider().isStopping();
|
||||
if (!stopping) {
|
||||
LOGGER.log(Level.SEVERE, tl("serverReloading"));
|
||||
}
|
||||
getBackup().setPendingShutdown(true);
|
||||
for (User user : getOnlineUsers()) {
|
||||
if (user.isVanished()) {
|
||||
user.setVanished(false);
|
||||
user.sendMessage(tl("unvanishedReload"));
|
||||
}
|
||||
user.stopTransaction();
|
||||
if (stopping) {
|
||||
user.setLastLocation();
|
||||
if (!user.isHidden()) {
|
||||
user.setLastLogout(System.currentTimeMillis());
|
||||
}
|
||||
user.cleanup();
|
||||
} else {
|
||||
user.stopTransaction();
|
||||
}
|
||||
}
|
||||
cleanupOpenInventories();
|
||||
if (getBackup().getTaskLock() != null && !getBackup().getTaskLock().isDone()) {
|
||||
LOGGER.log(Level.SEVERE, tl("backupInProgress"));
|
||||
getBackup().getTaskLock().join();
|
||||
}
|
||||
if (i18n != null) {
|
||||
i18n.onDisable();
|
||||
}
|
||||
if (backup != null) {
|
||||
backup.stopTask();
|
||||
}
|
||||
|
||||
this.getPermissionsHandler().unregisterContexts();
|
||||
|
||||
Economy.setEss(null);
|
||||
Trade.closeLog();
|
||||
getUserMap().getUUIDMap().shutdown();
|
||||
@@ -371,6 +430,13 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
}
|
||||
|
||||
i18n.updateLocale(settings.getLocale());
|
||||
for (String commandName : this.getDescription().getCommands().keySet()) {
|
||||
Command command = this.getCommand(commandName);
|
||||
if (command != null) {
|
||||
command.setDescription(tl(commandName + "CommandDescription"));
|
||||
command.setUsage(tl(commandName + "CommandUsage"));
|
||||
}
|
||||
}
|
||||
|
||||
final PluginManager pm = getServer().getPluginManager();
|
||||
registerListeners(pm);
|
||||
@@ -379,7 +445,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String commandLabel, String[] args) {
|
||||
return onTabCompleteEssentials(sender, command, commandLabel, args, Essentials.class.getClassLoader(),
|
||||
"com.earth2me.essentials.commands.Command", "essentials.", null);
|
||||
"com.earth2me.essentials.commands.Command", "essentials.", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -455,6 +521,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(final CommandSender sender, final Command command, final String commandLabel, final String[] args) {
|
||||
metrics.markCommand(command.getName(), true);
|
||||
return onCommandEssentials(sender, command, commandLabel, args, Essentials.class.getClassLoader(), "com.earth2me.essentials.commands.Command", "essentials.", null);
|
||||
}
|
||||
|
||||
@@ -487,7 +554,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
}
|
||||
|
||||
if (bSenderBlock != null) {
|
||||
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)});
|
||||
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)});
|
||||
}
|
||||
} else if (user == null) {
|
||||
Bukkit.getLogger().log(Level.INFO, "{0} issued server command: /{1} {2}", new Object[]{cSender.getName(), commandLabel, EssentialsCommand.getFinalArg(args, 0)});
|
||||
}
|
||||
@@ -507,6 +576,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
// Check for disabled commands
|
||||
if (getSettings().isCommandDisabled(commandLabel)) {
|
||||
sender.sendMessage(tl("commandDisabled", commandLabel));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -545,9 +615,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
cmd.run(getServer(), user, commandLabel, command, args);
|
||||
}
|
||||
return true;
|
||||
} catch (NoChargeException ex) {
|
||||
return true;
|
||||
} catch (QuietAbortException ex) {
|
||||
} catch (NoChargeException | QuietAbortException ex) {
|
||||
return true;
|
||||
} catch (NotEnoughArgumentsException ex) {
|
||||
sender.sendMessage(command.getDescription());
|
||||
@@ -623,13 +691,8 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics getMetrics() {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetrics(Metrics metrics) {
|
||||
this.metrics = metrics;
|
||||
public RandomTeleport getRandomTeleport() {
|
||||
return randomTeleport;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@@ -742,20 +805,25 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final String message) {
|
||||
return broadcastMessage(null, null, message, true);
|
||||
return broadcastMessage(null, null, message, true, u -> false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final IUser sender, final String message) {
|
||||
return broadcastMessage(sender, null, message, false);
|
||||
return broadcastMessage(sender, null, message, false, u -> false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final IUser sender, final String message, final Predicate<IUser> shouldExclude) {
|
||||
return broadcastMessage(sender, null, message, false, shouldExclude);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final String permission, final String message) {
|
||||
return broadcastMessage(null, permission, message, false);
|
||||
return broadcastMessage(null, permission, message, false, u -> false);
|
||||
}
|
||||
|
||||
private int broadcastMessage(final IUser sender, final String permission, final String message, final boolean keywords) {
|
||||
private int broadcastMessage(final IUser sender, final String permission, final String message, final boolean keywords, final Predicate<IUser> shouldExclude) {
|
||||
if (sender != null && sender.isHidden()) {
|
||||
return 0;
|
||||
}
|
||||
@@ -763,10 +831,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
IText broadcast = new SimpleTextInput(message);
|
||||
|
||||
final Collection<Player> players = getOnlinePlayers();
|
||||
|
||||
for (Player player : players) {
|
||||
final User user = getUser(player);
|
||||
if ((permission == null && (sender == null || !user.isIgnoredPlayer(sender))) || (permission != null && user.isAuthorized(permission))) {
|
||||
if (shouldExclude.test(user)) {
|
||||
continue;
|
||||
}
|
||||
if (keywords) {
|
||||
broadcast = new KeywordReplacer(broadcast, new CommandSource(player), this, false);
|
||||
}
|
||||
@@ -871,13 +941,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
|
||||
@Override
|
||||
public Iterable<User> getOnlineUsers() {
|
||||
return Iterables.transform(getOnlinePlayers(), new Function<Player, User>() {
|
||||
|
||||
@Override
|
||||
public User apply(Player player) {
|
||||
return getUser(player);
|
||||
}
|
||||
});
|
||||
return getOnlinePlayers().stream().map(this::getUser).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -895,6 +959,16 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
return potionMetaProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomItemResolver getCustomItemResolver() {
|
||||
return customItemResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerStateProvider getServerStateProvider() {
|
||||
return serverStateProvider;
|
||||
}
|
||||
|
||||
private static void addDefaultBackPermissionsToWorld(World w) {
|
||||
String permName = "essentials.back.into." + w.getName();
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.CreatureSpawner;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.earth2me.essentials;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@@ -14,11 +14,13 @@ import org.bukkit.util.Vector;
|
||||
import java.io.*;
|
||||
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.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -36,7 +38,7 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
protected static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
protected final File configFile;
|
||||
protected String templateName = null;
|
||||
protected static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
protected static final Charset UTF8 = StandardCharsets.UTF_8;
|
||||
private Class<?> resourceClass = EssentialsConf.class;
|
||||
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
|
||||
private final AtomicInteger pendingDiskWrites = new AtomicInteger(0);
|
||||
@@ -108,20 +110,21 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
if (length > buffer.remaining()) {
|
||||
ByteBuffer resize = ByteBuffer.allocate(buffer.capacity() + length - buffer.remaining());
|
||||
int resizePosition = buffer.position();
|
||||
buffer.rewind();
|
||||
// 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.rewind();
|
||||
((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.rewind();
|
||||
data.clear();
|
||||
((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);
|
||||
@@ -134,7 +137,7 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
decoder.flush(data);
|
||||
}
|
||||
final int end = data.position();
|
||||
data.rewind();
|
||||
((Buffer) data).rewind();
|
||||
super.loadFromString(data.subSequence(0, end).toString());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
@@ -437,9 +440,7 @@ public class EssentialsConf extends YamlConfiguration {
|
||||
} else {
|
||||
try {
|
||||
return new BigDecimal(input, MathContext.DECIMAL128);
|
||||
} catch (NumberFormatException e) {
|
||||
return def;
|
||||
} catch (ArithmeticException e) {
|
||||
} catch (NumberFormatException | ArithmeticException e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -127,7 +130,11 @@ public class EssentialsEntityListener implements Listener {
|
||||
if (event.getCombuster() instanceof Arrow && event.getEntity() instanceof Player) {
|
||||
Arrow combuster = (Arrow) event.getCombuster();
|
||||
if (combuster.getShooter() instanceof Player) {
|
||||
final User srcCombuster = ess.getUser(((Player) combuster.getShooter()).getUniqueId());
|
||||
Player shooter = (Player) combuster.getShooter();
|
||||
if (shooter.hasMetadata("NPC")) {
|
||||
return;
|
||||
}
|
||||
final User srcCombuster = ess.getUser(shooter.getUniqueId());
|
||||
if (srcCombuster.isGodModeEnabled() && !srcCombuster.isAuthorized("essentials.god.pvp")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@@ -140,7 +147,15 @@ public class EssentialsEntityListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerDeathEvent(final PlayerDeathEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity.hasMetadata("NPC")) {
|
||||
return;
|
||||
}
|
||||
final User user = ess.getUser(event.getEntity());
|
||||
if (ess.getSettings().infoAfterDeath()) {
|
||||
final Location loc = user.getLocation();
|
||||
user.sendMessage(tl("infoAfterDeath", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
}
|
||||
if (user.isAuthorized("essentials.back.ondeath") && !ess.getSettings().isCommandDisabled("back")) {
|
||||
user.setLastLocation();
|
||||
user.sendMessage(tl("backAfterDeath"));
|
||||
@@ -165,6 +180,57 @@ public class EssentialsEntityListener implements Listener {
|
||||
if (user.isAuthorized("essentials.keepinv")) {
|
||||
event.setKeepInventory(true);
|
||||
event.getDrops().clear();
|
||||
ISettings.KeepInvPolicy vanish = ess.getSettings().getVanishingItemsPolicy();
|
||||
ISettings.KeepInvPolicy bind = ess.getSettings().getBindingItemsPolicy();
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01) && (vanish != ISettings.KeepInvPolicy.KEEP || bind != ISettings.KeepInvPolicy.KEEP)) {
|
||||
for (ItemStack stack : event.getEntity().getInventory()) {
|
||||
if (stack != null) {
|
||||
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
|
||||
if (vanish == ISettings.KeepInvPolicy.DELETE) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
} else if (vanish == ISettings.KeepInvPolicy.DROP) {
|
||||
event.getDrops().add(stack);
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
}
|
||||
}
|
||||
if (stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE)) {
|
||||
if (bind == ISettings.KeepInvPolicy.DELETE) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
} else if (bind == ISettings.KeepInvPolicy.DROP) {
|
||||
event.getEntity().getInventory().remove(stack);
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemStack[] armor = event.getEntity().getInventory().getArmorContents();
|
||||
for (int i = 0; i < armor.length; i++) {
|
||||
ItemStack stack = armor[i];
|
||||
if (stack != null) {
|
||||
if (stack.getEnchantments().containsKey(Enchantment.VANISHING_CURSE)) {
|
||||
if (vanish == ISettings.KeepInvPolicy.DELETE) {
|
||||
armor[i] = null;
|
||||
} else if (vanish == ISettings.KeepInvPolicy.DROP) {
|
||||
if (!event.getDrops().contains(stack)) {
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
armor[i] = null;
|
||||
}
|
||||
}
|
||||
if (stack.getEnchantments().containsKey(Enchantment.BINDING_CURSE)) {
|
||||
if (bind == ISettings.KeepInvPolicy.DELETE) {
|
||||
armor[i] = null;
|
||||
} else if (bind == ISettings.KeepInvPolicy.DROP) {
|
||||
if (!event.getDrops().contains(stack)) {
|
||||
event.getDrops().add(stack);
|
||||
}
|
||||
armor[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
event.getEntity().getInventory().setArmorContents(armor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.commands.Commandfireball;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.TextInput;
|
||||
@@ -7,8 +8,10 @@ import com.earth2me.essentials.textreader.TextPager;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
@@ -29,6 +32,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
@@ -47,9 +51,40 @@ public class EssentialsPlayerListener implements Listener {
|
||||
this.ess = parent;
|
||||
}
|
||||
|
||||
private static boolean isEntityPickupEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.entity.EntityPickupItemEvent");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCommandSendEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerCommandSendEvent");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isArrowPickupEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerPickupArrowEvent");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
ess.getServer().getPluginManager().registerEvents(this, ess);
|
||||
|
||||
if (isArrowPickupEvent()) {
|
||||
ess.getServer().getPluginManager().registerEvents(new ArrowPickupListener(), ess);
|
||||
}
|
||||
|
||||
if (isEntityPickupEvent()) {
|
||||
ess.getServer().getPluginManager().registerEvents(new PickupListener1_12(), ess);
|
||||
} else {
|
||||
@@ -78,7 +113,12 @@ public class EssentialsPlayerListener implements Listener {
|
||||
if (user.isMuted()) {
|
||||
event.setCancelled(true);
|
||||
|
||||
user.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
String dateDiff = user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
user.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
} else {
|
||||
user.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
|
||||
LOGGER.info(tl("mutedUserSpeaks", user.getName(), event.getMessage()));
|
||||
}
|
||||
@@ -147,15 +187,16 @@ public class EssentialsPlayerListener implements Listener {
|
||||
public void onPlayerQuit(final PlayerQuitEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
|
||||
if (ess.getSettings().allowSilentJoinQuit() && user.isAuthorized("essentials.silentquit")) {
|
||||
if (hideJoinQuitMessages() || (ess.getSettings().allowSilentJoinQuit() && user.isAuthorized("essentials.silentquit"))) {
|
||||
event.setQuitMessage(null);
|
||||
} else if (ess.getSettings().isCustomQuitMessage() && event.getQuitMessage() != null) {
|
||||
final Player player = event.getPlayer();
|
||||
final String msg = ess.getSettings().getCustomQuitMessage()
|
||||
.replace("{PLAYER}", player.getDisplayName())
|
||||
.replace("{USERNAME}", player.getName())
|
||||
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()));
|
||||
|
||||
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()))
|
||||
.replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()));
|
||||
|
||||
event.setQuitMessage(msg.isEmpty() ? null : msg);
|
||||
}
|
||||
|
||||
@@ -180,7 +221,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
user.updateActivity(false);
|
||||
user.updateActivity(false, AfkStatusChangeEvent.Cause.QUIT);
|
||||
if (!user.isHidden()) {
|
||||
user.setLastLogout(System.currentTimeMillis());
|
||||
}
|
||||
@@ -192,17 +233,17 @@ public class EssentialsPlayerListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerJoin(final PlayerJoinEvent event) {
|
||||
final String joinMessage = event.getJoinMessage();
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
delayedJoin(event.getPlayer(), joinMessage);
|
||||
}
|
||||
});
|
||||
if (ess.getSettings().allowSilentJoinQuit() || ess.getSettings().isCustomJoinMessage()) {
|
||||
ess.runTaskAsynchronously(() -> delayedJoin(event.getPlayer(), joinMessage));
|
||||
|
||||
if (hideJoinQuitMessages() || ess.getSettings().allowSilentJoinQuit() || ess.getSettings().isCustomJoinMessage()) {
|
||||
event.setJoinMessage(null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hideJoinQuitMessages() {
|
||||
return ess.getSettings().hasJoinQuitMessagePlayerCount() && ess.getServer().getOnlinePlayers().size() > ess.getSettings().getJoinQuitMessagePlayerCount();
|
||||
}
|
||||
|
||||
public void delayedJoin(final Player player, final String message) {
|
||||
if (!player.isOnline()) {
|
||||
return;
|
||||
@@ -218,7 +259,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
dUser.checkMuteTimeout(currentTime);
|
||||
dUser.updateActivity(false);
|
||||
dUser.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN);
|
||||
dUser.stopTransaction();
|
||||
|
||||
class DelayJoinTask implements Runnable {
|
||||
@@ -257,13 +298,14 @@ public class EssentialsPlayerListener implements Listener {
|
||||
if (user.isAuthorized("essentials.silentjoin.vanish")) {
|
||||
user.setVanished(true);
|
||||
}
|
||||
} else if (message == null) {
|
||||
} else if (message == null || hideJoinQuitMessages()) {
|
||||
//NOOP
|
||||
} else if (ess.getSettings().isCustomJoinMessage()) {
|
||||
String msg = ess.getSettings().getCustomJoinMessage()
|
||||
.replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName())
|
||||
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers()))
|
||||
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()));
|
||||
.replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName())
|
||||
.replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUserMap().getUniqueUsers()))
|
||||
.replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size()))
|
||||
.replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime()));
|
||||
if (!msg.isEmpty()) {
|
||||
ess.getServer().broadcastMessage(msg);
|
||||
}
|
||||
@@ -315,7 +357,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
user.setGodModeEnabled(false);
|
||||
ess.getLogger().log(Level.INFO, "Set god mode to false for {0} because they had it enabled without permission.", user.getName());
|
||||
}
|
||||
|
||||
|
||||
user.setConfirmingClearCommand(null);
|
||||
user.getConfirmingPayments().clear();
|
||||
|
||||
@@ -323,7 +365,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
|
||||
class DelayMotdTask implements Runnable {
|
||||
private User user;
|
||||
private final User user;
|
||||
|
||||
public DelayMotdTask(User user) {
|
||||
this.user = user;
|
||||
@@ -366,11 +408,14 @@ public class EssentialsPlayerListener implements Listener {
|
||||
|
||||
Location loc = user.getHome(user.getLocation());
|
||||
if (loc == null) {
|
||||
loc = user.getBase().getBedSpawnLocation();
|
||||
}
|
||||
if (loc != null) {
|
||||
user.getBase().setCompassTarget(loc);
|
||||
PaperLib.getBedSpawnLocationAsync(user.getBase(), false).thenAccept(location -> {
|
||||
if (location != null) {
|
||||
user.getBase().setCompassTarget(location);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
user.getBase().setCompassTarget(loc);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
@@ -419,9 +464,13 @@ public class EssentialsPlayerListener implements Listener {
|
||||
final boolean backListener = ess.getSettings().registerBackInListener();
|
||||
final boolean teleportInvulnerability = ess.getSettings().isTeleportInvulnerability();
|
||||
if (backListener || teleportInvulnerability) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
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 (backListener && (event.getCause() == TeleportCause.PLUGIN || event.getCause() == TeleportCause.COMMAND)) {
|
||||
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)) {
|
||||
@@ -445,12 +494,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.hasUnlimited(new ItemStack(event.getBucket()))) {
|
||||
event.getItemStack().setType(event.getBucket());
|
||||
ess.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
});
|
||||
ess.scheduleSyncDelayedTask(user.getBase()::updateInventory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,13 +523,19 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
if (ess.getUser(player).isMuted() && (ess.getSettings().getMuteCommands().contains(cmd) || ess.getSettings().getMuteCommands().contains("*"))) {
|
||||
final User user = ess.getUser(player);
|
||||
if (user.isMuted() && (ess.getSettings().getMuteCommands().contains(cmd) || ess.getSettings().getMuteCommands().contains("*"))) {
|
||||
event.setCancelled(true);
|
||||
player.sendMessage(tl("voiceSilenced"));
|
||||
String dateDiff = user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
player.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
} else {
|
||||
player.sendMessage(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
LOGGER.info(tl("mutedUserSpeaks", player.getName(), event.getMessage()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
boolean broadcast = true; // whether to broadcast the updated activity
|
||||
boolean update = true; // Only modified when the command is afk
|
||||
|
||||
@@ -498,22 +548,22 @@ public class EssentialsPlayerListener implements Listener {
|
||||
broadcast = false;
|
||||
}
|
||||
}
|
||||
final User user = ess.getUser(player);
|
||||
|
||||
if (update) {
|
||||
user.updateActivityOnInteract(broadcast);
|
||||
}
|
||||
|
||||
if (ess.getSettings().isCommandCooldownsEnabled() && pluginCommand != null
|
||||
&& !user.isAuthorized("essentials.commandcooldowns.bypass")) {
|
||||
&& !user.isAuthorized("essentials.commandcooldowns.bypass")) {
|
||||
int argStartIndex = event.getMessage().indexOf(" ");
|
||||
String args = argStartIndex == -1 ? "" // No arguments present
|
||||
: " " + event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there.
|
||||
String args = argStartIndex == -1 ? "" // No arguments present
|
||||
: " " + event.getMessage().substring(argStartIndex); // arguments start at argStartIndex; substring from there.
|
||||
String fullCommand = pluginCommand.getName() + args;
|
||||
|
||||
// Used to determine whether a user already has an existing cooldown
|
||||
// If so, no need to check for (and write) new ones.
|
||||
boolean cooldownFound = false;
|
||||
|
||||
|
||||
// Iterate over a copy of getCommandCooldowns in case of concurrent modifications
|
||||
for (Entry<Pattern, Long> entry : new HashMap<>(user.getCommandCooldowns()).entrySet()) {
|
||||
// Remove any expired cooldowns
|
||||
@@ -549,27 +599,31 @@ public class EssentialsPlayerListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onPlayerChangedWorldFlyReset(final PlayerChangedWorldEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.getBase().getGameMode() != GameMode.CREATIVE
|
||||
// COMPAT: String compare for 1.7.10
|
||||
&& !user.getBase().getGameMode().name().equals("SPECTATOR")
|
||||
&& !user.isAuthorized("essentials.fly")) {
|
||||
user.getBase().setFallDistance(0f);
|
||||
user.getBase().setAllowFlight(false);
|
||||
}
|
||||
if (!user.isAuthorized("essentials.speed")) {
|
||||
user.getBase().setFlySpeed(0.1f);
|
||||
user.getBase().setWalkSpeed(0.2f);
|
||||
} else {
|
||||
if (user.getBase().getFlySpeed() > ess.getSettings().getMaxFlySpeed() && !user.isAuthorized("essentials.speed.bypass")) {
|
||||
user.getBase().setFlySpeed((float) ess.getSettings().getMaxFlySpeed());
|
||||
} else {
|
||||
user.getBase().setFlySpeed(user.getBase().getFlySpeed() * 0.99999f);
|
||||
}
|
||||
|
||||
if (user.getBase().getWalkSpeed() > ess.getSettings().getMaxWalkSpeed() && !user.isAuthorized("essentials.speed.bypass")) {
|
||||
user.getBase().setWalkSpeed((float) ess.getSettings().getMaxWalkSpeed());
|
||||
if (ess.getSettings().isWorldChangeFlyResetEnabled()) {
|
||||
if (user.getBase().getGameMode() != GameMode.CREATIVE
|
||||
// COMPAT: String compare for 1.7.10
|
||||
&& !user.getBase().getGameMode().name().equals("SPECTATOR")
|
||||
&& !user.isAuthorized("essentials.fly")) {
|
||||
user.getBase().setFallDistance(0f);
|
||||
user.getBase().setAllowFlight(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (ess.getSettings().isWorldChangeSpeedResetEnabled()) {
|
||||
if (!user.isAuthorized("essentials.speed")) {
|
||||
user.getBase().setFlySpeed(0.1f);
|
||||
user.getBase().setWalkSpeed(0.2f);
|
||||
} else {
|
||||
user.getBase().setWalkSpeed(user.getBase().getWalkSpeed() * 0.99999f);
|
||||
if (user.getBase().getFlySpeed() > ess.getSettings().getMaxFlySpeed() && !user.isAuthorized("essentials.speed.bypass")) {
|
||||
user.getBase().setFlySpeed((float) ess.getSettings().getMaxFlySpeed());
|
||||
} else {
|
||||
user.getBase().setFlySpeed(user.getBase().getFlySpeed() * 0.99999f);
|
||||
}
|
||||
|
||||
if (user.getBase().getWalkSpeed() > ess.getSettings().getMaxWalkSpeed() && !user.isAuthorized("essentials.speed.bypass")) {
|
||||
user.getBase().setWalkSpeed((float) ess.getSettings().getMaxWalkSpeed());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -604,7 +658,10 @@ public class EssentialsPlayerListener implements Listener {
|
||||
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());
|
||||
player.sendMessage(tl("bedSet", player.getLocation().getWorld().getName(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()));
|
||||
// In 1.15 and above, vanilla sends its own bed spawn message.
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_15_R01)) {
|
||||
player.sendMessage(tl("bedSet", player.getLocation().getWorld().getName(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -627,6 +684,8 @@ public class EssentialsPlayerListener implements Listener {
|
||||
case PHYSICAL:
|
||||
updateActivity = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (updateActivity) {
|
||||
@@ -668,7 +727,6 @@ public class EssentialsPlayerListener implements Listener {
|
||||
// We need to loop through each command and execute
|
||||
for (final String command : commandList) {
|
||||
if (command.contains("{player}")) {
|
||||
continue;
|
||||
} else if (command.startsWith("c:")) {
|
||||
used = true;
|
||||
user.getBase().chat(command.substring(2));
|
||||
@@ -705,7 +763,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
if (type == InventoryType.PLAYER) {
|
||||
final User user = ess.getUser((Player) event.getWhoClicked());
|
||||
final InventoryHolder invHolder = top.getHolder();
|
||||
if (invHolder != null && invHolder instanceof HumanEntity) {
|
||||
if (invHolder instanceof HumanEntity) {
|
||||
final User invOwner = ess.getUser((Player) invHolder);
|
||||
if (user.isInvSee() && (!user.isAuthorized("essentials.invsee.modify") || invOwner.isAuthorized("essentials.invsee.preventmodify") || !invOwner.getBase().isOnline())) {
|
||||
event.setCancelled(true);
|
||||
@@ -727,15 +785,15 @@ public class EssentialsPlayerListener implements Listener {
|
||||
} else if (type == InventoryType.CHEST && top.getSize() == 9) {
|
||||
final User user = ess.getUser((Player) event.getWhoClicked());
|
||||
final InventoryHolder invHolder = top.getHolder();
|
||||
if (invHolder != null && invHolder instanceof HumanEntity && user.isInvSee()) {
|
||||
if (invHolder instanceof HumanEntity && user.isInvSee()) {
|
||||
event.setCancelled(true);
|
||||
refreshPlayer = user.getBase();
|
||||
}
|
||||
} else if (clickedInventory != null && clickedInventory.getType() == InventoryType.PLAYER) {
|
||||
if (ess.getSettings().isDirectHatAllowed() && event.getClick() == ClickType.LEFT && event.getSlot() == 39
|
||||
&& event.getCursor().getType() != Material.AIR && event.getCursor().getType().getMaxDurability() == 0
|
||||
&& !MaterialUtil.isSkull(event.getCursor().getType())
|
||||
&& ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat")) {
|
||||
&& event.getCursor().getType() != Material.AIR && event.getCursor().getType().getMaxDurability() == 0
|
||||
&& !MaterialUtil.isSkull(event.getCursor().getType())
|
||||
&& ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat") && !ess.getUser(event.getWhoClicked()).isAuthorized("essentials.hat.prevent-type." + event.getCursor().getType().name().toLowerCase())) {
|
||||
event.setCancelled(true);
|
||||
final PlayerInventory inv = (PlayerInventory) clickedInventory;
|
||||
final ItemStack head = inv.getHelmet();
|
||||
@@ -745,13 +803,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
|
||||
if (refreshPlayer != null) {
|
||||
final Player player = refreshPlayer;
|
||||
ess.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.updateInventory();
|
||||
}
|
||||
}, 1);
|
||||
ess.scheduleSyncDelayedTask(refreshPlayer::updateInventory, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -777,7 +829,7 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
} else if (type == InventoryType.CHEST && top.getSize() == 9) {
|
||||
final InventoryHolder invHolder = top.getHolder();
|
||||
if (invHolder != null && invHolder instanceof HumanEntity) {
|
||||
if (invHolder instanceof HumanEntity) {
|
||||
final User user = ess.getUser((Player) event.getPlayer());
|
||||
user.setInvSee(false);
|
||||
refreshPlayer = user.getBase();
|
||||
@@ -785,44 +837,31 @@ public class EssentialsPlayerListener implements Listener {
|
||||
}
|
||||
|
||||
if (refreshPlayer != null) {
|
||||
final Player player = refreshPlayer;
|
||||
ess.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.updateInventory();
|
||||
}
|
||||
}, 1);
|
||||
ess.scheduleSyncDelayedTask(refreshPlayer::updateInventory, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlayerFishEvent(final PlayerFishEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
user.updateActivityOnInteract(true);
|
||||
user.updateActivityOnInteract(true);
|
||||
}
|
||||
|
||||
private static boolean isEntityPickupEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.entity.EntityPickupItemEvent");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCommandSendEvent() {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.PlayerCommandSendEvent");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
return false;
|
||||
private final class ArrowPickupListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onArrowPickup(final org.bukkit.event.player.PlayerPickupArrowEvent event) {
|
||||
if (event.getItem().hasMetadata(Commandfireball.FIREBALL_META_KEY)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class PickupListenerPre1_12 implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onPlayerPickupItem(final org.bukkit.event.player.PlayerPickupItemEvent event) {
|
||||
if (ess.getSettings().getDisableItemPickupWhileAfk()) {
|
||||
if (event.getItem().hasMetadata(Commandfireball.FIREBALL_META_KEY)) {
|
||||
event.setCancelled(true);
|
||||
} else if (ess.getSettings().getDisableItemPickupWhileAfk()) {
|
||||
if (ess.getUser(event.getPlayer()).isAfk()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@@ -846,30 +885,40 @@ public class EssentialsPlayerListener implements Listener {
|
||||
public void onCommandSend(final PlayerCommandSendEvent event) {
|
||||
User user = ess.getUser(event.getPlayer());
|
||||
|
||||
ArrayList<String> removedCmds = new ArrayList<>(event.getCommands());
|
||||
Set<PluginCommand> checked = new HashSet<>();
|
||||
Set<PluginCommand> toRemove = new HashSet<>();
|
||||
|
||||
event.getCommands().removeIf(str -> shouldHideFromUser(str, user));
|
||||
event.getCommands().removeIf(label -> {
|
||||
if (isEssentialsCommand(label)) {
|
||||
PluginCommand command = ess.getServer().getPluginCommand(label);
|
||||
if (!checked.contains(command)) {
|
||||
checked.add(command);
|
||||
if (!user.isAuthorized(command.getName().equals("r") ? "essentials.msg" : "essentials." + command.getName())) {
|
||||
toRemove.add(command);
|
||||
}
|
||||
}
|
||||
return toRemove.contains(command);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
removedCmds.removeAll(event.getCommands());
|
||||
ess.getLogger().info("Removed commands: " + removedCmds.toString());
|
||||
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 Essentials
|
||||
* - There is no known alternative OR the alternative is overridden by Essentials
|
||||
* - The user is not allowed to perform the given Essentials command
|
||||
* - The command is a plugin command
|
||||
* - The plugin command is from a plugin in an essentials-controlled package
|
||||
* - There is no known alternative OR the alternative is overridden by Essentials
|
||||
*/
|
||||
private boolean shouldHideFromUser(String commandLabel, User user) {
|
||||
PluginCommand command = ess.getServer().getPluginCommand(commandLabel);
|
||||
private boolean isEssentialsCommand(String label) {
|
||||
PluginCommand command = ess.getServer().getPluginCommand(label);
|
||||
|
||||
return command != null
|
||||
&& command.getPlugin().getName().equals("Essentials")
|
||||
&& (ess.getSettings().isCommandOverridden(commandLabel) || (ess.getAlternativeCommandsHandler().getAlternative(commandLabel) == null))
|
||||
&& !user.isAuthorized(command.getName().equals("r") ? "essentials.msg" : "essentials." + command.getName());
|
||||
&& (command.getPlugin() == ess || command.getPlugin().getClass().getName().startsWith("com.earth2me.essentials"))
|
||||
&& (ess.getSettings().isCommandOverridden(label) || (ess.getAlternativeCommandsHandler().getAlternative(label) == null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public class EssentialsPluginListener implements Listener, IConf {
|
||||
if (event.getPlugin().getName().equals("EssentialsChat")) {
|
||||
ess.getSettings().setEssentialsChatActive(false);
|
||||
}
|
||||
ess.getPermissionsHandler().checkPermissions();
|
||||
ess.getAlternativeCommandsHandler().removePlugin(event.getPlugin());
|
||||
// Check to see if the plugin thats being disabled is the one we are using
|
||||
if (ess.getPaymentMethod() != null && Methods.hasMethod() && Methods.checkDisabled(event.getPlugin())) {
|
||||
|
||||
@@ -17,15 +17,16 @@ import java.util.logging.Level;
|
||||
|
||||
|
||||
public class EssentialsServerListener implements Listener {
|
||||
private static List<String> ignoredSLPECallers = Arrays.asList(
|
||||
private static final List<String> ignoredSLPECallers = Arrays.asList(
|
||||
".LegacyPingHandler.channelRead(", // CB responding to pings from pre-Netty clients
|
||||
"de.dytanic.cloudnet.bridge.BukkitBootstrap" // CloudNet v2 doing... something
|
||||
"de.dytanic.cloudnet.bridge.BukkitBootstrap", // CloudNet v2 doing... something
|
||||
"de.dytanic.cloudnet.ext.bridge.bukkit.BukkitCloudNetBridgePlugin" // CloudNet v3 doing... something else
|
||||
);
|
||||
|
||||
private final transient IEssentials ess;
|
||||
private boolean unsupportedLogged = false;
|
||||
private boolean npeWarned = false;
|
||||
private boolean isPaperSample;
|
||||
private final boolean isPaperSample;
|
||||
private Method setSampleText;
|
||||
private Method getSampleText;
|
||||
|
||||
|
||||
@@ -42,6 +42,56 @@ public class EssentialsUpgrade {
|
||||
doneFile.load();
|
||||
}
|
||||
|
||||
public void convertIgnoreList() {
|
||||
Pattern pattern = Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
|
||||
if (doneFile.getBoolean("updateUsersIgnoreListUUID", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("Attempting to migrate ignore list to UUIDs");
|
||||
|
||||
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdataFolder.exists() || !userdataFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
final File[] userFiles = userdataFolder.listFiles();
|
||||
|
||||
for (File file : userFiles) {
|
||||
if (!file.isFile() || !file.getName().endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final EssentialsConf config = new EssentialsConf(file);
|
||||
try {
|
||||
config.load();
|
||||
if (config.hasProperty("ignore")) {
|
||||
List<String> migratedIgnores = new ArrayList<>();
|
||||
for (String name : Collections.synchronizedList(config.getStringList("ignore"))) {
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
if (pattern.matcher(name.trim()).matches()) {
|
||||
LOGGER.info("Detected already migrated ignore list!");
|
||||
return;
|
||||
}
|
||||
User user = ess.getOfflineUser(name);
|
||||
if (user != null && user.getBase() != null) {
|
||||
migratedIgnores.add(user.getBase().getUniqueId().toString());
|
||||
}
|
||||
}
|
||||
config.removeProperty("ignore");
|
||||
config.setProperty("ignore", migratedIgnores);
|
||||
config.forceSave();
|
||||
}
|
||||
} catch (RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file.toString());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateUsersIgnoreListUUID", true);
|
||||
doneFile.save();
|
||||
LOGGER.info("Done converting ignore list.");
|
||||
}
|
||||
|
||||
public void convertKits() {
|
||||
Kits kits = ess.getKits();
|
||||
EssentialsConf config = kits.getConfig();
|
||||
@@ -163,7 +213,7 @@ public class EssentialsUpgrade {
|
||||
try {
|
||||
config.load();
|
||||
if (config.hasProperty("powertools")) {
|
||||
@SuppressWarnings("unchecked") final Map<String, Object> powertools = config.getConfigurationSection("powertools").getValues(false);
|
||||
final Map<String, Object> powertools = config.getConfigurationSection("powertools").getValues(false);
|
||||
if (powertools == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -204,7 +254,7 @@ public class EssentialsUpgrade {
|
||||
|
||||
config.load();
|
||||
if (config.hasProperty("home") && config.hasProperty("home.default")) {
|
||||
@SuppressWarnings("unchecked") final String defworld = (String) config.getProperty("home.default");
|
||||
final String defworld = (String) config.getProperty("home.default");
|
||||
final Location defloc = getFakeLocation(config, "home.worlds." + defworld);
|
||||
if (defloc != null) {
|
||||
config.setProperty("homes.home", defloc);
|
||||
@@ -575,7 +625,7 @@ public class EssentialsUpgrade {
|
||||
conf.load();
|
||||
|
||||
String banReason;
|
||||
Long banTimeout;
|
||||
long banTimeout;
|
||||
|
||||
try {
|
||||
banReason = conf.getConfigurationSection("ban").getString("reason");
|
||||
@@ -616,12 +666,7 @@ public class EssentialsUpgrade {
|
||||
}
|
||||
}
|
||||
|
||||
private static final FileFilter YML_FILTER = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.isFile() && pathname.getName().endsWith(".yml");
|
||||
}
|
||||
};
|
||||
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);
|
||||
@@ -718,5 +763,6 @@ public class EssentialsUpgrade {
|
||||
banFormatChange();
|
||||
warnMetrics();
|
||||
repairUserMap();
|
||||
convertIgnoreList();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class ExecuteTimer {
|
||||
|
||||
|
||||
public ExecuteTimer() {
|
||||
times = new ArrayList<ExecuteRecord>();
|
||||
times = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
|
||||
@@ -2,12 +2,11 @@ package com.earth2me.essentials;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
@@ -23,7 +22,7 @@ public class I18n implements net.ess3.api.II18n {
|
||||
private transient ResourceBundle customBundle;
|
||||
private transient ResourceBundle localeBundle;
|
||||
private final transient ResourceBundle defaultBundle;
|
||||
private transient Map<String, MessageFormat> messageFormatCache = new HashMap<String, MessageFormat>();
|
||||
private transient Map<String, MessageFormat> messageFormatCache = new HashMap<>();
|
||||
private final transient IEssentials ess;
|
||||
private static final Pattern NODOUBLEMARK = Pattern.compile("''");
|
||||
private static final ResourceBundle NULL_BUNDLE = new ResourceBundle() {
|
||||
@@ -38,7 +37,7 @@ public class I18n implements net.ess3.api.II18n {
|
||||
|
||||
public I18n(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
defaultBundle = ResourceBundle.getBundle(MESSAGES, Locale.ENGLISH);
|
||||
defaultBundle = ResourceBundle.getBundle(MESSAGES, Locale.ENGLISH, new UTF8PropertiesControl());
|
||||
localeBundle = defaultBundle;
|
||||
customBundle = NULL_BUNDLE;
|
||||
}
|
||||
@@ -110,17 +109,17 @@ public class I18n implements net.ess3.api.II18n {
|
||||
}
|
||||
}
|
||||
ResourceBundle.clearCache();
|
||||
messageFormatCache = new HashMap<String, MessageFormat>();
|
||||
messageFormatCache = new HashMap<>();
|
||||
Logger.getLogger("Essentials").log(Level.INFO, String.format("Using locale %s", currentLocale.toString()));
|
||||
|
||||
try {
|
||||
localeBundle = ResourceBundle.getBundle(MESSAGES, currentLocale);
|
||||
localeBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new UTF8PropertiesControl());
|
||||
} catch (MissingResourceException ex) {
|
||||
localeBundle = NULL_BUNDLE;
|
||||
}
|
||||
|
||||
try {
|
||||
customBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new FileResClassLoader(I18n.class.getClassLoader(), ess));
|
||||
customBundle = ResourceBundle.getBundle(MESSAGES, currentLocale, new FileResClassLoader(I18n.class.getClassLoader(), ess), new UTF8PropertiesControl());
|
||||
} catch (MissingResourceException ex) {
|
||||
customBundle = NULL_BUNDLE;
|
||||
}
|
||||
@@ -130,7 +129,9 @@ public class I18n implements net.ess3.api.II18n {
|
||||
return input == null || input.length() == 0 ? input : input.toUpperCase(Locale.ENGLISH).charAt(0) + input.toLowerCase(Locale.ENGLISH).substring(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to load properties files from the plugin directory before falling back to the jar.
|
||||
*/
|
||||
private static class FileResClassLoader extends ClassLoader {
|
||||
private final transient File dataFolder;
|
||||
|
||||
@@ -145,8 +146,7 @@ public class I18n implements net.ess3.api.II18n {
|
||||
if (file.exists()) {
|
||||
try {
|
||||
return file.toURI().toURL();
|
||||
} catch (MalformedURLException ex) {
|
||||
}
|
||||
} catch (MalformedURLException ignored) {}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -157,10 +157,42 @@ public class I18n implements net.ess3.api.II18n {
|
||||
if (file.exists()) {
|
||||
try {
|
||||
return new FileInputStream(file);
|
||||
} catch (FileNotFoundException ex) {
|
||||
}
|
||||
} catch (FileNotFoundException ignored) {}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads .properties files as UTF-8 instead of ISO-8859-1, which is the default on Java 8/below.
|
||||
* Java 9 fixes this by defaulting to UTF-8 for .properties files.
|
||||
*/
|
||||
private static class UTF8PropertiesControl extends ResourceBundle.Control {
|
||||
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IOException {
|
||||
String resourceName = toResourceName(toBundleName(baseName, locale), "properties");
|
||||
ResourceBundle bundle = null;
|
||||
InputStream stream = null;
|
||||
if (reload) {
|
||||
URL url = loader.getResource(resourceName);
|
||||
if (url != null) {
|
||||
URLConnection connection = url.openConnection();
|
||||
if (connection != null) {
|
||||
connection.setUseCaches(false);
|
||||
stream = connection.getInputStream();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stream = loader.getResourceAsStream(resourceName);
|
||||
}
|
||||
if (stream != null) {
|
||||
try {
|
||||
// use UTF-8 here, this is the important bit
|
||||
bundle = new PropertyResourceBundle(new InputStreamReader(stream, StandardCharsets.UTF_8));
|
||||
} finally {
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@ package com.earth2me.essentials;
|
||||
import com.earth2me.essentials.api.IItemDb;
|
||||
import com.earth2me.essentials.api.IJails;
|
||||
import com.earth2me.essentials.api.IWarps;
|
||||
import com.earth2me.essentials.metrics.Metrics;
|
||||
import com.earth2me.essentials.perm.PermissionsHandler;
|
||||
import com.earth2me.essentials.register.payment.Methods;
|
||||
import net.ess3.nms.SpawnerProvider;
|
||||
import net.ess3.provider.ServerStateProvider;
|
||||
import net.ess3.provider.SpawnerProvider;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -18,6 +18,7 @@ import org.bukkit.scheduler.BukkitTask;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public interface IEssentials extends Plugin {
|
||||
void addReloadListener(IConf listener);
|
||||
@@ -47,6 +48,8 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
int broadcastMessage(IUser sender, String message);
|
||||
|
||||
int broadcastMessage(IUser sender, String message, Predicate<IUser> shouldExclude);
|
||||
|
||||
int broadcastMessage(String permission, String message);
|
||||
|
||||
ISettings getSettings();
|
||||
@@ -63,6 +66,8 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
Kits getKits();
|
||||
|
||||
RandomTeleport getRandomTeleport();
|
||||
|
||||
Methods getPaymentMethod();
|
||||
|
||||
BukkitTask runTaskAsynchronously(Runnable run);
|
||||
@@ -89,10 +94,6 @@ public interface IEssentials extends Plugin {
|
||||
|
||||
UserMap getUserMap();
|
||||
|
||||
Metrics getMetrics();
|
||||
|
||||
void setMetrics(Metrics metrics);
|
||||
|
||||
EssentialsTimer getTimer();
|
||||
|
||||
@Deprecated
|
||||
@@ -103,4 +104,6 @@ public interface IEssentials extends Plugin {
|
||||
Iterable<User> getOnlineUsers();
|
||||
|
||||
SpawnerProvider getSpawnerProvider();
|
||||
|
||||
ServerStateProvider getServerStateProvider();
|
||||
}
|
||||
@@ -3,8 +3,6 @@ package com.earth2me.essentials;
|
||||
import com.earth2me.essentials.commands.IEssentialsCommand;
|
||||
import com.earth2me.essentials.signs.EssentialsSign;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -15,6 +13,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
@@ -31,6 +30,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
long getBackupInterval();
|
||||
|
||||
boolean isAlwaysRunBackup();
|
||||
|
||||
String getChatFormat(String group);
|
||||
|
||||
int getChatRadius();
|
||||
@@ -47,6 +48,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
String getCurrencySymbol();
|
||||
|
||||
boolean isCurrencySymbolSuffixed();
|
||||
|
||||
int getOversizedStackSize();
|
||||
|
||||
int getDefaultStackSize();
|
||||
@@ -88,7 +91,7 @@ public interface ISettings extends IConf {
|
||||
|
||||
String getNicknamePrefix();
|
||||
|
||||
ChatColor getOperatorColor() throws Exception;
|
||||
String getOperatorColor() throws Exception;
|
||||
|
||||
boolean getPerWarpPermission();
|
||||
|
||||
@@ -118,6 +121,12 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isForceDisableTeleportSafety();
|
||||
|
||||
boolean isAlwaysTeleportSafety();
|
||||
|
||||
boolean isTeleportPassengerDismount();
|
||||
|
||||
boolean isForcePassengerTeleport();
|
||||
|
||||
double getTeleportCooldown();
|
||||
|
||||
double getTeleportDelay();
|
||||
@@ -159,6 +168,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isEcoLogUpdateEnabled();
|
||||
|
||||
boolean realNamesOnList();
|
||||
|
||||
boolean removeGodOnDisconnect();
|
||||
|
||||
boolean changeDisplayName();
|
||||
@@ -191,8 +202,24 @@ public interface ISettings extends IConf {
|
||||
|
||||
String getAfkListName();
|
||||
|
||||
boolean broadcastAfkMessage();
|
||||
|
||||
boolean areDeathMessagesEnabled();
|
||||
|
||||
KeepInvPolicy getVanishingItemsPolicy();
|
||||
|
||||
KeepInvPolicy getBindingItemsPolicy();
|
||||
|
||||
int getJoinQuitMessagePlayerCount();
|
||||
|
||||
boolean hasJoinQuitMessagePlayerCount();
|
||||
|
||||
enum KeepInvPolicy {
|
||||
KEEP,
|
||||
DELETE,
|
||||
DROP
|
||||
}
|
||||
|
||||
void setDebug(boolean debug);
|
||||
|
||||
Set<String> getNoGodWorlds();
|
||||
@@ -237,6 +264,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
void setEssentialsChatActive(boolean b);
|
||||
|
||||
long getMaxMute();
|
||||
|
||||
long getMaxTempban();
|
||||
|
||||
Map<String, Object> getListGroupConfig();
|
||||
@@ -267,6 +296,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
BigDecimal getMinimumPayAmount();
|
||||
|
||||
boolean isPayExcludesIgnoreList();
|
||||
|
||||
long getLastMessageReplyRecipientTimeout();
|
||||
|
||||
boolean isMilkBucketEasterEggEnabled();
|
||||
@@ -285,6 +316,10 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isCommandCooldownsEnabled();
|
||||
|
||||
boolean isWorldChangeFlyResetEnabled();
|
||||
|
||||
boolean isWorldChangeSpeedResetEnabled();
|
||||
|
||||
long getCommandCooldownMs(String label);
|
||||
|
||||
Entry<Pattern, Long> getCommandCooldownEntry(String label);
|
||||
@@ -301,6 +336,8 @@ public interface ISettings extends IConf {
|
||||
|
||||
boolean isAllowBulkBuySell();
|
||||
|
||||
boolean isAllowSellNamedItems();
|
||||
|
||||
boolean isAddingPrefixInPlayerlist();
|
||||
|
||||
boolean isAddingSuffixInPlayerlist();
|
||||
@@ -323,11 +360,24 @@ public interface ISettings extends IConf {
|
||||
|
||||
String getItemDbType();
|
||||
|
||||
boolean isForceEnableRecipe();
|
||||
|
||||
boolean allowOldIdSigns();
|
||||
|
||||
boolean isWaterSafe();
|
||||
|
||||
boolean isSafeUsermap();
|
||||
|
||||
boolean logCommandBlockCommands();
|
||||
|
||||
Set<Predicate<String>> getNickBlacklist();
|
||||
|
||||
double getMaxProjectileSpeed();
|
||||
|
||||
boolean isRemovingEffectsOnHeal();
|
||||
|
||||
boolean isSpawnIfNoHome();
|
||||
|
||||
boolean isConfirmHomeOverwrite();
|
||||
|
||||
boolean infoAfterDeath();
|
||||
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.api.IAsyncTeleport;
|
||||
import com.earth2me.essentials.commands.IEssentialsCommand;
|
||||
import net.ess3.api.ITeleport;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -53,21 +55,30 @@ public interface IUser {
|
||||
*/
|
||||
boolean hasOutstandingTeleportRequest();
|
||||
|
||||
/**
|
||||
* @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.api.IAsyncTeleport IAsyncTeleport} with {@link IUser#getAsyncTeleport()}
|
||||
*/
|
||||
@Deprecated
|
||||
ITeleport getTeleport();
|
||||
|
||||
IAsyncTeleport getAsyncTeleport();
|
||||
|
||||
BigDecimal getMoney();
|
||||
|
||||
void setMoney(final BigDecimal value) throws MaxMoneyException;
|
||||
|
||||
@Deprecated
|
||||
void setAfk(final boolean set);
|
||||
|
||||
void setAfk(final boolean set, final AfkStatusChangeEvent.Cause cause);
|
||||
|
||||
/**
|
||||
* 'Hidden' Represents when a player is hidden from others. This status includes when the player is hidden via other
|
||||
* supported plugins. Use isVanished() if you want to check if a user is vanished by Essentials.
|
||||
*
|
||||
* @return If the user is hidden or not
|
||||
*
|
||||
* @see isVanished
|
||||
* @see IUser#isVanished()
|
||||
*/
|
||||
boolean isHidden();
|
||||
|
||||
@@ -96,7 +107,7 @@ public interface IUser {
|
||||
*
|
||||
* @return If the user is vanished or not
|
||||
*
|
||||
* @see isHidden
|
||||
* @see IUser#isHidden()
|
||||
*/
|
||||
boolean isVanished();
|
||||
|
||||
|
||||
@@ -16,15 +16,13 @@ import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -71,7 +69,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
}
|
||||
|
||||
private void checkRegister() {
|
||||
if (enabled == false && getCount() > 0) {
|
||||
if (!enabled && getCount() > 0) {
|
||||
registerListeners();
|
||||
}
|
||||
}
|
||||
@@ -100,7 +98,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
if (getData().getJails() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ArrayList<String>(getData().getJails().keySet());
|
||||
return new ArrayList<>(getData().getJails().keySet());
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
@@ -119,7 +117,11 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method does not use asynchronous teleportation. Use {@link Jails#sendToJail(IUser, String, CompletableFuture)}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void sendToJail(final IUser user, final String jail) throws Exception {
|
||||
acquireReadLock();
|
||||
try {
|
||||
@@ -133,12 +135,30 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendToJail(IUser user, String jail, CompletableFuture<Boolean> future) throws Exception {
|
||||
acquireReadLock();
|
||||
try {
|
||||
if (user.getBase().isOnline()) {
|
||||
Location loc = getJail(jail);
|
||||
user.getAsyncTeleport().now(loc, false, TeleportCause.COMMAND, future);
|
||||
future.thenAccept(success -> {
|
||||
user.setJail(jail);
|
||||
});
|
||||
return;
|
||||
}
|
||||
user.setJail(jail);
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJail(final String jailName, final Location loc) throws Exception {
|
||||
acquireWriteLock();
|
||||
try {
|
||||
if (getData().getJails() == null) {
|
||||
getData().setJails(new HashMap<String, Location>());
|
||||
getData().setJails(new HashMap<>());
|
||||
}
|
||||
getData().getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc);
|
||||
} finally {
|
||||
@@ -160,7 +180,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockBreak(final BlockBreakEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-break")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +188,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockPlace(final BlockPlaceEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-place")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -176,7 +196,7 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockDamage(final BlockDamageEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-block-damage")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -197,6 +217,14 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailPlayerInteract(final PlayerInteractEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed() && !user.isAuthorized("essentials.jail.allow-interact")) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailPlayerGameModeChange(PlayerGameModeChangeEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
event.setCancelled(true);
|
||||
@@ -249,16 +277,22 @@ public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.sett
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sendToJail(user, user.getJail());
|
||||
} catch (Exception ex) {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
future.exceptionally(ex -> {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
}
|
||||
return false;
|
||||
});
|
||||
future.thenAccept(success -> user.sendMessage(tl("jailMessage")));
|
||||
|
||||
try {
|
||||
sendToJail(user, user.getJail(), future);
|
||||
} catch (Exception ex) {
|
||||
future.completeExceptionally(ex);
|
||||
}
|
||||
user.sendMessage(tl("jailMessage"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,10 @@ import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.events.KitClaimEvent;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -50,7 +53,6 @@ public class Kit {
|
||||
long nextUse = getNextUse(user);
|
||||
|
||||
if (nextUse == 0L) {
|
||||
return;
|
||||
} else if (nextUse < 0L) {
|
||||
user.sendMessage(tl("kitOnce"));
|
||||
throw new NoChargeException();
|
||||
@@ -122,7 +124,7 @@ public class Kit {
|
||||
throw new Exception(tl("kitNotFound"));
|
||||
}
|
||||
try {
|
||||
final List<String> itemList = new ArrayList<String>();
|
||||
final List<String> itemList = new ArrayList<>();
|
||||
final Object kitItems = kit.get("items");
|
||||
if (kitItems instanceof List) {
|
||||
for (Object item : (List) kitItems) {
|
||||
@@ -141,22 +143,30 @@ public class Kit {
|
||||
}
|
||||
}
|
||||
|
||||
public void expandItems(final User user) throws Exception {
|
||||
expandItems(user, getItems(user));
|
||||
public boolean expandItems(final User user) throws Exception {
|
||||
return expandItems(user, getItems(user));
|
||||
}
|
||||
|
||||
public void expandItems(final User user, final List<String> items) throws Exception {
|
||||
public boolean expandItems(final User user, final List<String> items) throws Exception {
|
||||
try {
|
||||
IText input = new SimpleTextInput(items);
|
||||
IText output = new KeywordReplacer(input, user.getSource(), ess, true, true);
|
||||
|
||||
KitClaimEvent event = new KitClaimEvent(user, this);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean spew = false;
|
||||
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
|
||||
final boolean currencyIsSuffix = ess.getSettings().isCurrencySymbolSuffixed();
|
||||
List<ItemStack> itemList = new ArrayList<>();
|
||||
List<String> commandQueue = new ArrayList<>();
|
||||
List<String> moneyQueue = new ArrayList<>();
|
||||
for (String kitItem : output.getLines()) {
|
||||
if (kitItem.startsWith(ess.getSettings().getCurrencySymbol())) {
|
||||
BigDecimal value = new BigDecimal(kitItem.substring(ess.getSettings().getCurrencySymbol().length()).trim());
|
||||
Trade t = new Trade(value, ess);
|
||||
t.pay(user, OverflowType.DROP);
|
||||
if (!currencyIsSuffix ? kitItem.startsWith(ess.getSettings().getCurrencySymbol()) : kitItem.endsWith(ess.getSettings().getCurrencySymbol())) {
|
||||
moneyQueue.add(NumberUtil.sanitizeCurrencyString(kitItem, ess));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -164,7 +174,7 @@ public class Kit {
|
||||
String command = kitItem.substring(1);
|
||||
String name = user.getName();
|
||||
command = command.replace("{player}", name);
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||
commandQueue.add(command);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -181,18 +191,24 @@ public class Kit {
|
||||
// We pass a null sender here because kits should not do perm checks
|
||||
metaStack.parseStringMeta(null, allowUnsafe, parts, 2, ess);
|
||||
}
|
||||
|
||||
final Map<Integer, ItemStack> overfilled;
|
||||
final boolean allowOversizedStacks = user.isAuthorized("essentials.oversizedstacks");
|
||||
|
||||
itemList.add(metaStack.getItemStack());
|
||||
}
|
||||
|
||||
|
||||
final Map<Integer, ItemStack> overfilled;
|
||||
final boolean allowOversizedStacks = user.isAuthorized("essentials.oversizedstacks");
|
||||
final boolean isDropItemsIfFull = ess.getSettings().isDropItemsIfFull();
|
||||
if (isDropItemsIfFull) {
|
||||
if (allowOversizedStacks) {
|
||||
overfilled = InventoryWorkaround.addOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), metaStack.getItemStack());
|
||||
overfilled = InventoryWorkaround.addOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), itemList.toArray(new ItemStack[0]));
|
||||
} else {
|
||||
overfilled = InventoryWorkaround.addItems(user.getBase().getInventory(), metaStack.getItemStack());
|
||||
overfilled = InventoryWorkaround.addItems(user.getBase().getInventory(), itemList.toArray(new ItemStack[0]));
|
||||
}
|
||||
for (ItemStack itemStack : overfilled.values()) {
|
||||
int spillAmount = itemStack.getAmount();
|
||||
if (!allowOversizedStacks) {
|
||||
itemStack.setAmount(spillAmount < itemStack.getMaxStackSize() ? spillAmount : itemStack.getMaxStackSize());
|
||||
itemStack.setAmount(Math.min(spillAmount, itemStack.getMaxStackSize()));
|
||||
}
|
||||
while (spillAmount > 0) {
|
||||
user.getWorld().dropItemNaturally(user.getLocation(), itemStack);
|
||||
@@ -200,8 +216,32 @@ public class Kit {
|
||||
}
|
||||
spew = true;
|
||||
}
|
||||
} else {
|
||||
if (allowOversizedStacks) {
|
||||
overfilled = InventoryWorkaround.addAllOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), itemList.toArray(new ItemStack[0]));
|
||||
} else {
|
||||
overfilled = InventoryWorkaround.addAllItems(user.getBase().getInventory(), itemList.toArray(new ItemStack[0]));
|
||||
}
|
||||
if (overfilled != null) {
|
||||
user.sendMessage(tl("kitInvFullNoDrop"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
user.getBase().updateInventory();
|
||||
|
||||
// Process money & command queues
|
||||
// Done after all items have been processed so commands are not run and money is not given if
|
||||
// an error occurs during the item giving process
|
||||
for (String valueString : moneyQueue) {
|
||||
BigDecimal value = new BigDecimal(valueString.trim());
|
||||
Trade t = new Trade(value, ess);
|
||||
t.pay(user, OverflowType.DROP);
|
||||
}
|
||||
|
||||
for (String cmd : commandQueue) {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd);
|
||||
}
|
||||
|
||||
if (spew) {
|
||||
user.sendMessage(tl("kitInvFull"));
|
||||
}
|
||||
@@ -210,5 +250,6 @@ public class Kit {
|
||||
ess.getLogger().log(Level.WARNING, e.getMessage());
|
||||
throw new Exception(tl("kitError2"), e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -64,13 +64,27 @@ public class Kits implements IConf {
|
||||
// you just found if you don't toLowercase it.
|
||||
if (kits.isConfigurationSection(name.toLowerCase())) {
|
||||
return kits.getConfigurationSection(name.toLowerCase()).getValues(true);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Tries to find an existing kit name that matches the given name, ignoring case. Returns null if no match.
|
||||
public String matchKit(String name) {
|
||||
if (config.isConfigurationSection("kits")) {
|
||||
final ConfigurationSection section = config.getConfigurationSection("kits");
|
||||
if (section != null) {
|
||||
for (String kitName : section.getKeys(false)) {
|
||||
if (kitName.equalsIgnoreCase(name)) {
|
||||
return kitName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addKit(String name, List<String> lines, long delay) {
|
||||
// Will overwrite but w/e
|
||||
config.set("kits." + name + ".delay", delay);
|
||||
@@ -79,6 +93,12 @@ public class Kits implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
public void removeKit(String name) {
|
||||
config.set("kits." + name, null);
|
||||
kits = _getKits();
|
||||
config.save();
|
||||
}
|
||||
|
||||
public String listKits(final net.ess3.api.IEssentials ess, final User user) throws Exception {
|
||||
try {
|
||||
final ConfigurationSection kits = config.getConfigurationSection("kits");
|
||||
|
||||
@@ -38,19 +38,16 @@ public class ManagedFile {
|
||||
try {
|
||||
copyResourceAscii("/" + filename, file);
|
||||
} catch (IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, tl("itemsCsvNotLoaded"), ex);
|
||||
Bukkit.getLogger().log(Level.SEVERE, tl("itemsCsvNotLoaded", filename), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyResourceAscii(final String resourceName, final File file) throws IOException {
|
||||
final InputStreamReader reader = new InputStreamReader(ManagedFile.class.getResourceAsStream(resourceName));
|
||||
try {
|
||||
try (InputStreamReader reader = new InputStreamReader(ManagedFile.class.getResourceAsStream(resourceName))) {
|
||||
final MessageDigest digest = getDigest();
|
||||
final DigestOutputStream digestStream = new DigestOutputStream(new FileOutputStream(file), digest);
|
||||
try {
|
||||
final OutputStreamWriter writer = new OutputStreamWriter(digestStream);
|
||||
try {
|
||||
try (DigestOutputStream digestStream = new DigestOutputStream(new FileOutputStream(file), digest)) {
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter(digestStream)) {
|
||||
final char[] buffer = new char[BUFFERSIZE];
|
||||
do {
|
||||
final int length = reader.read(buffer);
|
||||
@@ -66,14 +63,8 @@ public class ManagedFile {
|
||||
digestStream.on(false);
|
||||
digestStream.write('#');
|
||||
digestStream.write(hashInt.toString(16).getBytes());
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
} finally {
|
||||
digestStream.close();
|
||||
}
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +72,7 @@ public class ManagedFile {
|
||||
if (file.length() < 33) {
|
||||
return false;
|
||||
}
|
||||
final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
|
||||
try {
|
||||
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
|
||||
final byte[] buffer = new byte[(int) file.length()];
|
||||
int position = 0;
|
||||
do {
|
||||
@@ -96,8 +86,7 @@ public class ManagedFile {
|
||||
if (bais.skip(file.length() - 33) != file.length() - 33) {
|
||||
return false;
|
||||
}
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(bais));
|
||||
try {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(bais))) {
|
||||
String hash = reader.readLine();
|
||||
if (hash != null && hash.matches("#[a-f0-9]{32}")) {
|
||||
hash = hash.substring(1);
|
||||
@@ -108,8 +97,7 @@ public class ManagedFile {
|
||||
if (!versioncheck.equalsIgnoreCase(version)) {
|
||||
bais.reset();
|
||||
final MessageDigest digest = getDigest();
|
||||
final DigestInputStream digestStream = new DigestInputStream(bais, digest);
|
||||
try {
|
||||
try (DigestInputStream digestStream = new DigestInputStream(bais, digest)) {
|
||||
final byte[] bytes = new byte[(int) file.length() - 33];
|
||||
digestStream.read(bytes);
|
||||
final BigInteger correct = new BigInteger(hash, 16);
|
||||
@@ -119,17 +107,11 @@ public class ManagedFile {
|
||||
} else {
|
||||
Bukkit.getLogger().warning("File " + file.toString() + " has been modified by user and file version differs, please update the file manually.");
|
||||
}
|
||||
} finally {
|
||||
digestStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
} finally {
|
||||
bis.close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -144,9 +126,8 @@ public class ManagedFile {
|
||||
|
||||
public List<String> getLines() {
|
||||
try {
|
||||
final BufferedReader reader = new BufferedReader(new FileReader(file));
|
||||
try {
|
||||
final List<String> lines = new ArrayList<String>();
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
final List<String> lines = new ArrayList<>();
|
||||
do {
|
||||
final String line = reader.readLine();
|
||||
if (line == null) {
|
||||
@@ -156,8 +137,6 @@ public class ManagedFile {
|
||||
}
|
||||
} while (true);
|
||||
return lines;
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
|
||||
@@ -10,8 +10,6 @@ import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.base.Joiner;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.FireworkEffect;
|
||||
@@ -103,16 +101,11 @@ public class MetaItemStack {
|
||||
try {
|
||||
ess.getServer().getUnsafe().modifyItemStack(stack.clone(), "{}");
|
||||
return true;
|
||||
} catch (NullPointerException npe) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Itemstack is invalid", npe);
|
||||
}
|
||||
return false;
|
||||
} catch (NoSuchMethodError nsme) {
|
||||
return true;
|
||||
} catch (Throwable throwable) {
|
||||
} catch (Throwable npe) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "Itemstack is invalid", throwable);
|
||||
ess.getLogger().log(Level.INFO, "Itemstack is invalid", npe);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -164,22 +157,20 @@ public class MetaItemStack {
|
||||
meta.setDisplayName(displayName);
|
||||
stack.setItemMeta(meta);
|
||||
} else if (split.length > 1 && (split[0].equalsIgnoreCase("lore") || split[0].equalsIgnoreCase("desc")) && hasMetaPermission(sender, "lore", false, true, ess)) {
|
||||
final List<String> lore = new ArrayList<String>();
|
||||
for (String line : split[1].split("\\|")) {
|
||||
lore.add(FormatUtil.replaceFormat(line.replace('_', ' ')));
|
||||
final List<String> lore = new ArrayList<>();
|
||||
for (String line : split[1].split("(?<!\\\\)\\|")) {
|
||||
lore.add(FormatUtil.replaceFormat(line.replace('_', ' ').replace("\\|", "|")));
|
||||
}
|
||||
final ItemMeta meta = stack.getItemMeta();
|
||||
meta.setLore(lore);
|
||||
stack.setItemMeta(meta);
|
||||
} else if (split[0].equalsIgnoreCase("unbreakable") && hasMetaPermission(sender, "unbreakable", false, true, ess)) {
|
||||
boolean value = split.length > 1 ? Boolean.valueOf(split[1]) : true;
|
||||
boolean value = split.length <= 1 || Boolean.parseBoolean(split[1]);
|
||||
setUnbreakable(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())) {
|
||||
final String owner = split[1];
|
||||
final SkullMeta meta = (SkullMeta) stack.getItemMeta();
|
||||
meta.setOwningPlayer(ess.getServer().getOfflinePlayer(owner));
|
||||
stack.setItemMeta(meta);
|
||||
setSkullOwner(ess, stack, owner);
|
||||
} else {
|
||||
throw new Exception(tl("onlyPlayerSkulls"));
|
||||
}
|
||||
@@ -297,7 +288,7 @@ public class MetaItemStack {
|
||||
builder = FireworkEffect.builder();
|
||||
}
|
||||
|
||||
List<Color> primaryColors = new ArrayList<Color>();
|
||||
List<Color> primaryColors = new ArrayList<>();
|
||||
String[] colors = split[1].split(",");
|
||||
for (String color : colors) {
|
||||
if (colorMap.containsKey(color.toUpperCase())) {
|
||||
@@ -320,7 +311,7 @@ public class MetaItemStack {
|
||||
builder.with(finalEffect);
|
||||
}
|
||||
} else if (split[0].equalsIgnoreCase("fade") || (allowShortName && split[0].equalsIgnoreCase("f"))) {
|
||||
List<Color> fadeColors = new ArrayList<Color>();
|
||||
List<Color> fadeColors = new ArrayList<>();
|
||||
String[] colors = split[1].split(",");
|
||||
for (String color : colors) {
|
||||
if (colorMap.containsKey(color.toUpperCase())) {
|
||||
@@ -384,7 +375,7 @@ public class MetaItemStack {
|
||||
throw new Exception(tl("invalidPotionMeta", split[1]));
|
||||
}
|
||||
} else if (split[0].equalsIgnoreCase("splash") || (allowShortName && split[0].equalsIgnoreCase("s"))) {
|
||||
isSplashPotion = Boolean.valueOf(split[1]);
|
||||
isSplashPotion = Boolean.parseBoolean(split[1]);
|
||||
}
|
||||
|
||||
if (isValidPotion()) {
|
||||
@@ -491,11 +482,11 @@ public class MetaItemStack {
|
||||
|
||||
final BannerMeta meta = (BannerMeta) stack.getItemMeta();
|
||||
if (split[0].equalsIgnoreCase("basecolor")) {
|
||||
Color color = Color.fromRGB(Integer.valueOf(split[1]));
|
||||
Color color = Color.fromRGB(Integer.parseInt(split[1]));
|
||||
meta.setBaseColor(DyeColor.getByColor(color));
|
||||
} else if (patternType != null) {
|
||||
PatternType type = PatternType.valueOf(split[0]);
|
||||
DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.valueOf(split[1])));
|
||||
DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.parseInt(split[1])));
|
||||
org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
|
||||
meta.addPattern(pattern);
|
||||
}
|
||||
@@ -517,11 +508,11 @@ public class MetaItemStack {
|
||||
BlockStateMeta meta = (BlockStateMeta) stack.getItemMeta();
|
||||
Banner banner = (Banner) meta.getBlockState();
|
||||
if (split[0].equalsIgnoreCase("basecolor")) {
|
||||
Color color = Color.fromRGB(Integer.valueOf(split[1]));
|
||||
Color color = Color.fromRGB(Integer.parseInt(split[1]));
|
||||
banner.setBaseColor(DyeColor.getByColor(color));
|
||||
} else if (patternType != null) {
|
||||
PatternType type = PatternType.valueOf(split[0]);
|
||||
DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.valueOf(split[1])));
|
||||
DyeColor color = DyeColor.getByColor(Color.fromRGB(Integer.parseInt(split[1])));
|
||||
org.bukkit.block.banner.Pattern pattern = new org.bukkit.block.banner.Pattern(color, type);
|
||||
banner.addPattern(pattern);
|
||||
}
|
||||
@@ -584,4 +575,24 @@ public class MetaItemStack {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean useNewSkullMethod = true;
|
||||
|
||||
private static void setSkullOwner(final IEssentials ess, final ItemStack stack, final String owner) {
|
||||
if (!(stack.getItemMeta() instanceof SkullMeta)) return;
|
||||
|
||||
SkullMeta meta = (SkullMeta) stack.getItemMeta();
|
||||
if (useNewSkullMethod) {
|
||||
try {
|
||||
meta.setOwningPlayer(ess.getServer().getOfflinePlayer(owner));
|
||||
stack.setItemMeta(meta);
|
||||
return;
|
||||
} catch (NoSuchMethodError e) {
|
||||
useNewSkullMethod = false;
|
||||
}
|
||||
}
|
||||
|
||||
meta.setOwner(owner);
|
||||
stack.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,8 @@ public enum Mob {
|
||||
GIANT("Giant", Enemies.ENEMY, EntityType.GIANT),
|
||||
HORSE("Horse", Enemies.FRIENDLY, EntityType.HORSE),
|
||||
PIG("Pig", Enemies.FRIENDLY, EntityType.PIG),
|
||||
PIGZOMB("PigZombie", Enemies.NEUTRAL, EntityType.PIG_ZOMBIE),
|
||||
PIGZOMB("PigZombie", Enemies.NEUTRAL, MobCompat.ZOMBIFIED_PIGLIN),
|
||||
ZOMBIFIED_PIGLIN("ZombifiedPiglin", Enemies.NEUTRAL, MobCompat.ZOMBIFIED_PIGLIN),
|
||||
SHEEP("Sheep", Enemies.FRIENDLY, "", EntityType.SHEEP),
|
||||
SKELETON("Skeleton", Enemies.ENEMY, EntityType.SKELETON),
|
||||
SLIME("Slime", Enemies.ENEMY, EntityType.SLIME),
|
||||
@@ -89,7 +90,13 @@ public enum Mob {
|
||||
PILLAGER("Pillager", Enemies.ENEMY, "PILLAGER"),
|
||||
RAVAGER("Ravager", Enemies.ENEMY, "RAVAGER"),
|
||||
TRADER_LLAMA("TraderLlama", Enemies.FRIENDLY, "TRADER_LLAMA"),
|
||||
WANDERING_TRADER("WanderingTrader", Enemies.FRIENDLY, "WANDERING_TRADER")
|
||||
WANDERING_TRADER("WanderingTrader", Enemies.FRIENDLY, "WANDERING_TRADER"),
|
||||
BEE("Bee", Enemies.NEUTRAL, "BEE"),
|
||||
STRAY("Stray", Enemies.ENEMY, "STRAY"),
|
||||
HOGLIN("Hoglin", Enemies.ADULT_ENEMY, "HOGLIN"),
|
||||
PIGLIN("Piglin", Enemies.ADULT_ENEMY, "PIGLIN"),
|
||||
STRIDER("Strider", Enemies.FRIENDLY, "STRIDER"),
|
||||
ZOGLIN("Zoglin", Enemies.ENEMY, "ZOGLIN"),
|
||||
;
|
||||
|
||||
public static final Logger logger = Logger.getLogger("Essentials");
|
||||
@@ -153,7 +160,8 @@ public enum Mob {
|
||||
public enum Enemies {
|
||||
FRIENDLY("friendly"),
|
||||
NEUTRAL("neutral"),
|
||||
ENEMY("enemy");
|
||||
ENEMY("enemy"),
|
||||
ADULT_ENEMY("adult_enemy");
|
||||
|
||||
Enemies(final String type) {
|
||||
this.type = type;
|
||||
|
||||
@@ -1,28 +1,42 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Fox;
|
||||
import org.bukkit.entity.Llama;
|
||||
import org.bukkit.entity.MushroomCow;
|
||||
import org.bukkit.entity.Ocelot;
|
||||
import org.bukkit.entity.Panda;
|
||||
import org.bukkit.entity.Parrot;
|
||||
import org.bukkit.entity.TropicalFish;
|
||||
import org.bukkit.entity.Villager;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static com.earth2me.essentials.utils.EnumUtil.getEntityType;
|
||||
|
||||
public class MobCompat {
|
||||
|
||||
// Constants for mob interfaces added in later versions
|
||||
public static final Class RAIDER = ReflUtil.getClassCached("org.bukkit.entity.Raider");
|
||||
|
||||
// Constants for mobs added in later versions
|
||||
public static final EntityType LLAMA = getEntityType("LLAMA");
|
||||
public static final EntityType PARROT = getEntityType("PARROT");
|
||||
public static final EntityType TROPICAL_FISH = getEntityType("TROPICAL_FISH");
|
||||
public static final EntityType PANDA = getEntityType("PANDA");
|
||||
public static final EntityType TRADER_LLAMA = getEntityType("TRADER_LLAMA");
|
||||
public static final EntityType SHULKER = getEntityType("SHULKER");
|
||||
public static final EntityType STRAY = getEntityType("STRAY");
|
||||
public static final EntityType FOX = getEntityType("FOX");
|
||||
public static final EntityType PHANTOM = getEntityType("PHANTOM");
|
||||
|
||||
// Constants for mobs that have changed since earlier versions
|
||||
public static final EntityType CAT = getEntityType("CAT", "OCELOT");
|
||||
public static final EntityType ZOMBIFIED_PIGLIN = getEntityType("ZOMBIFIED_PIGLIN", "PIG_ZOMBIE");
|
||||
|
||||
public enum CatType {
|
||||
// These are (loosely) Mojang names for the cats
|
||||
@@ -64,12 +78,12 @@ public class MobCompat {
|
||||
NITWIT("NITWIT", "NITWIT"),
|
||||
SHEPHERD("FARMER", "SHEPHERD"),
|
||||
TOOLSMITH("BLACKSMITH", "TOOL_SMITH", "TOOLSMITH"),
|
||||
WEAPONSMITH("BLACKSMITH", "WEAPON_SMITH", "WEAPONSMITH")
|
||||
WEAPONSMITH("BLACKSMITH", "WEAPON_SMITH", "WEAPONSMITH"),
|
||||
;
|
||||
|
||||
private String oldProfession;
|
||||
private String oldCareer;
|
||||
private String newProfession;
|
||||
private final String oldProfession;
|
||||
private final String oldCareer;
|
||||
private final String newProfession;
|
||||
|
||||
VillagerProfession(final String oldProfession, final String career) {
|
||||
this.oldProfession = oldProfession;
|
||||
@@ -89,41 +103,33 @@ public class MobCompat {
|
||||
}
|
||||
|
||||
// Older cats are Ocelots, whereas 1.14+ cats are Cats
|
||||
private static Class catClass = ReflUtil.getClassCached("org.bukkit.entity.Cat");
|
||||
private static Class catTypeClass = ReflUtil.getClassCached("org.bukkit.entity.Cat.Type");
|
||||
private static Method catSetTypeMethod = (catClass == null || catTypeClass == null) ? null : ReflUtil.getMethodCached(catClass, "setCatType", catTypeClass);
|
||||
|
||||
private static boolean isNewCat() {
|
||||
return (catClass != null && catTypeClass != null && catSetTypeMethod != null);
|
||||
}
|
||||
|
||||
public static void setCatType(final Entity entity, final CatType type) {
|
||||
if (isNewCat()) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
((Ocelot) entity).setCatType(Ocelot.Type.valueOf(type.ocelotTypeName));
|
||||
} else {
|
||||
Class cat = ReflUtil.getClassCached("org.bukkit.entity.Cat");
|
||||
Class catType = ReflUtil.getClassCached("org.bukkit.entity.Cat$Type");
|
||||
Method setCatType = ReflUtil.getMethodCached(cat, "setCatType", catType);
|
||||
try {
|
||||
catSetTypeMethod.invoke(entity, EnumUtil.valueOf(catTypeClass, type.catTypeName));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
setCatType.invoke(entity, EnumUtil.valueOf(catType, type.catTypeName));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
((Ocelot) entity).setCatType(Ocelot.Type.valueOf(type.ocelotTypeName));
|
||||
}
|
||||
}
|
||||
|
||||
// Older villagers have professions and careers, 1.14+ villagers only have professions
|
||||
private static Class villagerCareerClass = ReflUtil.getClassCached("org.bukkit.entity.Villager.Career");
|
||||
private static Method villagerSetCareerMethod = (villagerCareerClass == null) ? null : ReflUtil.getMethodCached(Villager.class, "setCareer", villagerCareerClass);
|
||||
|
||||
private static boolean isCareerVillager() {
|
||||
return (villagerCareerClass != null && villagerSetCareerMethod != null);
|
||||
}
|
||||
|
||||
public static void setVillagerProfession(final Entity entity, final VillagerProfession profession) {
|
||||
if (!isCareerVillager()) {
|
||||
((Villager) entity).setProfession(profession.asEnum());
|
||||
} else {
|
||||
((Villager) entity).setProfession(profession.asEnum());
|
||||
if (!(entity instanceof Villager)) {
|
||||
return;
|
||||
}
|
||||
Villager villager = (Villager) entity;
|
||||
villager.setProfession(profession.asEnum());
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
Class villagerCareer = ReflUtil.getClassCached("org.bukkit.entity.Villager$Career");
|
||||
Method setCareer = ReflUtil.getMethodCached(Villager.class, "setCareer", villagerCareer);
|
||||
try {
|
||||
villagerSetCareerMethod.invoke(entity, EnumUtil.valueOf(villagerCareerClass, profession.oldCareer));
|
||||
setCareer.invoke(entity, EnumUtil.valueOf(villagerCareer, profession.oldCareer));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -132,92 +138,77 @@ public class MobCompat {
|
||||
|
||||
// Only 1.14+ villagers have biome variants
|
||||
public static void setVillagerType(final Entity entity, final String type) {
|
||||
Class typeEnum = ReflUtil.getClassCached("org.bukkit.entity.Villager.Type");
|
||||
if (typeEnum == null) return;
|
||||
|
||||
Method villagerSetTypeMethod = ReflUtil.getMethodCached(Villager.class, "setVillagerType", typeEnum);
|
||||
try {
|
||||
villagerSetTypeMethod.invoke(entity, EnumUtil.valueOf(typeEnum, type));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Villager) {
|
||||
((Villager) entity).setVillagerType(Villager.Type.valueOf(type));
|
||||
}
|
||||
}
|
||||
|
||||
// Llamas only exist in 1.11+
|
||||
public static void setLlamaColor(final Entity entity, final String color) {
|
||||
Class llamaClass = ReflUtil.getClassCached("org.bukkit.entity.Llama");
|
||||
if (llamaClass == null) return;
|
||||
|
||||
Class colorEnum = ReflUtil.getClassCached("org.bukkit.entity.Llama.Color");
|
||||
Method setVariantMethod = ReflUtil.getMethodCached(llamaClass, "setColor");
|
||||
|
||||
try {
|
||||
setVariantMethod.invoke(entity, EnumUtil.valueOf(colorEnum, color));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_11_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Llama) {
|
||||
((Llama) entity).setColor(Llama.Color.valueOf(color));
|
||||
}
|
||||
}
|
||||
|
||||
// Parrots only exist in 1.12+
|
||||
public static void setParrotVariant(final Entity entity, final String variant) {
|
||||
Class parrotClass = ReflUtil.getClassCached("org.bukkit.entity.Parrot");
|
||||
if (parrotClass == null) return;
|
||||
|
||||
Class variantEnum = ReflUtil.getClassCached("org.bukkit.entity.Parrot.Variant");
|
||||
Method setVariantMethod = ReflUtil.getMethodCached(parrotClass, "setVariant");
|
||||
try {
|
||||
setVariantMethod.invoke(entity, EnumUtil.valueOf(variantEnum, variant));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Parrot) {
|
||||
((Parrot) entity).setVariant(Parrot.Variant.valueOf(variant));
|
||||
}
|
||||
}
|
||||
|
||||
// Tropical fish only exist in 1.13+
|
||||
public static void setTropicalFishPattern(final Entity entity, final String pattern) {
|
||||
Class tropicalFishClass = ReflUtil.getClassCached("org.bukkit.entity.TropicalFish");
|
||||
if (tropicalFishClass == null) return;
|
||||
|
||||
Class patternEnum = ReflUtil.getClassCached("org.bukkit.entity.TropicalFish.Pattern");
|
||||
Method setPatternMethod = ReflUtil.getMethodCached(tropicalFishClass, "setPattern");
|
||||
try {
|
||||
setPatternMethod.invoke(entity, EnumUtil.valueOf(patternEnum, pattern));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof TropicalFish) {
|
||||
((TropicalFish) entity).setPattern(TropicalFish.Pattern.valueOf(pattern));
|
||||
}
|
||||
}
|
||||
|
||||
// Mushroom cow variant API only exists in 1.14+
|
||||
public static void setMooshroomVariant(final Entity entity, final String variant) {
|
||||
Class mushroomCowClass = ReflUtil.getClassCached("org.bukkit.entity.MushroomCow");
|
||||
Class variantEnum = ReflUtil.getClassCached("org.bukkit.entity.MushroomCow.Variant");
|
||||
if (mushroomCowClass == null || variantEnum == null) return;
|
||||
|
||||
Method setVariantMethod = ReflUtil.getMethodCached(mushroomCowClass, "setVariant");
|
||||
try {
|
||||
setVariantMethod.invoke(entity, EnumUtil.valueOf(variantEnum, variant));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof MushroomCow) {
|
||||
((MushroomCow) entity).setVariant(MushroomCow.Variant.valueOf(variant));
|
||||
}
|
||||
}
|
||||
|
||||
// Pandas only exists in 1.14+
|
||||
public static void setPandaGene(final Entity entity, final String gene, final boolean mainGene) {
|
||||
Class pandaClass = ReflUtil.getClassCached("org.bukkit.entity.Panda");
|
||||
if (pandaClass == null) return;
|
||||
|
||||
Class geneEnum = ReflUtil.getClassCached("org.bukkit.entity.Panda.Gene");
|
||||
Method setGeneMethod;
|
||||
|
||||
if (mainGene) {
|
||||
setGeneMethod = ReflUtil.getMethodCached(pandaClass, "setMainGene");
|
||||
} else {
|
||||
setGeneMethod = ReflUtil.getMethodCached(pandaClass, "setHiddenGene");
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Panda) {
|
||||
Panda panda = (Panda) entity;
|
||||
Panda.Gene pandaGene = Panda.Gene.valueOf(gene);
|
||||
if (mainGene) {
|
||||
panda.setMainGene(pandaGene);
|
||||
} else {
|
||||
panda.setHiddenGene(pandaGene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
setGeneMethod.invoke(entity, EnumUtil.valueOf(geneEnum, gene));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// Foxes only exist in 1.14+
|
||||
public static void setFoxType(final Entity entity, final String type) {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_14_R01)) {
|
||||
return;
|
||||
}
|
||||
if (entity instanceof Fox) {
|
||||
((Fox) entity).setFoxType(Fox.Type.valueOf(type));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.bukkit.material.Colorable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
@@ -32,7 +33,7 @@ public enum MobData {
|
||||
TAMED_TAMEABLE("tamed", Tameable.class, Data.TAMED, true),
|
||||
TAME_TAMEABLE("tame", Tameable.class, Data.TAMED, false),
|
||||
RANDOM_SHEEP("random", EntityType.SHEEP, Data.COLORABLE, true),
|
||||
COLORABLE_SHEEP("", StringUtil.joinList(DyeColor.values()).toLowerCase(Locale.ENGLISH), EntityType.SHEEP, Data.COLORABLE, true),
|
||||
COLORABLE_SHEEP("", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH)).collect(Collectors.toList()), EntityType.SHEEP, Data.COLORABLE, true),
|
||||
POLKA_HORSE("polka", EntityType.HORSE, Horse.Style.BLACK_DOTS, true),
|
||||
SOOTY_HORSE("sooty", EntityType.HORSE, Horse.Style.BLACK_DOTS, false),
|
||||
BLAZE_HORSE("blaze", EntityType.HORSE, Horse.Style.WHITE, true),
|
||||
@@ -113,8 +114,8 @@ public enum MobData {
|
||||
SNOWY_VILLAGER("snowy", EntityType.VILLAGER, "villagertype:SNOWY", true),
|
||||
SWAMP_VILLAGER("swamp", EntityType.VILLAGER, "villagertype:SWAMP", true),
|
||||
TAIGA_VILLAGER("taiga", EntityType.VILLAGER, "villagertype:TAIGA", true),
|
||||
SIZE_SLIME("", "<1-100>", EntityType.SLIME.getEntityClass(), Data.SIZE, true),
|
||||
NUM_EXPERIENCE_ORB("", "<1-2000000000>", EntityType.EXPERIENCE_ORB, Data.EXP, true),
|
||||
SIZE_SLIME("", Collections.singletonList("<1-100>"), EntityType.SLIME.getEntityClass(), Data.SIZE, true),
|
||||
NUM_EXPERIENCE_ORB("", Collections.singletonList("<1-2000000000>"), EntityType.EXPERIENCE_ORB, Data.EXP, true),
|
||||
RED_PARROT("red", MobCompat.PARROT, "parrot:RED", true),
|
||||
GREEN_PARROT("green", MobCompat.PARROT, "parrot:GREEN", true),
|
||||
BLUE_PARROT("blue", MobCompat.PARROT, "parrot:BLUE", true),
|
||||
@@ -153,7 +154,15 @@ public enum MobData {
|
||||
CREAMY_TRADER_LLAMA("creamy", MobCompat.TRADER_LLAMA, "llama:CREAMY", true),
|
||||
WHITE_TRADER_LLAMA("white", MobCompat.TRADER_LLAMA, "llama:WHITE", true),
|
||||
BROWN_TRADER_LLAMA("brown", MobCompat.TRADER_LLAMA, "llama:BROWN", true),
|
||||
GRAY_TRADER_LLAMA("gray", MobCompat.TRADER_LLAMA, "llama:GRAY", true)
|
||||
GRAY_TRADER_LLAMA("gray", MobCompat.TRADER_LLAMA, "llama:GRAY", true),
|
||||
RANDOM_SHULKER("random", MobCompat.SHULKER, Data.COLORABLE, true),
|
||||
COLORABLE_SHULKER("", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH)).collect(Collectors.toList()), MobCompat.SHULKER, Data.COLORABLE, true),
|
||||
RED_FOX("red", MobCompat.FOX, "fox:RED", true),
|
||||
SNOW_FOX("snow", MobCompat.FOX, "fox:SNOW", true),
|
||||
SIZE_PHANTOM("", Collections.singletonList("<1-100>"), MobCompat.PHANTOM, Data.SIZE, true),
|
||||
RAID_LEADER("leader", MobCompat.RAIDER, Data.RAID_LEADER, true),
|
||||
TROPICAL_FISH_BODY_COLOR("fish_body_color", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH) + "body").collect(Collectors.toList()), MobCompat.TROPICAL_FISH, Data.FISH_BODY_COLOR, true),
|
||||
TROPICAL_FISH_PATTERN_COLOR("fish_pattern_color", Arrays.stream(DyeColor.values()).map(color -> color.name().toLowerCase(Locale.ENGLISH) + "pattern").collect(Collectors.toList()), MobCompat.TROPICAL_FISH, Data.FISH_PATTERN_COLOR, true),
|
||||
;
|
||||
|
||||
|
||||
@@ -170,43 +179,46 @@ public enum MobData {
|
||||
TAMED,
|
||||
COLORABLE,
|
||||
EXP,
|
||||
SIZE
|
||||
SIZE,
|
||||
RAID_LEADER,
|
||||
FISH_BODY_COLOR,
|
||||
FISH_PATTERN_COLOR,
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static final Logger logger = Logger.getLogger("Essentials");
|
||||
|
||||
MobData(String n, Object type, Object value, boolean isPublic) {
|
||||
this.nickname = n;
|
||||
this.matched = n;
|
||||
this.helpMessage = n;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
MobData(String n, String h, Object type, Object value, boolean isPublic) {
|
||||
this.nickname = n;
|
||||
this.matched = n;
|
||||
this.helpMessage = h;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
final private String nickname;
|
||||
final private String helpMessage;
|
||||
final private List<String> suggestions;
|
||||
final private Object type;
|
||||
final private Object value;
|
||||
final private boolean isPublic;
|
||||
private String matched;
|
||||
|
||||
MobData(String n, Object type, Object value, boolean isPublic) {
|
||||
this.nickname = n;
|
||||
this.matched = n;
|
||||
this.suggestions = Collections.singletonList(n);
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
MobData(String n, List<String> s, Object type, Object value, boolean isPublic) {
|
||||
this.nickname = n;
|
||||
this.matched = n;
|
||||
this.suggestions = s;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.isPublic = isPublic;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, MobData> getPossibleData(final Entity spawned, boolean publicOnly) {
|
||||
LinkedHashMap<String, MobData> mobList = new LinkedHashMap<String, MobData>();
|
||||
LinkedHashMap<String, MobData> mobList = new LinkedHashMap<>();
|
||||
for (MobData data : MobData.values()) {
|
||||
if (data.type == null || (publicOnly && !data.isPublic)) continue;
|
||||
|
||||
if (data.type == null || (publicOnly && !data.isPublic)) {
|
||||
continue;
|
||||
}
|
||||
if (data.type instanceof EntityType && spawned.getType().equals(data.type)) {
|
||||
mobList.put(data.nickname.toLowerCase(Locale.ENGLISH), data);
|
||||
} else if (data.type instanceof Class && ((Class) data.type).isAssignableFrom(spawned.getClass())) {
|
||||
@@ -218,11 +230,11 @@ public enum MobData {
|
||||
}
|
||||
|
||||
public static List<String> getValidHelp(final Entity spawned) {
|
||||
List<String> output = new ArrayList<String>();
|
||||
List<String> output = new ArrayList<>();
|
||||
LinkedHashMap<String, MobData> posData = getPossibleData(spawned, true);
|
||||
|
||||
for (MobData data : posData.values()) {
|
||||
output.add(data.helpMessage);
|
||||
output.add(StringUtil.joinList(data.suggestions));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -233,9 +245,11 @@ public enum MobData {
|
||||
}
|
||||
|
||||
LinkedHashMap<String, MobData> posData = getPossibleData(spawned, false);
|
||||
for (String data : posData.keySet()) {
|
||||
if (name.contains(data)) {
|
||||
return posData.get(data);
|
||||
for (MobData data : posData.values()) {
|
||||
for (String suggestion : data.suggestions) {
|
||||
if (name.contains(suggestion)) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -291,7 +305,12 @@ public enum MobData {
|
||||
}
|
||||
} else if (this.value.equals(Data.SIZE)) {
|
||||
try {
|
||||
((Slime) spawned).setSize(Integer.parseInt(rawData));
|
||||
int size = Integer.parseInt(rawData);
|
||||
if (spawned instanceof Slime) {
|
||||
((Slime) spawned).setSize(size);
|
||||
} else if (spawned.getType() == MobCompat.PHANTOM) {
|
||||
((Phantom) spawned).setSize(size);
|
||||
}
|
||||
this.matched = rawData;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new Exception(tl("slimeMalformedSize"), e);
|
||||
@@ -313,6 +332,26 @@ public enum MobData {
|
||||
InventoryWorkaround.setItemInMainHand(invent, new ItemStack((Material) this.value, 1));
|
||||
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
|
||||
}
|
||||
} else if (this.value.equals(Data.RAID_LEADER)) {
|
||||
((Raider) spawned).setPatrolLeader(true);
|
||||
} else if (this.value.equals(Data.FISH_BODY_COLOR)) {
|
||||
for (String match : TROPICAL_FISH_BODY_COLOR.suggestions) {
|
||||
if (rawData.contains(match)) {
|
||||
this.matched = match;
|
||||
final String color = match.substring(0, match.indexOf("body")).toUpperCase(Locale.ENGLISH);
|
||||
((TropicalFish) spawned).setBodyColor(DyeColor.valueOf(color));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (this.value.equals(Data.FISH_PATTERN_COLOR)) {
|
||||
for (String match : TROPICAL_FISH_PATTERN_COLOR.suggestions) {
|
||||
if (rawData.contains(match)) {
|
||||
this.matched = match;
|
||||
final String color = match.substring(0, match.indexOf("pattern")).toUpperCase(Locale.ENGLISH);
|
||||
((TropicalFish) spawned).setPatternColor(DyeColor.valueOf(color));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (this.value instanceof String) {
|
||||
final String[] split = ((String) this.value).split(":");
|
||||
switch (split[0]) {
|
||||
@@ -337,6 +376,9 @@ public enum MobData {
|
||||
case "villagertype":
|
||||
MobCompat.setVillagerType(spawned, split[1]);
|
||||
break;
|
||||
case "fox":
|
||||
MobCompat.setFoxType(spawned, split[1]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
logger.warning("Unknown mob data type: " + this.toString());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.*;
|
||||
@@ -27,6 +28,9 @@ public class PlayerList {
|
||||
}
|
||||
user.setDisplayNick();
|
||||
groupString.append(user.getDisplayName());
|
||||
if (ess.getSettings().realNamesOnList() && !ChatColor.stripColor(user.getDisplayName()).equals(user.getName())) {
|
||||
groupString.append(" (").append(user.getName()).append(")");
|
||||
}
|
||||
groupString.append("\u00a7f");
|
||||
}
|
||||
return groupString.toString();
|
||||
@@ -40,7 +44,7 @@ public class PlayerList {
|
||||
for (User onlinePlayer : ess.getOnlineUsers()) {
|
||||
if (onlinePlayer.isHidden() || (user != null && !user.getBase().canSee(onlinePlayer.getBase()))) {
|
||||
playerHidden++;
|
||||
if (showHidden || user.getBase().canSee(onlinePlayer.getBase())) {
|
||||
if (showHidden || user != null && user.getBase().canSee(onlinePlayer.getBase())) {
|
||||
hiddenCount++;
|
||||
}
|
||||
}
|
||||
@@ -56,18 +60,13 @@ public class PlayerList {
|
||||
|
||||
// Build the basic player list, divided by groups.
|
||||
public static Map<String, List<User>> getPlayerLists(final IEssentials ess, final User sender, final boolean showHidden) {
|
||||
Server server = ess.getServer();
|
||||
final Map<String, List<User>> playerList = new HashMap<String, List<User>>();
|
||||
final Map<String, List<User>> playerList = new HashMap<>();
|
||||
for (User onlineUser : ess.getOnlineUsers()) {
|
||||
if ((sender == null && !showHidden && onlineUser.isHidden()) || (sender != null && !showHidden && !sender.getBase().canSee(onlineUser.getBase()))) {
|
||||
continue;
|
||||
}
|
||||
final String group = FormatUtil.stripFormat(FormatUtil.stripEssentialsFormat(onlineUser.getGroup().toLowerCase()));
|
||||
List<User> list = playerList.get(group);
|
||||
if (list == null) {
|
||||
list = new ArrayList<User>();
|
||||
playerList.put(group, list);
|
||||
}
|
||||
List<User> list = playerList.computeIfAbsent(group, k -> new ArrayList<>());
|
||||
list.add(onlineUser);
|
||||
}
|
||||
return playerList;
|
||||
@@ -76,13 +75,13 @@ public class PlayerList {
|
||||
// Handle the merging of groups
|
||||
public static List<User> getMergedList(final IEssentials ess, final Map<String, List<User>> playerList, final String groupName) {
|
||||
final Set<String> configGroups = ess.getSettings().getListGroupConfig().keySet();
|
||||
final List<User> users = new ArrayList<User>();
|
||||
final List<User> users = new ArrayList<>();
|
||||
for (String configGroup : configGroups) {
|
||||
if (configGroup.equalsIgnoreCase(groupName)) {
|
||||
String[] groupValues = ess.getSettings().getListGroupConfig().get(configGroup).toString().trim().split(" ");
|
||||
for (String groupValue : groupValues) {
|
||||
groupValue = groupValue.toLowerCase(Locale.ENGLISH);
|
||||
if (groupValue == null || groupValue.isEmpty()) {
|
||||
if (groupValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
List<User> u = playerList.get(groupValue.trim());
|
||||
@@ -104,20 +103,17 @@ public class PlayerList {
|
||||
if (groupUsers != null && !groupUsers.isEmpty()) {
|
||||
users.addAll(groupUsers);
|
||||
}
|
||||
if (users == null || users.isEmpty()) {
|
||||
if (users.isEmpty()) {
|
||||
throw new Exception(tl("groupDoesNotExist"));
|
||||
}
|
||||
final StringBuilder displayGroupName = new StringBuilder();
|
||||
displayGroupName.append(Character.toTitleCase(groupName.charAt(0)));
|
||||
displayGroupName.append(groupName.substring(1));
|
||||
return outputFormat(displayGroupName.toString(), listUsers(ess, users, ", "));
|
||||
String displayGroupName = Character.toTitleCase(groupName.charAt(0)) +
|
||||
groupName.substring(1);
|
||||
return outputFormat(displayGroupName, listUsers(ess, users, ", "));
|
||||
}
|
||||
|
||||
// Build the output string
|
||||
public static String outputFormat(final String group, final String message) {
|
||||
final StringBuilder outputString = new StringBuilder();
|
||||
outputString.append(tl("listGroupTag", FormatUtil.replaceFormat(group)));
|
||||
outputString.append(message);
|
||||
return outputString.toString();
|
||||
return tl("listGroupTag", FormatUtil.replaceFormat(group)) +
|
||||
message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.LocationUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class RandomTeleport implements IConf {
|
||||
private final IEssentials essentials;
|
||||
private final EssentialsConf config;
|
||||
private final ConcurrentLinkedQueue<Location> cachedLocations = new ConcurrentLinkedQueue<>();
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0;
|
||||
|
||||
public RandomTeleport(final IEssentials essentials) {
|
||||
this.essentials = essentials;
|
||||
File file = new File(essentials.getDataFolder(), "tpr.yml");
|
||||
config = new EssentialsConf(file);
|
||||
config.setTemplateName("/tpr.yml");
|
||||
config.options().copyHeader(true);
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
config.load();
|
||||
cachedLocations.clear();
|
||||
}
|
||||
|
||||
public Location getCenter() {
|
||||
try {
|
||||
Location center = config.getLocation("center", essentials.getServer());
|
||||
if (center != null) {
|
||||
return center;
|
||||
}
|
||||
} catch (InvalidWorldException ignored) {
|
||||
}
|
||||
Location center = essentials.getServer().getWorlds().get(0).getWorldBorder().getCenter();
|
||||
center.setY(center.getWorld().getHighestBlockYAt(center) + 1);
|
||||
setCenter(center);
|
||||
return center;
|
||||
}
|
||||
|
||||
public void setCenter(Location center) {
|
||||
config.setProperty("center", center);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public double getMinRange() {
|
||||
return config.getDouble("min-range", 0d);
|
||||
}
|
||||
|
||||
public void setMinRange(double minRange) {
|
||||
config.setProperty("min-range", minRange);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public double getMaxRange() {
|
||||
return config.getDouble("max-range", getCenter().getWorld().getWorldBorder().getSize() / 2);
|
||||
}
|
||||
|
||||
public void setMaxRange(double maxRange) {
|
||||
config.setProperty("max-range", maxRange);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public Set<Biome> getExcludedBiomes() {
|
||||
List<String> biomeNames = config.getStringList("excluded-biomes");
|
||||
Set<Biome> excludedBiomes = new HashSet<>();
|
||||
for (String biomeName : biomeNames) {
|
||||
try {
|
||||
excludedBiomes.add(Biome.valueOf(biomeName.toUpperCase()));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
return excludedBiomes;
|
||||
}
|
||||
|
||||
public int getFindAttempts() {
|
||||
return config.getInt("find-attempts", 10);
|
||||
}
|
||||
|
||||
public int getCacheThreshold() {
|
||||
return config.getInt("cache-threshold", 10);
|
||||
}
|
||||
|
||||
public boolean getPreCache() {
|
||||
return config.getBoolean("pre-cache", true);
|
||||
}
|
||||
|
||||
public Queue<Location> getCachedLocations() {
|
||||
return cachedLocations;
|
||||
}
|
||||
|
||||
// Get a random location; cached if possible. Otherwise on demand.
|
||||
public CompletableFuture<Location> getRandomLocation(Location center, double minRange, double maxRange) {
|
||||
int findAttempts = this.getFindAttempts();
|
||||
Queue<Location> cachedLocations = this.getCachedLocations();
|
||||
// Try to build up the cache if it is below the threshold
|
||||
if (cachedLocations.size() < this.getCacheThreshold()) {
|
||||
cacheRandomLocations(center, minRange, maxRange);
|
||||
}
|
||||
CompletableFuture<Location> future = new CompletableFuture<>();
|
||||
// Return a random location immediately if one is available, otherwise try to find one now
|
||||
if (cachedLocations.isEmpty()) {
|
||||
attemptRandomLocation(findAttempts, center, minRange, maxRange).thenAccept(future::complete);
|
||||
} else {
|
||||
future.complete(cachedLocations.poll());
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
// Prompts caching random valid locations, up to a maximum number of attempts
|
||||
public void cacheRandomLocations(Location center, double minRange, double maxRange) {
|
||||
essentials.getServer().getScheduler().scheduleSyncDelayedTask(essentials, () -> {
|
||||
for (int i = 0; i < this.getFindAttempts(); ++i) {
|
||||
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> {
|
||||
if (isValidRandomLocation(location)) {
|
||||
this.getCachedLocations().add(location);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Recursively attempt to find a random location. After a maximum number of attempts, the center is returned.
|
||||
private CompletableFuture<Location> attemptRandomLocation(int attempts, Location center, double minRange, double maxRange) {
|
||||
CompletableFuture<Location> future = new CompletableFuture<>();
|
||||
if (attempts > 0) {
|
||||
calculateRandomLocation(center, minRange, maxRange).thenAccept(location -> {
|
||||
if (isValidRandomLocation(location)) {
|
||||
future.complete(location);
|
||||
} else {
|
||||
attemptRandomLocation(attempts - 1, center, minRange, maxRange).thenAccept(future::complete);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
future.complete(center);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
// Calculates a random location asynchronously.
|
||||
private CompletableFuture<Location> calculateRandomLocation(Location center, double minRange, double maxRange) {
|
||||
CompletableFuture<Location> future = new CompletableFuture<>();
|
||||
final int dx = RANDOM.nextBoolean() ? 1 : -1, dz = RANDOM.nextBoolean() ? 1 : -1;
|
||||
Location location = new Location(
|
||||
center.getWorld(),
|
||||
center.getX() + dx * (minRange + RANDOM.nextDouble() * (maxRange - minRange)),
|
||||
center.getWorld().getMaxHeight(),
|
||||
center.getZ() + dz * (minRange + RANDOM.nextDouble() * (maxRange - minRange)),
|
||||
360 * RANDOM.nextFloat() - 180,
|
||||
0
|
||||
);
|
||||
PaperLib.getChunkAtAsync(location).thenAccept(chunk -> {
|
||||
if (World.Environment.NETHER.equals(center.getWorld().getEnvironment())) {
|
||||
location.setY(getNetherYAt(location));
|
||||
} else {
|
||||
location.setY(center.getWorld().getHighestBlockYAt(location) + HIGHEST_BLOCK_Y_OFFSET);
|
||||
}
|
||||
future.complete(location);
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
// Returns an appropriate elevation for a given location in the nether, or -1 if none is found
|
||||
private double getNetherYAt(Location location) {
|
||||
for (int y = 32; y < location.getWorld().getMaxHeight() / 2; ++y) {
|
||||
if (!LocationUtil.isBlockUnsafe(location.getWorld(), location.getBlockX(), y, location.getBlockZ())) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean isValidRandomLocation(Location location) {
|
||||
return location.getBlockY() > 0 && !this.getExcludedBiomes().contains(location.getBlock().getBiome());
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -156,6 +157,21 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return forceDisableTeleportSafety;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAlwaysTeleportSafety() {
|
||||
return config.getBoolean("force-safe-teleport-location", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTeleportPassengerDismount() {
|
||||
return config.getBoolean("teleport-passenger-dismount", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForcePassengerTeleport() {
|
||||
return config.getBoolean("force-passenger-teleportation", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTeleportDelay() {
|
||||
return config.getDouble("teleport-delay", 0);
|
||||
@@ -181,7 +197,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return isCommandDisabled(cmd.getName());
|
||||
}
|
||||
|
||||
private Set<String> disabledCommands = new HashSet<String>();
|
||||
private Set<String> disabledCommands = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public boolean isCommandDisabled(String label) {
|
||||
@@ -189,7 +205,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
}
|
||||
|
||||
private Set<String> getDisabledCommands() {
|
||||
Set<String> disCommands = new HashSet<String>();
|
||||
Set<String> disCommands = new HashSet<>();
|
||||
for (String c : config.getStringList("disabled-commands")) {
|
||||
disCommands.add(c.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
@@ -269,10 +285,10 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
private Set<String> socialSpyCommands = new HashSet<String>();
|
||||
private Set<String> socialSpyCommands = new HashSet<>();
|
||||
|
||||
private Set<String> _getSocialSpyCommands() {
|
||||
Set<String> socialspyCommands = new HashSet<String>();
|
||||
Set<String> socialspyCommands = new HashSet<>();
|
||||
|
||||
if (config.isList("socialspy-commands")) {
|
||||
for (String c : config.getStringList("socialspy-commands")) {
|
||||
@@ -295,10 +311,10 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return config.getBoolean("socialspy-listen-muted-players", true);
|
||||
}
|
||||
|
||||
private Set<String> muteCommands = new HashSet<String>();
|
||||
private Set<String> muteCommands = new HashSet<>();
|
||||
|
||||
private Set<String> _getMuteCommands() {
|
||||
Set<String> muteCommands = new HashSet<String>();
|
||||
Set<String> muteCommands = new HashSet<>();
|
||||
if (config.isList("mute-commands")) {
|
||||
for (String s : config.getStringList("mute-commands")) {
|
||||
muteCommands.add(s.toLowerCase(Locale.ENGLISH));
|
||||
@@ -359,29 +375,37 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return config.getBoolean("skip-used-one-time-kits-from-kit-list", false);
|
||||
}
|
||||
|
||||
private ChatColor operatorColor = null;
|
||||
private String operatorColor = null;
|
||||
|
||||
@Override
|
||||
public ChatColor getOperatorColor() {
|
||||
public String getOperatorColor() {
|
||||
return operatorColor;
|
||||
}
|
||||
|
||||
private ChatColor _getOperatorColor() {
|
||||
private String _getOperatorColor() {
|
||||
String colorName = config.getString("ops-name-color", null);
|
||||
|
||||
if (colorName == null) {
|
||||
return ChatColor.DARK_RED;
|
||||
}
|
||||
if ("none".equalsIgnoreCase(colorName) || colorName.isEmpty()) {
|
||||
return ChatColor.RED.toString();
|
||||
} else if (colorName.equalsIgnoreCase("none") || colorName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return ChatColor.valueOf(colorName.toUpperCase(Locale.ENGLISH));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return FormatUtil.parseHexColor(colorName);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
||||
return ChatColor.getByChar(colorName);
|
||||
try {
|
||||
return ChatColor.valueOf(colorName.toUpperCase(Locale.ENGLISH)).toString();
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
ChatColor lastResort = ChatColor.getByChar(colorName);
|
||||
if (lastResort != null) {
|
||||
return lastResort.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -419,7 +443,12 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return config.getString("backup.command", null);
|
||||
}
|
||||
|
||||
private final Map<String, String> chatFormats = Collections.synchronizedMap(new HashMap<String, String>());
|
||||
@Override
|
||||
public boolean isAlwaysRunBackup() {
|
||||
return config.getBoolean("backup.always-run", false);
|
||||
}
|
||||
|
||||
private final Map<String, String> chatFormats = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
@Override
|
||||
public String getChatFormat(String group) {
|
||||
@@ -438,6 +467,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
mFormat = mFormat.replace("{TEAMNAME}", "{5}");
|
||||
mFormat = mFormat.replace("{PREFIX}", "{6}");
|
||||
mFormat = mFormat.replace("{SUFFIX}", "{7}");
|
||||
mFormat = mFormat.replace("{USERNAME}", "{8}");
|
||||
mFormat = "§r".concat(mFormat);
|
||||
chatFormats.put(group, mFormat);
|
||||
}
|
||||
@@ -480,7 +510,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
Map<String, Object> defaultMap = new HashMap<String, Object>();
|
||||
Map<String, Object> defaultMap = new HashMap<>();
|
||||
if (config.getBoolean("sort-list-by-groups", false)) {
|
||||
defaultMap.put("ListByGroup", "ListByGroup");
|
||||
} else {
|
||||
@@ -492,7 +522,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
config.load();
|
||||
noGodWorlds = new HashSet<String>(config.getStringList("no-god-in-worlds"));
|
||||
noGodWorlds = new HashSet<>(config.getStringList("no-god-in-worlds"));
|
||||
enabledSigns = _getEnabledSigns();
|
||||
teleportSafety = _isTeleportSafetyEnabled();
|
||||
forceDisableTeleportSafety = _isForceDisableTeleportSafety();
|
||||
@@ -506,6 +536,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
sleepIgnoresAfkPlayers = _sleepIgnoresAfkPlayers();
|
||||
afkListName = _getAfkListName();
|
||||
isAfkListName = !afkListName.equalsIgnoreCase("none");
|
||||
broadcastAfkMessage = _broadcastAfkMessage();
|
||||
itemSpawnBl = _getItemSpawnBlacklist();
|
||||
loginAttackDelay = _getLoginAttackDelay();
|
||||
signUsePerSecond = _getSignUsePerSecond();
|
||||
@@ -550,10 +581,15 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
isCompassTowardsHomePerm = _isCompassTowardsHomePerm();
|
||||
isAllowWorldInBroadcastworld = _isAllowWorldInBroadcastworld();
|
||||
itemDbType = _getItemDbType();
|
||||
forceEnableRecipe = _isForceEnableRecipe();
|
||||
allowOldIdSigns = _allowOldIdSigns();
|
||||
isWaterSafe = _isWaterSafe();
|
||||
isSafeUsermap = _isSafeUsermap();
|
||||
logCommandBlockCommands = _logCommandBlockCommands();
|
||||
nickBlacklist = _getNickBlacklist();
|
||||
maxProjectileSpeed = _getMaxProjectileSpeed();
|
||||
removeEffectsOnHeal = _isRemovingEffectsOnHeal();
|
||||
vanishingItemPolicy = _getVanishingItemsPolicy();
|
||||
bindingItemPolicy = _getBindingItemsPolicy();
|
||||
}
|
||||
|
||||
void _lateLoadItemSpawnBlacklist() {
|
||||
@@ -589,7 +625,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return epItemSpwn;
|
||||
}
|
||||
|
||||
private List<EssentialsSign> enabledSigns = new ArrayList<EssentialsSign>();
|
||||
private List<EssentialsSign> enabledSigns = new ArrayList<>();
|
||||
private boolean signsEnabled = false;
|
||||
|
||||
@Override
|
||||
@@ -600,7 +636,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
private List<EssentialsSign> _getEnabledSigns() {
|
||||
this.signsEnabled = false; // Ensure boolean resets on reload.
|
||||
|
||||
List<EssentialsSign> newSigns = new ArrayList<EssentialsSign>();
|
||||
List<EssentialsSign> newSigns = new ArrayList<>();
|
||||
|
||||
for (String signName : config.getStringList("enabledSigns")) {
|
||||
signName = signName.trim().toUpperCase(Locale.ENGLISH);
|
||||
@@ -667,6 +703,11 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return config.getString("currency-symbol", "$").concat("$").substring(0, 1).replaceAll("[0-9]", "$");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrencySymbolSuffixed() {
|
||||
return config.getBoolean("currency-symbol-suffix", false);
|
||||
}
|
||||
|
||||
// #easteregg
|
||||
@Override
|
||||
@Deprecated
|
||||
@@ -781,6 +822,11 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return economyLogUpdate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean realNamesOnList() {
|
||||
return config.getBoolean("real-names-on-list", false);
|
||||
}
|
||||
|
||||
public boolean _isEcoLogUpdateEnabled() {
|
||||
return config.getBoolean("economy-log-update-enabled", false);
|
||||
}
|
||||
@@ -934,12 +980,55 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return afkListName;
|
||||
}
|
||||
|
||||
private boolean broadcastAfkMessage;
|
||||
|
||||
@Override
|
||||
public boolean broadcastAfkMessage() {
|
||||
return broadcastAfkMessage;
|
||||
}
|
||||
|
||||
private boolean _broadcastAfkMessage() {
|
||||
return config.getBoolean("broadcast-afk-message", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areDeathMessagesEnabled() {
|
||||
return config.getBoolean("death-messages", true);
|
||||
}
|
||||
|
||||
private Set<String> noGodWorlds = new HashSet<String>();
|
||||
private KeepInvPolicy vanishingItemPolicy;
|
||||
|
||||
public KeepInvPolicy _getVanishingItemsPolicy() {
|
||||
String value = config.getString("vanishing-items-policy", "keep").toLowerCase(Locale.ENGLISH);
|
||||
try {
|
||||
return KeepInvPolicy.valueOf(value.toUpperCase(Locale.ENGLISH));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return KeepInvPolicy.KEEP;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeepInvPolicy getVanishingItemsPolicy() {
|
||||
return vanishingItemPolicy;
|
||||
}
|
||||
|
||||
private KeepInvPolicy bindingItemPolicy;
|
||||
|
||||
public KeepInvPolicy _getBindingItemsPolicy() {
|
||||
String value = config.getString("binding-items-policy", "keep").toLowerCase(Locale.ENGLISH);
|
||||
try {
|
||||
return KeepInvPolicy.valueOf(value.toUpperCase(Locale.ENGLISH));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return KeepInvPolicy.KEEP;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeepInvPolicy getBindingItemsPolicy() {
|
||||
return bindingItemPolicy;
|
||||
}
|
||||
|
||||
private Set<String> noGodWorlds = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public Set<String> getNoGodWorlds() {
|
||||
@@ -1105,8 +1194,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
|
||||
private long _getEconomyLagWarning() {
|
||||
// Default to 25ms
|
||||
final long value = (long) (config.getDouble("economy-lag-warning", 25.0) * 1000000);
|
||||
return value;
|
||||
return (long) (config.getDouble("economy-lag-warning", 25.0) * 1000000);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1119,8 +1207,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
|
||||
private long _getPermissionsLagWarning() {
|
||||
// Default to 25ms
|
||||
final long value = (long) (config.getDouble("permissions-lag-warning", 25.0) * 1000000);
|
||||
return value;
|
||||
return (long) (config.getDouble("permissions-lag-warning", 25.0) * 1000000);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1128,6 +1215,11 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return permissionsLagWarning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxMute() {
|
||||
return config.getLong("max-mute-time", -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxTempban() {
|
||||
return config.getLong("max-tempban-time", -1);
|
||||
@@ -1193,6 +1285,16 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return isCustomQuitMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getJoinQuitMessagePlayerCount() {
|
||||
return config.getInt("hide-join-quit-messages-above", -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasJoinQuitMessagePlayerCount() {
|
||||
return getJoinQuitMessagePlayerCount() >= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotifyNoNewMail() {
|
||||
return config.getBoolean("notify-no-new-mail", true);
|
||||
@@ -1218,6 +1320,11 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return new BigDecimal(config.getString("minimum-pay-amount", "0.001"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPayExcludesIgnoreList() {
|
||||
return config.getBoolean("pay-excludes-ignore-list", false);
|
||||
}
|
||||
|
||||
@Override public long getLastMessageReplyRecipientTimeout() {
|
||||
return config.getLong("last-message-reply-recipient-timeout", 180);
|
||||
}
|
||||
@@ -1313,7 +1420,7 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
* >> Process cooldown value
|
||||
* ================================ */
|
||||
Object value = section.get(cmdEntry);
|
||||
if (!(value instanceof Number) && value instanceof String) {
|
||||
if (value instanceof String) {
|
||||
try {
|
||||
value = Double.parseDouble(value.toString());
|
||||
} catch (NumberFormatException ignored) {
|
||||
@@ -1425,7 +1532,6 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
newSigns.add(Signs.valueOf(signName).getSign());
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, tl("unknownItemInList", signName, "unprotected-sign-names"));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return newSigns;
|
||||
@@ -1441,6 +1547,11 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return config.getBoolean("allow-bulk-buy-sell", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowSellNamedItems() {
|
||||
return config.getBoolean("allow-selling-named-items", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAddingPrefixInPlayerlist() {
|
||||
return config.getBoolean("add-prefix-in-playerlist", false);
|
||||
@@ -1466,6 +1577,16 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
return config.getBoolean("allow-direct-hat", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWorldChangeFlyResetEnabled() {
|
||||
return config.getBoolean("world-change-fly-reset", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWorldChangeSpeedResetEnabled() {
|
||||
return config.getBoolean("world-change-speed-reset", true);
|
||||
}
|
||||
|
||||
private List<String> defaultEnabledConfirmCommands;
|
||||
|
||||
private List<String> _getDefaultEnabledConfirmCommands() {
|
||||
@@ -1532,15 +1653,6 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
|
||||
private boolean forceEnableRecipe; // https://github.com/EssentialsX/Essentials/issues/1397
|
||||
|
||||
private boolean _isForceEnableRecipe() {
|
||||
return config.getBoolean("force-enable-recipe", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceEnableRecipe() {
|
||||
return forceEnableRecipe;
|
||||
}
|
||||
|
||||
private boolean allowOldIdSigns;
|
||||
|
||||
private boolean _allowOldIdSigns() {
|
||||
@@ -1576,4 +1688,73 @@ public class Settings implements net.ess3.api.ISettings {
|
||||
public boolean isSafeUsermap() {
|
||||
return isSafeUsermap;
|
||||
}
|
||||
|
||||
private boolean logCommandBlockCommands;
|
||||
|
||||
private boolean _logCommandBlockCommands() {
|
||||
return config.getBoolean("log-command-block-commands", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean logCommandBlockCommands() {
|
||||
return logCommandBlockCommands;
|
||||
}
|
||||
|
||||
private Set<Predicate<String>> nickBlacklist;
|
||||
|
||||
private Set<Predicate<String>> _getNickBlacklist() {
|
||||
Set<Predicate<String>> blacklist = new HashSet<>();
|
||||
|
||||
config.getStringList("nick-blacklist").forEach(entry -> {
|
||||
try {
|
||||
blacklist.add(Pattern.compile(entry).asPredicate());
|
||||
} catch (PatternSyntaxException e) {
|
||||
logger.warning("Invalid nickname blacklist regex: " + entry);
|
||||
}
|
||||
});
|
||||
|
||||
return blacklist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Predicate<String>> getNickBlacklist() {
|
||||
return nickBlacklist;
|
||||
}
|
||||
|
||||
private double maxProjectileSpeed;
|
||||
|
||||
private double _getMaxProjectileSpeed() {
|
||||
return config.getDouble("max-projectile-speed", 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMaxProjectileSpeed() {
|
||||
return maxProjectileSpeed;
|
||||
}
|
||||
|
||||
private boolean removeEffectsOnHeal;
|
||||
|
||||
private boolean _isRemovingEffectsOnHeal() {
|
||||
return config.getBoolean("remove-effects-on-heal", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemovingEffectsOnHeal() {
|
||||
return removeEffectsOnHeal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpawnIfNoHome() {
|
||||
return config.getBoolean("spawn-if-no-home", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfirmHomeOverwrite() {
|
||||
return config.getBoolean("confirm-home-overwrite", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean infoAfterDeath() {
|
||||
return config.getBoolean("send-info-after-death", false);
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public class SpawnMob {
|
||||
|
||||
public static String mobList(final User user) {
|
||||
final Set<String> mobList = Mob.getMobList();
|
||||
final Set<String> availableList = new HashSet<String>();
|
||||
final Set<String> availableList = new HashSet<>();
|
||||
for (String mob : mobList) {
|
||||
if (user.isAuthorized("essentials.spawnmob." + mob.toLowerCase(Locale.ENGLISH))) {
|
||||
availableList.add(mob);
|
||||
@@ -44,7 +44,7 @@ public class SpawnMob {
|
||||
public static List<String> mobParts(final String mobString) {
|
||||
String[] mobParts = mobString.split(",");
|
||||
|
||||
List<String> mobs = new ArrayList<String>();
|
||||
List<String> mobs = new ArrayList<>();
|
||||
|
||||
for (String mobPart : mobParts) {
|
||||
String[] mobDatas = mobPart.split(":");
|
||||
@@ -56,7 +56,7 @@ public class SpawnMob {
|
||||
public static List<String> mobData(final String mobString) {
|
||||
String[] mobParts = mobString.split(",");
|
||||
|
||||
List<String> mobData = new ArrayList<String>();
|
||||
List<String> mobData = new ArrayList<>();
|
||||
|
||||
for (String mobPart : mobParts) {
|
||||
String[] mobDatas = mobPart.split(":");
|
||||
@@ -92,8 +92,8 @@ public class SpawnMob {
|
||||
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);
|
||||
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
Mob mob = Mob.fromName(parts.get(i));
|
||||
for (String part : parts) {
|
||||
Mob mob = Mob.fromName(part);
|
||||
checkSpawnable(ess, sender, mob);
|
||||
}
|
||||
|
||||
@@ -235,30 +235,20 @@ public class SpawnMob {
|
||||
final EntityEquipment invent = ((LivingEntity) spawned).getEquipment();
|
||||
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(Material.BOW, 1));
|
||||
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
|
||||
|
||||
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
|
||||
invent.setBootsDropChance(0.0f);
|
||||
}
|
||||
|
||||
if (type == EntityType.PIG_ZOMBIE) {
|
||||
if (type == MobCompat.ZOMBIFIED_PIGLIN) {
|
||||
final PigZombie zombie = ((PigZombie) spawned);
|
||||
setVillager(zombie, false);
|
||||
|
||||
final EntityEquipment invent = zombie.getEquipment();
|
||||
InventoryWorkaround.setItemInMainHand(invent, new ItemStack(GOLDEN_SWORD, 1));
|
||||
InventoryWorkaround.setItemInMainHandDropChance(invent, 0.1f);
|
||||
|
||||
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
|
||||
invent.setBootsDropChance(0.0f);
|
||||
}
|
||||
|
||||
if (type == EntityType.ZOMBIE) {
|
||||
final Zombie zombie = ((Zombie) spawned);
|
||||
setVillager(zombie, false);
|
||||
|
||||
final EntityEquipment invent = zombie.getEquipment();
|
||||
invent.setBoots(new ItemStack(GOLDEN_BOOTS, 1));
|
||||
invent.setBootsDropChance(0.0f);
|
||||
}
|
||||
|
||||
if (type == EntityType.HORSE) {
|
||||
|
||||
@@ -7,6 +7,8 @@ import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.ITeleport;
|
||||
import net.ess3.api.IUser;
|
||||
import net.ess3.api.events.UserWarpEvent;
|
||||
import net.ess3.api.events.teleport.PreTeleportEvent;
|
||||
import net.ess3.api.events.teleport.TeleportWarmupEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -20,6 +22,10 @@ import java.util.GregorianCalendar;
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.AsyncTeleport AsyncTeleport}
|
||||
*/
|
||||
@Deprecated
|
||||
public class Teleport implements ITeleport {
|
||||
private final IUser teleportOwner;
|
||||
private final IEssentials ess;
|
||||
@@ -27,6 +33,7 @@ public class Teleport implements ITeleport {
|
||||
|
||||
private TeleportType tpType;
|
||||
|
||||
@Deprecated
|
||||
public Teleport(IUser user, IEssentials ess) {
|
||||
this.teleportOwner = user;
|
||||
this.ess = ess;
|
||||
@@ -39,6 +46,7 @@ public class Teleport implements ITeleport {
|
||||
NORMAL
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void cooldown(boolean check) throws Exception {
|
||||
final Calendar time = new GregorianCalendar();
|
||||
if (teleportOwner.getLastTeleportTimestamp() > 0) {
|
||||
@@ -72,6 +80,7 @@ public class Teleport implements ITeleport {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private boolean cooldownApplies() {
|
||||
boolean applies = true;
|
||||
String globalBypassPerm = "essentials.teleport.cooldown.bypass";
|
||||
@@ -91,6 +100,7 @@ public class Teleport implements ITeleport {
|
||||
return applies;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void warnUser(final IUser user, final double delay) {
|
||||
Calendar c = new GregorianCalendar();
|
||||
c.add(Calendar.SECOND, (int) delay);
|
||||
@@ -100,6 +110,7 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//The now function is used when you want to skip tp delay when teleporting someone to a location or player.
|
||||
@Override
|
||||
@Deprecated
|
||||
public void now(Location loc, boolean cooldown, TeleportCause cause) throws Exception {
|
||||
if (cooldown) {
|
||||
cooldown(false);
|
||||
@@ -109,6 +120,7 @@ public class Teleport implements ITeleport {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void now(Player entity, boolean cooldown, TeleportCause cause) throws Exception {
|
||||
if (cooldown) {
|
||||
cooldown(false);
|
||||
@@ -118,11 +130,28 @@ public class Teleport implements ITeleport {
|
||||
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
protected void now(IUser teleportee, ITarget target, TeleportCause cause) throws Exception {
|
||||
cancel(false);
|
||||
teleportee.setLastLocation();
|
||||
Location loc = target.getLocation();
|
||||
|
||||
PreTeleportEvent event = new PreTeleportEvent(teleportee, cause, target);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (teleportee.isAuthorized("essentials.back.onteleport")) {
|
||||
teleportee.setLastLocation();
|
||||
}
|
||||
|
||||
if (!teleportee.getBase().isEmpty()) {
|
||||
if (!ess.getSettings().isTeleportPassengerDismount()) {
|
||||
throw new Exception(tl("passengerTeleportFail"));
|
||||
}
|
||||
teleportee.getBase().eject();
|
||||
}
|
||||
|
||||
if (LocationUtil.isBlockUnsafeForUser(teleportee, loc.getWorld(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())) {
|
||||
if (ess.getSettings().isTeleportSafetyEnabled()) {
|
||||
if (ess.getSettings().isForceDisableTeleportSafety()) {
|
||||
@@ -154,12 +183,14 @@ public class Teleport implements ITeleport {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void teleport(Location loc, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
teleport(teleportOwner, new LocationTarget(loc), chargeFor, cause);
|
||||
}
|
||||
|
||||
//This is used when teleporting to a player
|
||||
@Override
|
||||
@Deprecated
|
||||
public void teleport(Player entity, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
ITarget target = new PlayerTarget(entity);
|
||||
teleportOwner.sendMessage(tl("teleportToPlayer", entity.getDisplayName()));
|
||||
@@ -168,12 +199,14 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//This is used when teleporting to stored location
|
||||
@Override
|
||||
@Deprecated
|
||||
public void teleportPlayer(IUser teleportee, Location loc, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
teleport(teleportee, new LocationTarget(loc), chargeFor, cause);
|
||||
}
|
||||
|
||||
//This is used on /tphere
|
||||
@Override
|
||||
@Deprecated
|
||||
public void teleportPlayer(IUser teleportee, Player entity, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
ITarget target = new PlayerTarget(entity);
|
||||
teleport(teleportee, target, chargeFor, cause);
|
||||
@@ -181,9 +214,17 @@ public class Teleport implements ITeleport {
|
||||
teleportOwner.sendMessage(tl("teleporting", target.getLocation().getWorld().getName(), target.getLocation().getBlockX(), target.getLocation().getBlockY(), target.getLocation().getBlockZ()));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void teleport(IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
TeleportWarmupEvent event = new TeleportWarmupEvent(teleportee, cause, target, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
Trade cashCharge = chargeFor;
|
||||
|
||||
if (chargeFor != null) {
|
||||
@@ -211,9 +252,17 @@ public class Teleport implements ITeleport {
|
||||
initTimer((long) (delay * 1000.0), teleportee, target, cashCharge, cause, false);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void teleportOther(IUser teleporter, IUser teleportee, ITarget target, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
TeleportWarmupEvent event = new TeleportWarmupEvent(teleporter, teleportee, cause, target, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
Trade cashCharge = chargeFor;
|
||||
|
||||
if (teleporter != null && chargeFor != null) {
|
||||
@@ -246,8 +295,17 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//The respawn function is a wrapper used to handle tp fallback, on /jail and /home
|
||||
@Override
|
||||
@Deprecated
|
||||
public void respawn(final Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
double delay = ess.getSettings().getTeleportDelay();
|
||||
|
||||
TeleportWarmupEvent event = new TeleportWarmupEvent(teleportOwner, cause, null, delay);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
delay = event.getDelay();
|
||||
|
||||
if (chargeFor != null) {
|
||||
chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
@@ -266,6 +324,7 @@ public class Teleport implements ITeleport {
|
||||
initTimer((long) (delay * 1000.0), teleportOwner, null, chargeFor, cause, true);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
void respawnNow(IUser teleportee, TeleportCause cause) throws Exception {
|
||||
final Player player = teleportee.getBase();
|
||||
Location bed = player.getBedSpawnLocation();
|
||||
@@ -283,13 +342,14 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//The warp function is a wrapper used to teleportPlayer a player to a /warp
|
||||
@Override
|
||||
@Deprecated
|
||||
public void warp(IUser teleportee, String warp, Trade chargeFor, TeleportCause cause) throws Exception {
|
||||
UserWarpEvent event = new UserWarpEvent(teleportee, warp, chargeFor);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if(event.isCancelled()) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
warp = event.getWarp();
|
||||
Location loc = ess.getWarps().getWarp(warp);
|
||||
teleportee.sendMessage(tl("warpingTo", warp, loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
@@ -301,12 +361,14 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//The back function is a wrapper used to teleportPlayer a player /back to their previous location.
|
||||
@Override
|
||||
@Deprecated
|
||||
public void back(Trade chargeFor) throws Exception {
|
||||
back(teleportOwner, chargeFor);
|
||||
}
|
||||
|
||||
//This function is a wrapper over the other back function for cases where another player performs back for them
|
||||
@Override
|
||||
@Deprecated
|
||||
public void back(IUser teleporter, Trade chargeFor) throws Exception {
|
||||
tpType = TeleportType.BACK;
|
||||
final Location loc = teleportOwner.getLastLocation();
|
||||
@@ -316,15 +378,18 @@ public class Teleport implements ITeleport {
|
||||
|
||||
//This function is used to throw a user back after a jail sentence
|
||||
@Override
|
||||
@Deprecated
|
||||
public void back() throws Exception {
|
||||
now(teleportOwner, new LocationTarget(teleportOwner.getLastLocation()), TeleportCause.COMMAND);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setTpType(TeleportType tpType) {
|
||||
this.tpType = tpType;
|
||||
}
|
||||
|
||||
//If we need to cancelTimer a pending teleportPlayer call this method
|
||||
@Deprecated
|
||||
private void cancel(boolean notifyUser) {
|
||||
if (timedTeleport != null) {
|
||||
timedTeleport.cancelTimer(notifyUser);
|
||||
@@ -332,6 +397,7 @@ public class Teleport implements ITeleport {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void initTimer(long delay, IUser teleportUser, ITarget target, Trade chargeFor, TeleportCause cause, boolean respawn) {
|
||||
timedTeleport = new TimedTeleport(teleportOwner, ess, this, delay, teleportUser, target, chargeFor, cause, respawn);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.UUID;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
@Deprecated
|
||||
public class TimedTeleport implements Runnable {
|
||||
private static final double MOVE_CONSTANT = 0.3;
|
||||
private final IUser teleportOwner;
|
||||
@@ -98,19 +98,17 @@ public class TimedTeleport implements Runnable {
|
||||
cancelTimer(false);
|
||||
teleportUser.sendMessage(tl("teleportationCommencing"));
|
||||
|
||||
try {
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
if (timer_respawn) {
|
||||
teleport.respawnNow(teleportUser, timer_cause);
|
||||
} else {
|
||||
teleport.now(teleportUser, timer_teleportTarget, timer_cause);
|
||||
}
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.charge(teleportOwner);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.isAffordableFor(teleportOwner);
|
||||
}
|
||||
if (timer_respawn) {
|
||||
teleport.respawnNow(teleportUser, timer_cause);
|
||||
} else {
|
||||
teleport.now(teleportUser, timer_teleportTarget, timer_cause);
|
||||
}
|
||||
if (timer_chargeFor != null) {
|
||||
timer_chargeFor.charge(teleportOwner);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
ess.showError(teleportOwner.getSource(), ex, "\\ teleport");
|
||||
|
||||
@@ -18,6 +18,8 @@ import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -81,26 +83,43 @@ public class Trade {
|
||||
}
|
||||
|
||||
public void isAffordableFor(final IUser user) throws ChargeException {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
isAffordableFor(user, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
try {
|
||||
future.get();
|
||||
} catch (InterruptedException e) { //If this happens, we have bigger problems...
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
throw (ChargeException) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void isAffordableFor(final IUser user, CompletableFuture<Boolean> future) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "checking if " + user.getName() + " can afford charge.");
|
||||
}
|
||||
|
||||
if (getMoney() != null && getMoney().signum() > 0 && !user.canAfford(getMoney())) {
|
||||
throw new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)));
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (getItemStack() != null && !user.getBase().getInventory().containsAtLeast(itemStack, itemStack.getAmount())) {
|
||||
throw new ChargeException(tl("missingItems", getItemStack().getAmount(), ess.getItemDb().name(getItemStack())));
|
||||
future.completeExceptionally(new ChargeException(tl("missingItems", getItemStack().getAmount(), ess.getItemDb().name(getItemStack()))));
|
||||
return;
|
||||
}
|
||||
|
||||
BigDecimal money;
|
||||
if (command != null && !command.isEmpty() && (money = getCommandCost(user)).signum() > 0 && !user.canAfford(money)) {
|
||||
throw new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(money, ess)));
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(money, ess))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (exp != null && exp > 0 && SetExpFix.getTotalExperience(user.getBase()) < exp) {
|
||||
throw new ChargeException(tl("notEnoughExperience"));
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughExperience")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +194,20 @@ public class Trade {
|
||||
}
|
||||
|
||||
public void charge(final IUser user) throws ChargeException {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
charge(user, future);
|
||||
if (future.isCompletedExceptionally()) {
|
||||
try {
|
||||
future.get();
|
||||
} catch (InterruptedException e) { //If this happens, we have bigger problems...
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
throw (ChargeException) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void charge(final IUser user, CompletableFuture<Boolean> future) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().log(Level.INFO, "attempting to charge user " + user.getName());
|
||||
}
|
||||
@@ -183,7 +216,8 @@ public class Trade {
|
||||
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " money " + getMoney().toPlainString());
|
||||
}
|
||||
if (!user.canAfford(getMoney()) && getMoney().signum() > 0) {
|
||||
throw new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess)));
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(getMoney(), ess))));
|
||||
return;
|
||||
}
|
||||
user.takeMoney(getMoney());
|
||||
}
|
||||
@@ -192,7 +226,8 @@ public class Trade {
|
||||
ess.getLogger().log(Level.INFO, "charging user " + user.getName() + " itemstack " + getItemStack().toString());
|
||||
}
|
||||
if (!user.getBase().getInventory().containsAtLeast(getItemStack(), getItemStack().getAmount())) {
|
||||
throw new ChargeException(tl("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " ")));
|
||||
future.completeExceptionally(new ChargeException(tl("missingItems", getItemStack().getAmount(), getItemStack().getType().toString().toLowerCase(Locale.ENGLISH).replace("_", " "))));
|
||||
return;
|
||||
}
|
||||
user.getBase().getInventory().removeItem(getItemStack());
|
||||
user.getBase().updateInventory();
|
||||
@@ -200,7 +235,8 @@ public class Trade {
|
||||
if (command != null) {
|
||||
final BigDecimal cost = getCommandCost(user);
|
||||
if (!user.canAfford(cost) && cost.signum() > 0) {
|
||||
throw new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(cost, ess)));
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(cost, ess))));
|
||||
return;
|
||||
}
|
||||
user.takeMoney(cost);
|
||||
}
|
||||
@@ -210,7 +246,8 @@ public class Trade {
|
||||
}
|
||||
final int experience = SetExpFix.getTotalExperience(user.getBase());
|
||||
if (experience < getExperience() && getExperience() > 0) {
|
||||
throw new ChargeException(tl("notEnoughExperience"));
|
||||
future.completeExceptionally(new ChargeException(tl("notEnoughExperience")));
|
||||
return;
|
||||
}
|
||||
SetExpFix.setTotalExperience(user.getBase(), experience - getExperience());
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
public class UUIDMap {
|
||||
private final transient net.ess3.api.IEssentials ess;
|
||||
private File userList;
|
||||
private final File userList;
|
||||
private final transient Pattern splitPattern = Pattern.compile(",");
|
||||
|
||||
private static boolean pendingWrite;
|
||||
@@ -28,15 +28,12 @@ public class UUIDMap {
|
||||
this.ess = ess;
|
||||
userList = new File(ess.getDataFolder(), "usermap.csv");
|
||||
pendingWrite = false;
|
||||
writeTaskRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (pendingWrite) {
|
||||
try {
|
||||
new WriteRunner(ess.getDataFolder(), userList, ess.getUserMap().getNames()).run();
|
||||
} catch (Throwable t) { // bad code to prevent task from being suppressed
|
||||
t.printStackTrace();
|
||||
}
|
||||
writeTaskRunnable = () -> {
|
||||
if (pendingWrite) {
|
||||
try {
|
||||
new WriteRunner(ess.getDataFolder(), userList, ess.getUserMap().getNames()).run();
|
||||
} catch (Throwable t) { // bad code to prevent task from being suppressed
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -16,8 +16,6 @@ import net.ess3.api.events.JailStatusChangeEvent;
|
||||
import net.ess3.api.events.MuteStatusChangeEvent;
|
||||
import net.ess3.api.events.UserBalanceUpdateEvent;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -28,7 +26,14 @@ import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
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.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -37,12 +42,13 @@ import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class User extends UserData implements Comparable<User>, IMessageRecipient, net.ess3.api.IUser {
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
private IMessageRecipient messageRecipient;
|
||||
private final IMessageRecipient messageRecipient;
|
||||
private transient UUID teleportRequester;
|
||||
private transient boolean teleportRequestHere;
|
||||
private transient Location teleportLocation;
|
||||
private transient boolean vanished;
|
||||
private transient final Teleport teleport;
|
||||
private transient final AsyncTeleport teleport;
|
||||
private transient final Teleport legacyTeleport;
|
||||
private transient long teleportRequestTime;
|
||||
private transient long lastOnlineActivity;
|
||||
private transient long lastThrottledAction;
|
||||
@@ -57,13 +63,16 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
private boolean ignoreMsg = false;
|
||||
private String afkMessage;
|
||||
private long afkSince;
|
||||
private Map<User, BigDecimal> confirmingPayments = new WeakHashMap<>();
|
||||
private final Map<User, BigDecimal> confirmingPayments = new WeakHashMap<>();
|
||||
private String confirmingClearCommand;
|
||||
private long lastNotifiedAboutMailsMs;
|
||||
private String lastHomeConfirmation;
|
||||
private long lastHomeConfirmationTimestamp;
|
||||
|
||||
public User(final Player base, final IEssentials ess) {
|
||||
super(base, ess);
|
||||
teleport = new Teleport(this, ess);
|
||||
teleport = new AsyncTeleport(this, ess);
|
||||
legacyTeleport = new Teleport(this, ess);
|
||||
if (isAfk()) {
|
||||
afkPosition = this.getLocation();
|
||||
}
|
||||
@@ -162,10 +171,14 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void giveMoney(final BigDecimal value, final CommandSource initiator) throws MaxMoneyException {
|
||||
giveMoney(value, initiator, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public void giveMoney(final BigDecimal value, final CommandSource initiator, UserBalanceUpdateEvent.Cause cause) throws MaxMoneyException {
|
||||
if (value.signum() == 0) {
|
||||
return;
|
||||
}
|
||||
setMoney(getMoney().add(value));
|
||||
setMoney(getMoney().add(value), cause);
|
||||
sendMessage(tl("addedToAccount", NumberUtil.displayCurrency(value, ess)));
|
||||
if (initiator != null) {
|
||||
initiator.sendMessage(tl("addedToOthersAccount", NumberUtil.displayCurrency(value, ess), this.getDisplayName(), NumberUtil.displayCurrency(getMoney(), ess)));
|
||||
@@ -174,13 +187,17 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void payUser(final User reciever, final BigDecimal value) throws Exception {
|
||||
payUser(reciever, value, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public void payUser(final User reciever, final BigDecimal value, UserBalanceUpdateEvent.Cause cause) throws Exception {
|
||||
if (value.compareTo(BigDecimal.ZERO) < 1) {
|
||||
throw new Exception(tl("payMustBePositive"));
|
||||
}
|
||||
|
||||
if (canAfford(value)) {
|
||||
setMoney(getMoney().subtract(value));
|
||||
reciever.setMoney(reciever.getMoney().add(value));
|
||||
setMoney(getMoney().subtract(value), cause);
|
||||
reciever.setMoney(reciever.getMoney().add(value), cause);
|
||||
sendMessage(tl("moneySentTo", NumberUtil.displayCurrency(value, ess), reciever.getDisplayName()));
|
||||
reciever.sendMessage(tl("moneyRecievedFrom", NumberUtil.displayCurrency(value, ess), getDisplayName()));
|
||||
} else {
|
||||
@@ -195,11 +212,15 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void takeMoney(final BigDecimal value, final CommandSource initiator) {
|
||||
takeMoney(value, initiator, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public void takeMoney(final BigDecimal value, final CommandSource initiator, UserBalanceUpdateEvent.Cause cause) {
|
||||
if (value.signum() == 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setMoney(getMoney().subtract(value));
|
||||
setMoney(getMoney().subtract(value), cause);
|
||||
} catch (MaxMoneyException ex) {
|
||||
ess.getLogger().log(Level.WARNING, "Invalid call to takeMoney, total balance can't be more than the max-money limit.", ex);
|
||||
}
|
||||
@@ -226,12 +247,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
_dispose();
|
||||
}
|
||||
});
|
||||
ess.runTaskAsynchronously(this::_dispose);
|
||||
}
|
||||
|
||||
private void _dispose() {
|
||||
@@ -329,26 +345,34 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
if (this.getBase().isOp()) {
|
||||
try {
|
||||
final ChatColor opPrefix = ess.getSettings().getOperatorColor();
|
||||
if (opPrefix != null && opPrefix.toString().length() > 0) {
|
||||
prefix.insert(0, opPrefix.toString());
|
||||
final String opPrefix = ess.getSettings().getOperatorColor();
|
||||
if (opPrefix != null && !opPrefix.isEmpty()) {
|
||||
prefix.insert(0, opPrefix);
|
||||
suffix = "§r";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ess.getSettings().addPrefixSuffix()) {
|
||||
//These two extra toggles are not documented, because they are mostly redundant #EasterEgg
|
||||
if (withPrefix || !ess.getSettings().disablePrefix()) {
|
||||
final String ptext = ess.getPermissionsHandler().getPrefix(base).replace('&', '§');
|
||||
final String ptext = FormatUtil.replaceFormat(ess.getPermissionsHandler().getPrefix(base));
|
||||
prefix.insert(0, ptext);
|
||||
suffix = "§r";
|
||||
}
|
||||
if (withSuffix || !ess.getSettings().disableSuffix()) {
|
||||
final String stext = ess.getPermissionsHandler().getSuffix(base).replace('&', '§');
|
||||
final String stext = FormatUtil.replaceFormat(ess.getPermissionsHandler().getSuffix(base));
|
||||
suffix = stext + "§r";
|
||||
suffix = suffix.replace("§f§f", "§f").replace("§f§r", "§r").replace("§r§r", "§r");
|
||||
// :YEP: WHAT ARE THEY DOING?
|
||||
// :YEP: STILL. LEGACY CODE.
|
||||
// :YEP: BUT WHY?
|
||||
// :YEP: I CAN'T BELIEVE THIS!
|
||||
// Code from 1542 BC #EasterEgg
|
||||
suffix = suffix.replace("§f§r", "§r").replace("§r§r", "§r");
|
||||
}
|
||||
}
|
||||
final String strPrefix = prefix.toString();
|
||||
@@ -394,10 +418,19 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
|
||||
@Override
|
||||
public Teleport getTeleport() {
|
||||
public AsyncTeleport getAsyncTeleport() {
|
||||
return teleport;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This API is not asynchronous. Use {@link User#getAsyncTeleport()}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Teleport getTeleport() {
|
||||
return legacyTeleport;
|
||||
}
|
||||
|
||||
public long getLastOnlineActivity() {
|
||||
return lastOnlineActivity;
|
||||
}
|
||||
@@ -432,7 +465,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
final Method.MethodAccount account = Methods.getMethod().getAccount(this.getName());
|
||||
return BigDecimal.valueOf(account.balance());
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return super.getMoney();
|
||||
@@ -440,6 +473,10 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void setMoney(final BigDecimal value) throws MaxMoneyException {
|
||||
setMoney(value, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public void setMoney(final BigDecimal value, UserBalanceUpdateEvent.Cause cause) throws MaxMoneyException {
|
||||
if (ess.getSettings().isEcoDisabled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Internal economy functions disabled, aborting balance change.");
|
||||
@@ -447,11 +484,11 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return;
|
||||
}
|
||||
final BigDecimal oldBalance = _getMoney();
|
||||
|
||||
UserBalanceUpdateEvent updateEvent = new UserBalanceUpdateEvent(this.getBase(), oldBalance, value);
|
||||
|
||||
UserBalanceUpdateEvent updateEvent = new UserBalanceUpdateEvent(this.getBase(), oldBalance, value, cause);
|
||||
ess.getServer().getPluginManager().callEvent(updateEvent);
|
||||
BigDecimal newBalance = updateEvent.getNewBalance();
|
||||
|
||||
|
||||
if (Methods.hasMethod()) {
|
||||
try {
|
||||
final Method method = Methods.getMethod();
|
||||
@@ -460,7 +497,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
final Method.MethodAccount account = Methods.getMethod().getAccount(this.getName());
|
||||
account.set(newBalance.doubleValue());
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
super.setMoney(newBalance, true);
|
||||
@@ -471,7 +508,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
if (ess.getSettings().isEcoDisabled()) {
|
||||
return;
|
||||
}
|
||||
if (Methods.hasMethod() && super.getMoney() != value) {
|
||||
if (Methods.hasMethod() && !super.getMoney().equals(value)) {
|
||||
try {
|
||||
super.setMoney(value, false);
|
||||
} catch (MaxMoneyException ex) {
|
||||
@@ -482,7 +519,12 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
@Override
|
||||
public void setAfk(final boolean set) {
|
||||
final AfkStatusChangeEvent afkEvent = new AfkStatusChangeEvent(this, set);
|
||||
setAfk(set, AfkStatusChangeEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAfk(boolean set, AfkStatusChangeEvent.Cause cause) {
|
||||
final AfkStatusChangeEvent afkEvent = new AfkStatusChangeEvent(this, set, cause);
|
||||
ess.getServer().getPluginManager().callEvent(afkEvent);
|
||||
if (afkEvent.isCancelled()) {
|
||||
return;
|
||||
@@ -500,7 +542,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
_setAfk(set);
|
||||
updateAfkListName();
|
||||
}
|
||||
|
||||
|
||||
private void updateAfkListName() {
|
||||
if (ess.getSettings().isAfkListName()) {
|
||||
if(isAfk()) {
|
||||
@@ -512,8 +554,13 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean toggleAfk() {
|
||||
setAfk(!isAfk());
|
||||
return toggleAfk(AfkStatusChangeEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public boolean toggleAfk(AfkStatusChangeEvent.Cause cause) {
|
||||
setAfk(!isAfk(), cause);
|
||||
return isAfk();
|
||||
}
|
||||
|
||||
@@ -529,7 +576,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
@Override
|
||||
public void setHidden(final boolean hidden) {
|
||||
this.hidden = hidden;
|
||||
if (hidden == true) {
|
||||
if (hidden) {
|
||||
setLastLogout(getLastOnlineActivity());
|
||||
}
|
||||
}
|
||||
@@ -546,14 +593,12 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
sendMessage(tl("haveBeenReleased"));
|
||||
setJail(null);
|
||||
if (ess.getSettings().isTeleportBackWhenFreedFromJail()) {
|
||||
try {
|
||||
getTeleport().back();
|
||||
} catch (Exception ex) {
|
||||
try {
|
||||
getTeleport().respawn(null, TeleportCause.PLUGIN);
|
||||
} catch (Exception ex1) {
|
||||
}
|
||||
}
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
getAsyncTeleport().back(future);
|
||||
future.exceptionally(e -> {
|
||||
getAsyncTeleport().respawn(null, TeleportCause.PLUGIN, new CompletableFuture<>());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -564,7 +609,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
//Returns true if status expired during this check
|
||||
public boolean checkMuteTimeout(final long currentTime) {
|
||||
if (getMuteTimeout() > 0 && getMuteTimeout() < currentTime && isMuted()) {
|
||||
final MuteStatusChangeEvent event = new MuteStatusChangeEvent(this, null, false);
|
||||
final MuteStatusChangeEvent event = new MuteStatusChangeEvent(this, null, false, getMuteTimeout(), getMuteReason());
|
||||
ess.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
@@ -578,14 +623,24 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
return false;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void updateActivity(final boolean broadcast) {
|
||||
updateActivity(broadcast, AfkStatusChangeEvent.Cause.UNKNOWN);
|
||||
}
|
||||
|
||||
public void updateActivity(final boolean broadcast, AfkStatusChangeEvent.Cause cause) {
|
||||
if (isAfk()) {
|
||||
setAfk(false);
|
||||
setAfk(false, cause);
|
||||
if (broadcast && !isHidden()) {
|
||||
setDisplayNick();
|
||||
final String msg = tl("userIsNotAway", getDisplayName());
|
||||
if (!msg.isEmpty()) {
|
||||
ess.broadcastMessage(this, msg);
|
||||
final String selfmsg = tl("userIsNotAwaySelf", getDisplayName());
|
||||
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
|
||||
// exclude user from receiving general AFK announcement in favor of personal message
|
||||
ess.broadcastMessage(this, msg, u -> u == this);
|
||||
}
|
||||
if (!selfmsg.isEmpty()) {
|
||||
this.sendMessage(selfmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -594,13 +649,13 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
|
||||
public void updateActivityOnMove(final boolean broadcast) {
|
||||
if(ess.getSettings().cancelAfkOnMove()) {
|
||||
updateActivity(broadcast);
|
||||
updateActivity(broadcast, AfkStatusChangeEvent.Cause.MOVE);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateActivityOnInteract(final boolean broadcast) {
|
||||
if(ess.getSettings().cancelAfkOnInteract()) {
|
||||
updateActivity(broadcast);
|
||||
updateActivity(broadcast, AfkStatusChangeEvent.Cause.INTERACT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,12 +683,17 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
final long autoafk = ess.getSettings().getAutoAfk();
|
||||
if (!isAfk() && autoafk > 0 && lastActivity + autoafk * 1000 < System.currentTimeMillis() && isAuthorized("essentials.afk.auto")) {
|
||||
setAfk(true);
|
||||
setAfk(true, AfkStatusChangeEvent.Cause.ACTIVITY);
|
||||
if (!isHidden()) {
|
||||
setDisplayNick();
|
||||
final String msg = tl("userIsAway", getDisplayName());
|
||||
if (!msg.isEmpty()) {
|
||||
ess.broadcastMessage(this, msg);
|
||||
final String selfmsg = tl("userIsAwaySelf", getDisplayName());
|
||||
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
|
||||
// exclude user from receiving general AFK announcement in favor of personal message
|
||||
ess.broadcastMessage(this, msg, u -> u == this);
|
||||
}
|
||||
if (!selfmsg.isEmpty()) {
|
||||
this.sendMessage(selfmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -655,9 +715,7 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
if (isAfk()) {
|
||||
// Protect AFK players by representing them in a god mode state to render them invulnerable to damage.
|
||||
if (ess.getSettings().getFreezeAfkPlayers()) {
|
||||
return true;
|
||||
}
|
||||
return ess.getSettings().getFreezeAfkPlayers();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -923,4 +981,20 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getLastHomeConfirmation() {
|
||||
return lastHomeConfirmation;
|
||||
}
|
||||
|
||||
public void setLastHomeConfirmation(String lastHomeConfirmation) {
|
||||
this.lastHomeConfirmation = lastHomeConfirmation;
|
||||
}
|
||||
|
||||
public long getLastHomeConfirmationTimestamp() {
|
||||
return lastHomeConfirmationTimestamp;
|
||||
}
|
||||
|
||||
public void setLastHomeConfirmationTimestamp() {
|
||||
this.lastHomeConfirmationTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
@@ -24,12 +25,11 @@ import static com.earth2me.essentials.I18n.tl;
|
||||
public abstract class UserData extends PlayerExtension implements IConf {
|
||||
protected final transient IEssentials ess;
|
||||
private final EssentialsUserConf config;
|
||||
private final File folder;
|
||||
|
||||
protected UserData(Player base, IEssentials ess) {
|
||||
super(base);
|
||||
this.ess = ess;
|
||||
folder = new File(ess.getDataFolder(), "userdata");
|
||||
File folder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
@@ -149,15 +149,14 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
if (config.isConfigurationSection("homes")) {
|
||||
return config.getConfigurationSection("homes").getValues(false);
|
||||
}
|
||||
return new HashMap<String, Object>();
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
private String getHomeName(String search) {
|
||||
if (NumberUtil.isInt(search)) {
|
||||
try {
|
||||
search = getHomes().get(Integer.parseInt(search) - 1);
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
} catch (NumberFormatException | IndexOutOfBoundsException ignored) {
|
||||
}
|
||||
}
|
||||
return search;
|
||||
@@ -189,7 +188,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
|
||||
public List<String> getHomes() {
|
||||
return new ArrayList<String>(homes.keySet());
|
||||
return new ArrayList<>(homes.keySet());
|
||||
}
|
||||
|
||||
public void setHome(String name, Location loc) {
|
||||
@@ -218,6 +217,10 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return config.hasProperty("home");
|
||||
}
|
||||
|
||||
public boolean hasHome(String name) {
|
||||
return config.hasProperty("homes." + name);
|
||||
}
|
||||
|
||||
private String nickname;
|
||||
|
||||
public String _getNickname() {
|
||||
@@ -234,10 +237,10 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
private List<Material> unlimited;
|
||||
private Set<Material> unlimited;
|
||||
|
||||
private List<Material> _getUnlimited() {
|
||||
List<Material> retlist = new ArrayList<>();
|
||||
private Set<Material> _getUnlimited() {
|
||||
Set<Material> retlist = new HashSet<>();
|
||||
List<String> configList = config.getStringList("unlimited");
|
||||
for(String s : configList) {
|
||||
Material mat = Material.matchMaterial(s);
|
||||
@@ -249,7 +252,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
return retlist;
|
||||
}
|
||||
|
||||
public List<Material> getUnlimited() {
|
||||
public Set<Material> getUnlimited() {
|
||||
return unlimited;
|
||||
}
|
||||
|
||||
@@ -258,13 +261,20 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
|
||||
public void setUnlimited(ItemStack stack, boolean state) {
|
||||
if (unlimited.contains(stack.getType())) {
|
||||
unlimited.remove(stack.getType());
|
||||
}
|
||||
boolean wasUpdated;
|
||||
if (state) {
|
||||
unlimited.add(stack.getType());
|
||||
wasUpdated = unlimited.add(stack.getType());
|
||||
} else {
|
||||
wasUpdated = unlimited.remove(stack.getType());
|
||||
}
|
||||
config.setProperty("unlimited", unlimited);
|
||||
|
||||
if (wasUpdated) {
|
||||
applyUnlimited();
|
||||
}
|
||||
}
|
||||
|
||||
private void applyUnlimited() {
|
||||
config.setProperty("unlimited", unlimited.stream().map(Enum::name).collect(Collectors.toList()));
|
||||
config.save();
|
||||
}
|
||||
|
||||
@@ -464,19 +474,42 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
config.save();
|
||||
}
|
||||
|
||||
private List<String> ignoredPlayers;
|
||||
private List<UUID> ignoredPlayers;
|
||||
|
||||
public List<String> _getIgnoredPlayers() {
|
||||
return Collections.synchronizedList(config.getStringList("ignore"));
|
||||
public List<UUID> _getIgnoredPlayers() {
|
||||
List<UUID> players = new ArrayList<>();
|
||||
for (String uuid : config.getStringList("ignore")) {
|
||||
try {
|
||||
players.add(UUID.fromString(uuid));
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
}
|
||||
return Collections.synchronizedList(players);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setIgnoredPlayers(List<String> players) {
|
||||
List<UUID> uuids = new ArrayList<>();
|
||||
for (String player : players) {
|
||||
User user = ess.getOfflineUser(player);
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
uuids.add(user.getBase().getUniqueId());
|
||||
}
|
||||
setIgnoredPlayerUUIDs(uuids);
|
||||
}
|
||||
|
||||
public void setIgnoredPlayerUUIDs(List<UUID> players) {
|
||||
if (players == null || players.isEmpty()) {
|
||||
ignoredPlayers = Collections.synchronizedList(new ArrayList<String>());
|
||||
ignoredPlayers = Collections.synchronizedList(new ArrayList<>());
|
||||
config.removeProperty("ignore");
|
||||
} else {
|
||||
ignoredPlayers = players;
|
||||
config.setProperty("ignore", players);
|
||||
List<String> uuids = new ArrayList<>();
|
||||
for (UUID uuid : players) {
|
||||
uuids.add(uuid.toString());
|
||||
}
|
||||
config.setProperty("ignore", uuids);
|
||||
}
|
||||
config.save();
|
||||
}
|
||||
@@ -491,17 +524,19 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
|
||||
public boolean isIgnoredPlayer(IUser user) {
|
||||
return (ignoredPlayers.contains(user.getName().toLowerCase(Locale.ENGLISH)) && !user.isIgnoreExempt());
|
||||
return ignoredPlayers.contains(user.getBase().getUniqueId()) && !user.isIgnoreExempt();
|
||||
}
|
||||
|
||||
public void setIgnoredPlayer(IUser user, boolean set) {
|
||||
final String entry = user.getName().toLowerCase(Locale.ENGLISH);
|
||||
UUID uuid = user.getBase().getUniqueId();
|
||||
if (set) {
|
||||
if (!ignoredPlayers.contains(entry)) ignoredPlayers.add(entry);
|
||||
if (!ignoredPlayers.contains(uuid)) {
|
||||
ignoredPlayers.add(uuid);
|
||||
}
|
||||
} else {
|
||||
ignoredPlayers.remove(entry);
|
||||
ignoredPlayers.remove(uuid);
|
||||
}
|
||||
setIgnoredPlayers(ignoredPlayers);
|
||||
setIgnoredPlayerUUIDs(ignoredPlayers);
|
||||
}
|
||||
|
||||
private boolean godmode;
|
||||
@@ -787,7 +822,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
|
||||
if (config.isConfigurationSection("timestamps.kits")) {
|
||||
final ConfigurationSection section = config.getConfigurationSection("timestamps.kits");
|
||||
final Map<String, Long> timestamps = new HashMap<String, Long>();
|
||||
final Map<String, Long> timestamps = new HashMap<>();
|
||||
for (String command : section.getKeys(false)) {
|
||||
if (section.isLong(command)) {
|
||||
timestamps.put(command.toLowerCase(Locale.ENGLISH), section.getLong(command));
|
||||
@@ -797,7 +832,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
}
|
||||
return timestamps;
|
||||
}
|
||||
return new HashMap<String, Long>();
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
public long getKitTimestamp(String name) {
|
||||
@@ -836,28 +871,28 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||
if (config.isConfigurationSection("info")) {
|
||||
return config.getConfigurationSection("info").getKeys(true);
|
||||
}
|
||||
return new HashSet<String>();
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
public Map<String, Object> getConfigMap() {
|
||||
if (config.isConfigurationSection("info")) {
|
||||
return config.getConfigurationSection("info").getValues(true);
|
||||
}
|
||||
return new HashMap<String, Object>();
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
public Map<String, Object> getConfigMap(String node) {
|
||||
if (config.isConfigurationSection("info." + node)) {
|
||||
return config.getConfigurationSection("info." + node).getValues(true);
|
||||
}
|
||||
return new HashMap<String, Object>();
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
// Pattern, Date. Pattern for less pattern creations
|
||||
private Map<Pattern, Long> commandCooldowns;
|
||||
|
||||
private Map<Pattern, Long> _getCommandCooldowns() {
|
||||
if (!config.isConfigurationSection("timestamps.command-cooldowns")) {
|
||||
if (!config.contains("timestamps.command-cooldowns")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
private final transient ConcurrentSkipListSet<UUID> keys = new ConcurrentSkipListSet<>();
|
||||
private final transient ConcurrentSkipListMap<String, UUID> names = new ConcurrentSkipListMap<>();
|
||||
private final transient ConcurrentSkipListMap<UUID, ArrayList<String>> history = new ConcurrentSkipListMap<>();
|
||||
private UUIDMap uuidMap;
|
||||
private final UUIDMap uuidMap;
|
||||
|
||||
private final transient Cache<String, User> users;
|
||||
private static boolean legacy = false;
|
||||
@@ -53,29 +53,26 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
}
|
||||
|
||||
private void loadAllUsersAsync(final IEssentials ess) {
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (users) {
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
keys.clear();
|
||||
users.invalidateAll();
|
||||
for (String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final String name = string.substring(0, string.length() - 4);
|
||||
try {
|
||||
keys.add(UUID.fromString(name));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
//Ignore these users till they rejoin.
|
||||
}
|
||||
}
|
||||
uuidMap.loadAllUsers(names, history);
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
synchronized (users) {
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
keys.clear();
|
||||
users.invalidateAll();
|
||||
for (String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final String name = string.substring(0, string.length() - 4);
|
||||
try {
|
||||
keys.add(UUID.fromString(name));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
//Ignore these users till they rejoin.
|
||||
}
|
||||
}
|
||||
uuidMap.loadAllUsers(names, history);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -112,9 +109,7 @@ public class UserMap extends CacheLoader<String, User> implements IConf {
|
||||
} else {
|
||||
return legacyCacheGet(uuid);
|
||||
}
|
||||
} catch (ExecutionException ex) {
|
||||
return null;
|
||||
} catch (UncheckedExecutionException ex) {
|
||||
} catch (ExecutionException | UncheckedExecutionException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ 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, EssentialsConf> warpPoints = new HashMap<StringIgnoreCase, EssentialsConf>();
|
||||
private final Map<StringIgnoreCase, EssentialsConf> warpPoints = new HashMap<>();
|
||||
private final File warpsFolder;
|
||||
private final Server server;
|
||||
|
||||
@@ -36,11 +36,11 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
|
||||
@Override
|
||||
public Collection<String> getList() {
|
||||
final List<String> keys = new ArrayList<String>();
|
||||
final List<String> keys = new ArrayList<>();
|
||||
for (StringIgnoreCase stringIgnoreCase : warpPoints.keySet()) {
|
||||
keys.add(stringIgnoreCase.getString());
|
||||
}
|
||||
Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
|
||||
keys.sort(String.CASE_INSENSITIVE_ORDER);
|
||||
return keys;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
try {
|
||||
uuid = UUID.fromString(conf.getString("lastowner"));
|
||||
}
|
||||
catch (Exception ex) {}
|
||||
catch (Exception ignored) {}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@@ -111,11 +111,11 @@ public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
warpPoints.clear();
|
||||
File[] listOfFiles = warpsFolder.listFiles();
|
||||
if (listOfFiles.length >= 1) {
|
||||
for (int i = 0; i < listOfFiles.length; i++) {
|
||||
String filename = listOfFiles[i].getName();
|
||||
if (listOfFiles[i].isFile() && filename.endsWith(".yml")) {
|
||||
for (File listOfFile : listOfFiles) {
|
||||
String filename = listOfFile.getName();
|
||||
if (listOfFile.isFile() && filename.endsWith(".yml")) {
|
||||
try {
|
||||
EssentialsConf conf = new EssentialsConf(listOfFiles[i]);
|
||||
EssentialsConf conf = new EssentialsConf(listOfFile);
|
||||
conf.load();
|
||||
String name = conf.getString("name");
|
||||
if (name != null) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import net.ess3.api.events.UserBalanceUpdateEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
@@ -41,7 +42,9 @@ public class Economy {
|
||||
File folder = new File(ess.getDataFolder(), "userdata");
|
||||
name = StringUtil.safeString(name);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
if (!folder.mkdirs()) {
|
||||
throw new RuntimeException("Error while creating userdata directory!");
|
||||
}
|
||||
}
|
||||
UUID npcUUID = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
EssentialsUserConf npcConfig = new EssentialsUserConf(name, npcUUID, new File(folder, npcUUID.toString() + ".yml"));
|
||||
@@ -63,7 +66,7 @@ public class Economy {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
if (name == null) {
|
||||
throw new RuntimeException("Economy username cannot be null");
|
||||
throw new IllegalArgumentException("Economy username cannot be null");
|
||||
}
|
||||
|
||||
User user = ess.getUser(name);
|
||||
@@ -85,9 +88,20 @@ public class Economy {
|
||||
return user;
|
||||
}
|
||||
|
||||
private static User getUserByUUID(UUID uuid) {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
if (uuid == null) {
|
||||
throw new IllegalArgumentException("Economy uuid cannot be null");
|
||||
}
|
||||
return ess.getUser(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the balance of a user
|
||||
*
|
||||
* @deprecated Use {@link Economy#getMoneyExact(UUID)} or {@link Economy#getMoneyExact(User)}
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @return balance
|
||||
@@ -106,17 +120,41 @@ public class Economy {
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Usernames can change, use {@link Economy#getMoneyExact(UUID)} or {@link Economy#getMoneyExact(User)}
|
||||
* @param name Name of user
|
||||
* @return Exact balance of user
|
||||
* @throws UserDoesNotExistException
|
||||
*/
|
||||
@Deprecated
|
||||
public static BigDecimal getMoneyExact(String name) throws UserDoesNotExistException {
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return getMoneyExact(user);
|
||||
}
|
||||
|
||||
public static BigDecimal getMoneyExact(UUID uuid) throws UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return getMoneyExact(user);
|
||||
}
|
||||
|
||||
public static BigDecimal getMoneyExact(User user) {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return user.getMoney();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the balance of a user
|
||||
*
|
||||
* @deprecated Use {@link Economy#setMoney(UUID, BigDecimal)} or {@link Economy#setMoney(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param balance The balance you want to set
|
||||
*
|
||||
@@ -132,11 +170,55 @@ public class Economy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the balance of a user
|
||||
*
|
||||
* @deprecated Usernames can change use {@link Economy#setMoney(UUID, BigDecimal)} or {@link Economy#setMoney(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of user
|
||||
* @param balance The balance you want to set
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
@Deprecated
|
||||
public static void setMoney(String name, BigDecimal balance) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
setMoney(user, balance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the balance of a user
|
||||
*
|
||||
* @param uuid UUID of user
|
||||
* @param balance The balance you want to set
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that uuid does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
public static void setMoney(UUID uuid, BigDecimal balance) throws NoLoanPermittedException, UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
setMoney(user, balance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the balance of a user
|
||||
*
|
||||
* @param user User
|
||||
* @param balance The balance you want to set
|
||||
*
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
public static void setMoney(User user, BigDecimal balance) throws NoLoanPermittedException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
if (balance.compareTo(ess.getSettings().getMinMoney()) < 0) {
|
||||
throw new NoLoanPermittedException();
|
||||
}
|
||||
@@ -144,16 +226,18 @@ public class Economy {
|
||||
throw new NoLoanPermittedException();
|
||||
}
|
||||
try {
|
||||
user.setMoney(balance);
|
||||
user.setMoney(balance, UserBalanceUpdateEvent.Cause.API);
|
||||
} catch (MaxMoneyException ex) {
|
||||
//TODO: Update API to show max balance errors
|
||||
}
|
||||
Trade.log("API", "Set", "API", name, new Trade(balance, ess), null, null, null, ess);
|
||||
Trade.log("API", "Set", "API", user.getName(), new Trade(balance, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds money to the balance of a user
|
||||
*
|
||||
* Use {@link Economy#add(UUID, BigDecimal)} or {@link Economy#add(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The money you want to add
|
||||
*
|
||||
@@ -169,17 +253,72 @@ public class Economy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds money to the balance of a user
|
||||
*
|
||||
* @deprecated Usernames can change, use {@link Economy#add(UUID, BigDecimal)} or {@link Economy#add(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money to be added to the user's account
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
@Deprecated
|
||||
public static void add(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).add(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Add", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
add(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Substracts money from the balance of a user
|
||||
* Adds money to the balance of a user
|
||||
*
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The money you want to add
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that uuid does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void add(UUID uuid, BigDecimal amount) throws NoLoanPermittedException, ArithmeticException, UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
add(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds money to the balance of a user
|
||||
*
|
||||
* @deprecated Usernames can change, use {@link Economy#add(UUID, BigDecimal)} or {@link Economy#add(User, BigDecimal)}
|
||||
*
|
||||
* @param user User
|
||||
* @param amount The money you want to add
|
||||
*
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void add(User user, BigDecimal amount) throws NoLoanPermittedException, ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
BigDecimal result = getMoneyExact(user).add(amount, MATH_CONTEXT);
|
||||
setMoney(user, result);
|
||||
Trade.log("API", "Add", "API", user.getName(), new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts money from the balance of a user
|
||||
*
|
||||
* @deprecated Use {@link Economy#subtract(UUID, BigDecimal)} or {@link Economy#subtract(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The money you want to substract
|
||||
* @param amount The money you want to subtract
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
@@ -189,19 +328,70 @@ public class Economy {
|
||||
try {
|
||||
substract(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to substract " + amount + " of balance of " + name + ": " + e.getMessage(), e);
|
||||
logger.log(Level.WARNING, "Failed to subtract " + amount + " of balance of " + name + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts money from the balance of a user
|
||||
*
|
||||
* @deprecated Usernames can change, use {@link Economy#subtract(UUID, BigDecimal)} or {@link Economy#subtract(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The money you want to subtract
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
@Deprecated
|
||||
public static void substract(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).subtract(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Subtract", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts money from the balance of a user
|
||||
*
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The money you want to subtract
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void subtract(UUID uuid, BigDecimal amount) throws NoLoanPermittedException, ArithmeticException, UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
subtract(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts money from the balance of a user
|
||||
*
|
||||
* @param user User
|
||||
* @param amount The money you want to subtract
|
||||
*
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void subtract(User user, BigDecimal amount) throws NoLoanPermittedException, ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
BigDecimal result = getMoneyExact(user).subtract(amount, MATH_CONTEXT);
|
||||
setMoney(user, result);
|
||||
Trade.log("API", "Subtract", "API", user.getName(), new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the balance of a user by a value
|
||||
*
|
||||
* @deprecated Use {@link Economy#divide(UUID, BigDecimal)} or {@link Economy#divide(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is divided by this value
|
||||
*
|
||||
@@ -217,15 +407,68 @@ public class Economy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the balance of a user by a value
|
||||
*
|
||||
* @deprecated Usernames can change, use {@link Economy#divide(UUID, BigDecimal)} or {@link Economy#divide(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is divided by this value
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
@Deprecated
|
||||
public static void divide(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).divide(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Divide", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
divide(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the balance of a user by a value
|
||||
*
|
||||
* @param uuid Name of the user
|
||||
* @param amount The balance is divided by this value
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void divide(UUID uuid, BigDecimal amount) throws NoLoanPermittedException, ArithmeticException, UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
divide(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the balance of a user by a value
|
||||
*
|
||||
* @param user Name of the user
|
||||
* @param amount The balance is divided by this value
|
||||
*
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void divide(User user, BigDecimal amount) throws NoLoanPermittedException, ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
BigDecimal result = getMoneyExact(user).divide(amount, MATH_CONTEXT);
|
||||
setMoney(user, result);
|
||||
Trade.log("API", "Divide", "API", user.getName(), new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the balance of a user by a value
|
||||
*
|
||||
* @deprecated Use {@link Economy#multiply(UUID, BigDecimal)} or {@link Economy#multiply(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is multiplied by this value
|
||||
*
|
||||
@@ -241,20 +484,74 @@ public class Economy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the balance of a user by a value
|
||||
*
|
||||
* @deprecated Usernames can change, use {@link Economy#multiply(UUID, BigDecimal)} or {@link Economy#multiply(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is multiplied by the this value
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
@Deprecated
|
||||
public static void multiply(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).multiply(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Multiply", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
multiply(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the balance of a user by a value
|
||||
*
|
||||
* @param uuid Name of the user
|
||||
* @param amount The balance is multiplied by the this value
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that uuid does not exist
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void multiply(UUID uuid, BigDecimal amount) throws NoLoanPermittedException, ArithmeticException, UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
multiply(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the balance of a user by a value
|
||||
*
|
||||
* @param user Name of the user
|
||||
* @param amount The balance is multiplied by the this value
|
||||
*
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static void multiply(User user, BigDecimal amount) throws NoLoanPermittedException, ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
BigDecimal result = getMoneyExact(user).multiply(amount, MATH_CONTEXT);
|
||||
setMoney(user, result);
|
||||
Trade.log("API", "Multiply", "API", user.getName(), new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the balance of a user to the starting balance
|
||||
*
|
||||
* @deprecated Usernames can change, use {@link Economy#resetBalance(UUID)} or {@link Economy#resetBalance(User)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
@Deprecated
|
||||
public static void resetBalance(String name) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
@@ -264,6 +561,42 @@ public class Economy {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the balance of a user to the starting balance
|
||||
*
|
||||
* @param uuid UUID of the user
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
public static void resetBalance(UUID uuid) throws NoLoanPermittedException, UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
resetBalance(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the balance of a user to the starting balance
|
||||
*
|
||||
* @param user User
|
||||
*
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
public static void resetBalance(User user) throws NoLoanPermittedException {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
setMoney(user, ess.getSettings().getStartingBalance());
|
||||
Trade.log("API", "Reset", "API", user.getName(), new Trade(BigDecimal.ZERO, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Economy#hasEnough(UUID, BigDecimal)} or {@link Economy#hasEnough(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
@@ -281,11 +614,60 @@ public class Economy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Usernames can change, use {@link Economy#hasEnough(UUID, BigDecimal)} or {@link Economy#hasEnough(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
* @return true, if the user has more or an equal amount of money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasEnough(String name, BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
return amount.compareTo(getMoneyExact(name)) <= 0;
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return hasEnough(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
* @return true, if the user has more or an equal amount of money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exist
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasEnough(UUID uuid, BigDecimal amount) throws ArithmeticException, UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return hasEnough(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param user User
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
* @return true, if the user has more or an equal amount of money
|
||||
*
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasEnough(User user, BigDecimal amount) throws ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return amount.compareTo(getMoneyExact(user)) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Economy#hasMore(UUID, BigDecimal)} or {@link Economy#hasMore(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
@@ -303,11 +685,61 @@ public class Economy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Usernames can change, use {@link Economy#hasMore(UUID, BigDecimal)} or {@link Economy#hasMore(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
* @return true, if the user has more money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasMore(String name, BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
return amount.compareTo(getMoneyExact(name)) < 0;
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return hasMore(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
* @return true, if the user has more money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exists
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasMore(UUID uuid, BigDecimal amount) throws ArithmeticException, UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return hasMore(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param user User
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
* @return true, if the user has more money
|
||||
*
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasMore(User user, BigDecimal amount) throws ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return amount.compareTo(getMoneyExact(user)) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Economy#hasLess(UUID, BigDecimal)} or {@link Economy#hasLess(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should not have
|
||||
*
|
||||
@@ -325,12 +757,62 @@ public class Economy {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Usernames can change, use {@link Economy#hasLess(UUID, BigDecimal)} or {@link Economy#hasLess(User, BigDecimal)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should not have
|
||||
*
|
||||
* @return true, if the user has less money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exist
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasLess(String name, BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
return amount.compareTo(getMoneyExact(name)) > 0;
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return hasLess(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uuid UUID of the user
|
||||
* @param amount The amount of money the user should not have
|
||||
*
|
||||
* @return true, if the user has less money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exist
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasLess(UUID uuid, BigDecimal amount) throws ArithmeticException, UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return hasLess(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param user User
|
||||
* @param amount The amount of money the user should not have
|
||||
*
|
||||
* @return true, if the user has less money
|
||||
*
|
||||
* @throws ArithmeticException
|
||||
*/
|
||||
public static boolean hasLess(User user, BigDecimal amount) throws ArithmeticException {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return amount.compareTo(getMoneyExact(user)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has a negative balance
|
||||
*
|
||||
* @deprecated Usernames can change, use {@link Economy#isNegative(UUID)} or {@link Economy#isNegative(User)}
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
@@ -338,8 +820,44 @@ public class Economy {
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isNegative(String name) throws UserDoesNotExistException {
|
||||
return getMoneyExact(name).signum() < 0;
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return isNegative(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has a negative balance
|
||||
*
|
||||
* @param uuid UUID of the user
|
||||
*
|
||||
* @return true, if the user has a negative balance
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that UUID does not exists
|
||||
*/
|
||||
public static boolean isNegative(UUID uuid) throws UserDoesNotExistException {
|
||||
User user = getUserByUUID(uuid);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(uuid);
|
||||
}
|
||||
return isNegative(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has a negative balance
|
||||
*
|
||||
* @param user User
|
||||
*
|
||||
* @return true, if the user has a negative balance
|
||||
*/
|
||||
public static boolean isNegative(User user) {
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("Economy user cannot be null");
|
||||
}
|
||||
return getMoneyExact(user).signum() < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,14 +887,28 @@ public class Economy {
|
||||
/**
|
||||
* Test if a player exists to avoid the UserDoesNotExistException
|
||||
*
|
||||
* @deprecated Essentials is moving away from username based economy methods. This may be removed in the future.
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @return true, if the user exists
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean playerExists(String name) {
|
||||
return getUserByName(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a player exists to avoid the UserDoesNotExistException
|
||||
*
|
||||
* @param uuid UUID of the user
|
||||
*
|
||||
* @return true, if the user exists
|
||||
*/
|
||||
public static boolean playerExists(UUID uuid) {
|
||||
return getUserByUUID(uuid) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a player is a npc
|
||||
*
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import com.earth2me.essentials.Trade;
|
||||
import net.ess3.api.IUser;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
public interface IAsyncTeleport {
|
||||
|
||||
/**
|
||||
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
|
||||
*
|
||||
* @param loc - Where should the player end up
|
||||
* @param cooldown - If cooldown should be enforced
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void now(Location loc, boolean cooldown, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
|
||||
*
|
||||
* @param entity - Where should the player end up
|
||||
* @param cooldown - If cooldown should be enforced
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void now(Player entity, boolean cooldown, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport a player to a specific location
|
||||
*
|
||||
* @param loc - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause.
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void teleport(Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport a player to a specific player
|
||||
*
|
||||
* @param entity - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void teleport(Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport a player to a specific location
|
||||
*
|
||||
* @param otherUser - Which user will be teleported
|
||||
* @param loc - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void teleportPlayer(IUser otherUser, Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport a player to a specific player
|
||||
*
|
||||
* @param otherUser - Which user will be teleported
|
||||
* @param entity - Where should the player end up
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void teleportPlayer(IUser otherUser, Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle tp fallback on /jail and /home
|
||||
*
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void respawn(final Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle /warp teleports
|
||||
*
|
||||
* @param otherUser - Which user will be teleported
|
||||
* @param warp - The name of the warp the user will be teleported too.
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param cause - The reported teleportPlayer cause
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void warp(IUser otherUser, String warp, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle /back teleports
|
||||
*
|
||||
* @param chargeFor - What the user will be charged if teleportPlayer is successful
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void back(Trade chargeFor, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle /back teleports that
|
||||
* are executed by a different player with this
|
||||
* instance of teleport as a target.
|
||||
*
|
||||
* @param teleporter - The user performing the /back command.
|
||||
* This value may be {@code null} to indicate console.
|
||||
* @param chargeFor - What the {@code teleporter} will be charged if teleportPlayer is successful
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void back(IUser teleporter, Trade chargeFor, CompletableFuture<Boolean> future);
|
||||
|
||||
/**
|
||||
* Teleport wrapper used to handle throwing user home after a jail sentence
|
||||
*
|
||||
* @param future - Future which is completed with the success status of the execution
|
||||
*/
|
||||
void back(CompletableFuture<Boolean> future);
|
||||
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@@ -55,7 +53,7 @@ public interface IItemDb {
|
||||
nameList = nameList.subList(0, 14);
|
||||
}
|
||||
return StringUtil.joinList(", ", nameList);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a List of all aliases for the given item stack.
|
||||
@@ -85,13 +83,12 @@ public interface IItemDb {
|
||||
List<ItemStack> getMatching(User user, String[] args) throws Exception;
|
||||
|
||||
/**
|
||||
* Serialise an ItemStack into a format that can be decoded by
|
||||
* {@link #get(String) get} and
|
||||
* {@link com.earth2me.essentials.MetaItemStack#parseStringMeta(CommandSource, boolean, String[], int, IEssentials)} MetaItemStack#parseStringMeta}.
|
||||
* Used to encode items for kits.
|
||||
* Converts the given {@link ItemStack} to a string representation that can be saved.
|
||||
* This is typically used for /createkit but can be used by other plugins for various purposes too.
|
||||
* Note that this will try registered resolvers first - to avoid this, use {@link net.ess3.api.IItemDb#serialize(ItemStack, boolean)} instead.
|
||||
*
|
||||
* @param is Stack to serialise
|
||||
* @return Serialised stack
|
||||
* @param is The stack to serialize
|
||||
* @return A string representing the given stack
|
||||
*/
|
||||
String serialize(ItemStack is);
|
||||
|
||||
@@ -130,11 +127,13 @@ public interface IItemDb {
|
||||
* item IDs to modern names.
|
||||
*
|
||||
* @param item Legacy ID in colon syntax.
|
||||
* @return
|
||||
* @return Material if an appropriate material exists, else null.
|
||||
*/
|
||||
default Material getFromLegacy(String item) {
|
||||
final String[] split = item.split(":");
|
||||
|
||||
if (!NumberUtil.isInt(split[0])) return null;
|
||||
|
||||
final int id = Integer.parseInt(split[0]);
|
||||
byte damage = 0;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.ess3.api.IUser;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
public interface IJails extends IReload {
|
||||
@@ -46,13 +47,27 @@ public interface IJails extends IReload {
|
||||
/**
|
||||
* Attempts to send the given user to the given jail
|
||||
*
|
||||
* @deprecated Use {@link IJails#sendToJail(IUser, String, CompletableFuture)}
|
||||
*
|
||||
* @param user the user to send to jail
|
||||
* @param jail the jail to send the user to
|
||||
*
|
||||
* @throws Exception if the user is offline or jail does not exist
|
||||
*/
|
||||
@Deprecated
|
||||
void sendToJail(IUser user, String jail) throws Exception;
|
||||
|
||||
/**
|
||||
* Attempts to send the given user to the given jail
|
||||
*
|
||||
* @param user the user to send to jail
|
||||
* @param jail the jail to send the user to
|
||||
* @param future Future which is completed with the success status of the execution
|
||||
*
|
||||
* @throws Exception if the user is offline or jail does not exist
|
||||
*/
|
||||
void sendToJail(IUser user, String jail, CompletableFuture<Boolean> future) throws Exception;
|
||||
|
||||
/**
|
||||
* Set a new jail with the given name and location
|
||||
*
|
||||
|
||||
@@ -7,6 +7,9 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated This API is not asynchronous. Use {@link com.earth2me.essentials.api.IAsyncTeleport IAsyncTeleport}
|
||||
*/
|
||||
public interface ITeleport {
|
||||
/**
|
||||
* Used to skip teleportPlayer delay when teleporting someone to a location or player.
|
||||
@@ -17,6 +20,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void now(Location loc, boolean cooldown, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -28,6 +32,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void now(Player entity, boolean cooldown, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
@Deprecated
|
||||
@@ -42,6 +47,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void teleport(Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -53,6 +59,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void teleport(Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -65,6 +72,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void teleportPlayer(IUser otherUser, Location loc, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -77,6 +85,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void teleportPlayer(IUser otherUser, Player entity, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -87,6 +96,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void respawn(final Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -99,6 +109,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void warp(IUser otherUser, String warp, Trade chargeFor, PlayerTeleportEvent.TeleportCause cause) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -108,6 +119,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void back(Trade chargeFor) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -117,10 +129,11 @@ public interface ITeleport {
|
||||
*
|
||||
* @param teleporter - The user performing the /back command.
|
||||
* This value may be {@code null} to indicate console.
|
||||
* @param chargeFor - What the {@code teleporter} will be charged if teleportPlayer is successful
|
||||
* @param chargeFor - What the {@code teleporter} will be charged if teleportPlayer is successful
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void back(IUser teleporter, Trade chargeFor) throws Exception;
|
||||
|
||||
/**
|
||||
@@ -128,6 +141,7 @@ public interface ITeleport {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Deprecated
|
||||
void back() throws Exception;
|
||||
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public interface IWarps extends IConf {
|
||||
/**
|
||||
* Gets Lastowner UUID
|
||||
*
|
||||
* @param name - Name of warp
|
||||
* @param warp - Name of warp
|
||||
*
|
||||
* @throws WarpNotFoundException
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
@@ -7,4 +9,8 @@ public class UserDoesNotExistException extends Exception {
|
||||
public UserDoesNotExistException(String name) {
|
||||
super(tl("userDoesNotExist", name));
|
||||
}
|
||||
|
||||
public UserDoesNotExistException(UUID uuid) {
|
||||
super(tl("uuidDoesNotExist", uuid.toString()));
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -24,10 +26,6 @@ public class Commandafk extends EssentialsCommand {
|
||||
afkUser = getPlayer(server, user, args, 0);
|
||||
message = args.length > 1 ? getFinalArg(args, 1) : null;
|
||||
} catch (PlayerNotFoundException e) {
|
||||
// If only one arg is passed, assume the command executor is targeting another player.
|
||||
if (args.length == 1) {
|
||||
throw e;
|
||||
}
|
||||
message = getFinalArg(args, 0);
|
||||
}
|
||||
toggleAfk(user, afkUser, message);
|
||||
@@ -51,7 +49,11 @@ public class Commandafk extends EssentialsCommand {
|
||||
private void toggleAfk(User sender, User user, String message) throws Exception {
|
||||
if (message != null && sender != null) {
|
||||
if (sender.isMuted()) {
|
||||
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReason", sender.getMuteReason()) : tl("voiceSilenced"));
|
||||
String dateDiff = sender.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(sender.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReason", sender.getMuteReason()) : tl("voiceSilenced"));
|
||||
}
|
||||
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, sender.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
if (!sender.isAuthorized("essentials.afk.message")) {
|
||||
throw new Exception(tl("noPermToAFKMessage"));
|
||||
@@ -59,25 +61,31 @@ public class Commandafk extends EssentialsCommand {
|
||||
}
|
||||
user.setDisplayNick();
|
||||
String msg = "";
|
||||
if (!user.toggleAfk()) {
|
||||
//user.sendMessage(_("markedAsNotAway"));
|
||||
String selfmsg = "";
|
||||
if (!user.toggleAfk(AfkStatusChangeEvent.Cause.COMMAND)) {
|
||||
if (!user.isHidden()) {
|
||||
msg = tl("userIsNotAway", user.getDisplayName());
|
||||
selfmsg = tl("userIsNotAwaySelf", user.getDisplayName());
|
||||
}
|
||||
user.updateActivity(false);
|
||||
user.updateActivity(false, AfkStatusChangeEvent.Cause.COMMAND);
|
||||
} else {
|
||||
//user.sendMessage(_("markedAsAway"));
|
||||
if (!user.isHidden()) {
|
||||
if (message != null) {
|
||||
msg = tl("userIsAwayWithMessage", user.getDisplayName(), message);
|
||||
selfmsg = tl("userIsAwaySelfWithMessage", user.getDisplayName(), message);
|
||||
} else {
|
||||
msg = tl("userIsAway", user.getDisplayName());
|
||||
selfmsg = tl("userIsAwaySelf", user.getDisplayName());
|
||||
}
|
||||
}
|
||||
user.setAfkMessage(message);
|
||||
}
|
||||
if (!msg.isEmpty()) {
|
||||
ess.broadcastMessage(user, msg);
|
||||
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
|
||||
// exclude user from receiving general AFK announcement in favor of personal message
|
||||
ess.broadcastMessage(user, msg, u -> u == user);
|
||||
}
|
||||
if (!selfmsg.isEmpty()) {
|
||||
user.sendMessage(selfmsg);
|
||||
}
|
||||
user.setDisplayNick(); // Set this again after toggling
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ public class Commandback extends EssentialsCommand {
|
||||
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
CommandSource sender = user.getSource();
|
||||
if (args.length > 0 && user.isAuthorized("essentials.back.others")) {
|
||||
this.parseCommand(server, sender, args, true);
|
||||
this.parseCommand(server, sender, args, true, commandLabel);
|
||||
return;
|
||||
}
|
||||
|
||||
teleportBack(sender, user);
|
||||
teleportBack(sender, user, commandLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,10 +36,10 @@ public class Commandback extends EssentialsCommand {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
this.parseCommand(server, sender, args, true);
|
||||
this.parseCommand(server, sender, args, true, commandLabel);
|
||||
}
|
||||
|
||||
private void parseCommand(Server server, CommandSource sender, String[] args, boolean allowOthers) throws Exception {
|
||||
private void parseCommand(Server server, CommandSource sender, String[] args, boolean allowOthers, String commandLabel) throws Exception {
|
||||
Collection<Player> players = new ArrayList<>();
|
||||
|
||||
if (allowOthers && args.length > 0 && args[0].trim().length() > 2) {
|
||||
@@ -52,11 +52,11 @@ public class Commandback extends EssentialsCommand {
|
||||
|
||||
for (Player player : players) {
|
||||
sender.sendMessage(tl("backOther", player.getName()));
|
||||
teleportBack(sender, ess.getUser(player));
|
||||
teleportBack(sender, ess.getUser(player), commandLabel);
|
||||
}
|
||||
}
|
||||
|
||||
private void teleportBack(CommandSource sender, User user) throws Exception {
|
||||
private void teleportBack(CommandSource sender, User user, String commandLabel) throws Exception {
|
||||
if (user.getLastLocation() == null) {
|
||||
throw new Exception(tl("noLocationFound"));
|
||||
}
|
||||
@@ -77,15 +77,15 @@ public class Commandback extends EssentialsCommand {
|
||||
}
|
||||
|
||||
if (requester == null) {
|
||||
user.getTeleport().back(null, null);
|
||||
user.getAsyncTeleport().back(null, null, getNewExceptionFuture(sender, commandLabel));
|
||||
} else if (!requester.equals(user)) {
|
||||
Trade charge = new Trade(this.getName(), this.ess);
|
||||
charge.isAffordableFor(requester);
|
||||
user.getTeleport().back(requester, charge);
|
||||
user.getAsyncTeleport().back(requester, charge, getNewExceptionFuture(sender, commandLabel));
|
||||
} else {
|
||||
Trade charge = new Trade(this.getName(), this.ess);
|
||||
charge.isAffordableFor(user);
|
||||
user.getTeleport().back(charge);
|
||||
user.getAsyncTeleport().back(charge, getNewExceptionFuture(sender, commandLabel));
|
||||
}
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public class Commandbalance extends EssentialsCommand {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
User target = getPlayer(server, args, 0, true, true);
|
||||
User target = getPlayer(server, args, 0, false, true);
|
||||
sender.sendMessage(tl("balanceOther", target.isHidden() ? target.getName() : target.getDisplayName(), NumberUtil.displayCurrency(target.getMoney(), ess)));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.bukkit.Server;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DateFormat;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
@@ -88,7 +87,7 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
try {
|
||||
if (force || cacheage <= System.currentTimeMillis() - CACHETIME) {
|
||||
cache.getLines().clear();
|
||||
final Map<String, BigDecimal> balances = new HashMap<String, BigDecimal>();
|
||||
final Map<String, BigDecimal> balances = new HashMap<>();
|
||||
BigDecimal totalMoney = BigDecimal.ZERO;
|
||||
if (ess.getSettings().isEcoDisabled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
@@ -113,13 +112,8 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
final List<Map.Entry<String, BigDecimal>> sortedEntries = new ArrayList<Map.Entry<String, BigDecimal>>(balances.entrySet());
|
||||
Collections.sort(sortedEntries, new Comparator<Map.Entry<String, BigDecimal>>() {
|
||||
@Override
|
||||
public int compare(final Entry<String, BigDecimal> entry1, final Entry<String, BigDecimal> entry2) {
|
||||
return entry2.getValue().compareTo(entry1.getValue());
|
||||
}
|
||||
});
|
||||
final List<Map.Entry<String, BigDecimal>> sortedEntries = new ArrayList<>(balances.entrySet());
|
||||
sortedEntries.sort((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue()));
|
||||
|
||||
cache.getLines().add(tl("serverTotal", NumberUtil.displayCurrency(totalMoney, ess)));
|
||||
int pos = 1;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.Mob;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandbeezooka extends EssentialsCommand {
|
||||
|
||||
public Commandbeezooka() {
|
||||
super("beezooka");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_15_R01)) {
|
||||
user.sendMessage(tl("unsupportedFeature"));
|
||||
return;
|
||||
}
|
||||
|
||||
final Entity bee = Mob.BEE.spawn(user.getWorld(), server, user.getBase().getEyeLocation());
|
||||
bee.setVelocity(user.getBase().getEyeLocation().getDirection().multiply(2));
|
||||
|
||||
ess.scheduleSyncDelayedTask(() -> {
|
||||
final Location loc = bee.getLocation();
|
||||
bee.remove();
|
||||
loc.getWorld().createExplosion(loc, 0F);
|
||||
}, 20);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,9 +33,11 @@ public class Commandbigtree extends EssentialsCommand {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final Location loc = LocationUtil.getTarget(user.getBase());
|
||||
final Location safeLocation = LocationUtil.getSafeDestination(loc);
|
||||
final boolean success = user.getWorld().generateTree(safeLocation, tree);
|
||||
final Location loc = LocationUtil.getTarget(user.getBase()).add(0, 1, 0);
|
||||
if (!user.getWorld().getBlockAt(loc).isPassable()) {
|
||||
throw new Exception(tl("bigTreeFailure"));
|
||||
}
|
||||
final boolean success = user.getWorld().generateTree(loc, tree);
|
||||
if (success) {
|
||||
user.sendMessage(tl("bigTreeSuccess"));
|
||||
} else {
|
||||
|
||||
@@ -6,8 +6,6 @@ import org.bukkit.Server;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
@@ -19,7 +17,7 @@ public class Commandbreak extends EssentialsCommand {
|
||||
//TODO: Switch to use util class
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final Block block = user.getBase().getTargetBlock((Set<Material>) null, 20);
|
||||
final Block block = user.getBase().getTargetBlock(null, 20);
|
||||
if (block == null) {
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -15,6 +13,8 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandclearinventory extends EssentialsCommand {
|
||||
|
||||
@@ -38,10 +38,10 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
|
||||
private void parseCommand(Server server, CommandSource sender, String commandLabel, String[] args, boolean allowOthers, boolean allowAll)
|
||||
throws Exception {
|
||||
Collection<Player> players = new ArrayList<Player>();
|
||||
Collection<Player> players = new ArrayList<>();
|
||||
User senderUser = ess.getUser(sender.getPlayer());
|
||||
String previousClearCommand = "";
|
||||
|
||||
|
||||
int offset = 0;
|
||||
|
||||
if (sender.isPlayer()) {
|
||||
@@ -80,39 +80,65 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
}
|
||||
}
|
||||
|
||||
protected void clearHandler(CommandSource sender, Player player, String[] args, int offset, boolean showExtended) throws Exception {
|
||||
short data = -1;
|
||||
int type = -1;
|
||||
private static class Item {
|
||||
private Material material;
|
||||
private short data;
|
||||
|
||||
public Item(Material material, short data) {
|
||||
this.material = material;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public short getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
private enum ClearHandlerType {
|
||||
ALL_EXCEPT_ARMOR, ALL_INCLUDING_ARMOR, SPECIFIC_ITEM
|
||||
}
|
||||
|
||||
protected void clearHandler(CommandSource sender, Player player, String[] args, int offset, boolean showExtended) {
|
||||
ClearHandlerType type = ClearHandlerType.ALL_EXCEPT_ARMOR;
|
||||
final Set<Item> items = new HashSet<>();
|
||||
int amount = -1;
|
||||
final Set<Material> mats = new HashSet<>();
|
||||
|
||||
if (args.length > (offset + 1) && NumberUtil.isInt(args[(offset + 1)])) {
|
||||
amount = Integer.parseInt(args[(offset + 1)]);
|
||||
}
|
||||
if (args.length > offset) {
|
||||
if (args[offset].equalsIgnoreCase("**")) {
|
||||
type = -2;
|
||||
type = ClearHandlerType.ALL_INCLUDING_ARMOR;
|
||||
} else if (!args[offset].equalsIgnoreCase("*")) {
|
||||
final String[] split = args[offset].split(",");
|
||||
|
||||
for (String name : split) {
|
||||
for (String item : split) {
|
||||
final String[] itemParts = item.split(":");
|
||||
short data;
|
||||
try {
|
||||
mats.add(ess.getItemDb().get(name).getType());
|
||||
data = Short.parseShort(itemParts[1]);
|
||||
} catch (Exception e) {
|
||||
data = 0;
|
||||
}
|
||||
try {
|
||||
items.add(new Item(ess.getItemDb().get(itemParts[0]).getType(), data));
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
type = 1;
|
||||
type = ClearHandlerType.SPECIFIC_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == -1) // type -1 represents wildcard or all items
|
||||
if (type == ClearHandlerType.ALL_EXCEPT_ARMOR)
|
||||
{
|
||||
if (showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearingAllItems", player.getDisplayName()));
|
||||
}
|
||||
InventoryWorkaround.clearInventoryNoArmor(player.getInventory());
|
||||
InventoryWorkaround.setItemInOffHand(player, null);
|
||||
} else if (type == -2) // type -2 represents double wildcard or all items and armor
|
||||
} else if (type == ClearHandlerType.ALL_INCLUDING_ARMOR)
|
||||
{
|
||||
if (showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearingAllArmor", player.getDisplayName()));
|
||||
@@ -121,20 +147,21 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
InventoryWorkaround.setItemInOffHand(player, null);
|
||||
player.getInventory().setArmorContents(null);
|
||||
} else {
|
||||
for (Material mat : mats) {
|
||||
for (Item item : items) {
|
||||
ItemStack stack = new ItemStack(item.getMaterial());
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_0_R01)) {
|
||||
stack.setDurability(item.getData());
|
||||
}
|
||||
if (amount == -1) // amount -1 means all items will be cleared
|
||||
{
|
||||
ItemStack stack = new ItemStack(mat, BASE_AMOUNT, data);
|
||||
stack.setAmount(BASE_AMOUNT);
|
||||
ItemStack removedStack = player.getInventory().removeItem(stack).get(0);
|
||||
final int removedAmount = (BASE_AMOUNT - removedStack.getAmount());
|
||||
if (removedAmount > 0 || showExtended) {
|
||||
sender.sendMessage(tl("inventoryClearingStack", removedAmount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
|
||||
}
|
||||
} else {
|
||||
if (amount < 0) {
|
||||
amount = 1;
|
||||
}
|
||||
ItemStack stack = new ItemStack(mat, amount);
|
||||
stack.setAmount(amount < 0 ? 1 : amount);
|
||||
if (player.getInventory().containsAtLeast(stack, amount)) {
|
||||
sender.sendMessage(tl("inventoryClearingStack", amount, stack.getType().toString().toLowerCase(Locale.ENGLISH), player.getDisplayName()));
|
||||
player.getInventory().removeItem(stack);
|
||||
@@ -195,6 +222,6 @@ public class Commandclearinventory extends EssentialsCommand {
|
||||
}
|
||||
|
||||
private String formatCommand(String commandLabel, String[] args) {
|
||||
return "/" + commandLabel + " " + StringUtil.joinList(" ", (Object[]) args);
|
||||
return "/" + commandLabel + " " + StringUtil.joinList(" ", args);
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public class Commandcondense extends EssentialsCommand {
|
||||
super("condense");
|
||||
}
|
||||
|
||||
private Map<ItemStack, SimpleRecipe> condenseList = new HashMap<>();
|
||||
private final Map<ItemStack, SimpleRecipe> condenseList = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
@@ -120,7 +120,7 @@ public class Commandcondense extends EssentialsCommand {
|
||||
}
|
||||
if (!bestRecipes.isEmpty()) {
|
||||
if (bestRecipes.size() > 1) {
|
||||
Collections.sort(bestRecipes, SimpleRecipeComparator.INSTANCE);
|
||||
bestRecipes.sort(SimpleRecipeComparator.INSTANCE);
|
||||
}
|
||||
SimpleRecipe recipe = bestRecipes.get(0);
|
||||
condenseList.put(stack, recipe);
|
||||
@@ -171,9 +171,9 @@ public class Commandcondense extends EssentialsCommand {
|
||||
}
|
||||
|
||||
|
||||
private class SimpleRecipe implements Recipe {
|
||||
private ItemStack result;
|
||||
private ItemStack input;
|
||||
private static class SimpleRecipe implements Recipe {
|
||||
private final ItemStack result;
|
||||
private final ItemStack input;
|
||||
|
||||
private SimpleRecipe(ItemStack result, ItemStack input) {
|
||||
this.result = result;
|
||||
|
||||
@@ -57,7 +57,7 @@ public class Commandcreatekit extends EssentialsCommand {
|
||||
}
|
||||
|
||||
// Command handler will auto fail if this fails.
|
||||
long delay = Long.valueOf(args[1]);
|
||||
long delay = Long.parseLong(args[1]);
|
||||
String kitname = args[0];
|
||||
ItemStack[] items = user.getBase().getInventory().getContents();
|
||||
List<String> list = new ArrayList<>();
|
||||
@@ -85,46 +85,43 @@ public class Commandcreatekit extends EssentialsCommand {
|
||||
}
|
||||
|
||||
private void uploadPaste(final CommandSource sender, final String kitName, final long delay, final String contents) {
|
||||
executorService.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(PASTE_UPLOAD_URL).openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestProperty("User-Agent", "EssentialsX plugin");
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
os.write(contents.getBytes(Charsets.UTF_8));
|
||||
}
|
||||
// Error
|
||||
if (connection.getResponseCode() >= 400) {
|
||||
sender.sendMessage(tl("createKitFailed", kitName));
|
||||
String message = CharStreams.toString(new InputStreamReader(connection.getErrorStream(), Charsets.UTF_8));
|
||||
ess.getLogger().severe("Error creating kit: " + message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read URL
|
||||
JsonObject object = GSON.fromJson(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8), JsonObject.class);
|
||||
String pasteUrl = PASTE_URL + object.get("key").getAsString();
|
||||
connection.disconnect();
|
||||
|
||||
String separator = tl("createKitSeparator");
|
||||
String delayFormat = "0";
|
||||
if (delay > 0) {
|
||||
delayFormat = DateUtil.formatDateDiff(System.currentTimeMillis() + (delay * 1000));
|
||||
}
|
||||
sender.sendMessage(separator);
|
||||
sender.sendMessage(tl("createKitSuccess", kitName, delayFormat, pasteUrl));
|
||||
sender.sendMessage(separator);
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info(sender.getSender().getName() + " created a kit: " + pasteUrl);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(tl("createKitFailed", kitName));
|
||||
e.printStackTrace();
|
||||
executorService.submit(() -> {
|
||||
try {
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(PASTE_UPLOAD_URL).openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestProperty("User-Agent", "EssentialsX plugin");
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
os.write(contents.getBytes(Charsets.UTF_8));
|
||||
}
|
||||
// Error
|
||||
if (connection.getResponseCode() >= 400) {
|
||||
sender.sendMessage(tl("createKitFailed", kitName));
|
||||
String message = CharStreams.toString(new InputStreamReader(connection.getErrorStream(), Charsets.UTF_8));
|
||||
ess.getLogger().severe("Error creating kit: " + message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read URL
|
||||
JsonObject object = GSON.fromJson(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8), JsonObject.class);
|
||||
String pasteUrl = PASTE_URL + object.get("key").getAsString();
|
||||
connection.disconnect();
|
||||
|
||||
String separator = tl("createKitSeparator");
|
||||
String delayFormat = "0";
|
||||
if (delay > 0) {
|
||||
delayFormat = DateUtil.formatDateDiff(System.currentTimeMillis() + (delay * 1000));
|
||||
}
|
||||
sender.sendMessage(separator);
|
||||
sender.sendMessage(tl("createKitSuccess", kitName, delayFormat, pasteUrl));
|
||||
sender.sendMessage(separator);
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info(sender.getSender().getName() + " created a kit: " + pasteUrl);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(tl("createKitFailed", kitName));
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -55,22 +55,25 @@ public class Commanddelhome extends EssentialsCommand {
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
boolean canDelOthers = (user == null || user.isAuthorized("essentials.delhome.others"));
|
||||
|
||||
boolean canDelOthers = user == null || user.isAuthorized("essentials.delhome.others");
|
||||
if (args.length == 1) {
|
||||
List<String> homes = user == null ? new ArrayList<>() : user.getHomes();
|
||||
if (canDelOthers) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return user.getHomes();
|
||||
}
|
||||
} else if (args.length == 2 && canDelOthers) {
|
||||
try {
|
||||
user = getPlayer(server, args, 0, true, true);
|
||||
return user.getHomes();
|
||||
} catch (Exception ex) {
|
||||
// No such user
|
||||
return Collections.emptyList();
|
||||
int sepIndex = args[0].indexOf(':');
|
||||
if (sepIndex < 0) {
|
||||
getPlayers(server, sender).forEach(player -> homes.add(player + ":"));
|
||||
} else {
|
||||
String namePart = args[0].substring(0, sepIndex);
|
||||
User otherUser;
|
||||
try {
|
||||
otherUser = getPlayer(server, new String[]{namePart}, 0, true, true);
|
||||
} catch (Exception ex) {
|
||||
return homes;
|
||||
}
|
||||
otherUser.getHomes().forEach(home -> homes.add(namePart + ":" + home));
|
||||
}
|
||||
}
|
||||
return homes;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.Kit;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commanddelkit extends EssentialsCommand {
|
||||
public Commanddelkit() {
|
||||
super("delkit");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
final String kitList = ess.getKits().listKits(ess, null);
|
||||
sender.sendMessage(kitList.length() > 0 ? tl("kits", kitList) : tl("noKits"));
|
||||
throw new NoChargeException();
|
||||
} else {
|
||||
final String kitName = ess.getKits().matchKit(args[0]);
|
||||
final Kit kit = new Kit(kitName, ess);
|
||||
|
||||
if (sender.getPlayer() != null) {
|
||||
kit.checkPerms(ess.getUser(sender.getPlayer()));
|
||||
}
|
||||
|
||||
ess.getKits().removeKit(kitName);
|
||||
sender.sendMessage(tl("deleteKit", kitName));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList(ess.getKits().getKits().getKeys(false));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class Commanddepth extends EssentialsCommand {
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final int depth = user.getLocation().getBlockY() - 63;
|
||||
final int depth = user.getLocation().getBlockY() - user.getWorld().getSeaLevel();
|
||||
if (depth > 0) {
|
||||
user.sendMessage(tl("depthAboveSea", depth));
|
||||
} else if (depth < 0) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import net.ess3.api.events.UserBalanceUpdateEvent;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -19,6 +20,7 @@ import static com.earth2me.essentials.I18n.tl;
|
||||
public class Commandeco extends EssentialsLoopCommand {
|
||||
Commandeco.EcoCommands cmd;
|
||||
BigDecimal amount;
|
||||
boolean isPercent;
|
||||
|
||||
public Commandeco() {
|
||||
super("eco");
|
||||
@@ -34,6 +36,7 @@ public class Commandeco extends EssentialsLoopCommand {
|
||||
|
||||
try {
|
||||
cmd = Commandeco.EcoCommands.valueOf(args[0].toUpperCase(Locale.ENGLISH));
|
||||
isPercent = cmd != EcoCommands.RESET && args[2].endsWith("%");
|
||||
amount = (cmd == Commandeco.EcoCommands.RESET) ? startingBalance : new BigDecimal(args[2].replaceAll("[^0-9\\.]", ""));
|
||||
} catch (Exception ex) {
|
||||
throw new NotEnoughArgumentsException(ex);
|
||||
@@ -52,9 +55,12 @@ public class Commandeco extends EssentialsLoopCommand {
|
||||
|
||||
@Override
|
||||
protected void updatePlayer(final Server server, final CommandSource sender, final User player, final String[] args) throws NotEnoughArgumentsException, ChargeException, MaxMoneyException {
|
||||
if (isPercent && cmd != EcoCommands.RESET) {
|
||||
amount = player.getMoney().multiply(amount).scaleByPowerOfTen(-2);
|
||||
}
|
||||
switch (cmd) {
|
||||
case GIVE:
|
||||
player.giveMoney(amount, sender);
|
||||
player.giveMoney(amount, sender, UserBalanceUpdateEvent.Cause.COMMAND_ECO);
|
||||
break;
|
||||
|
||||
case TAKE:
|
||||
@@ -72,10 +78,10 @@ public class Commandeco extends EssentialsLoopCommand {
|
||||
BigDecimal money = player.getMoney();
|
||||
BigDecimal minBalance = ess.getSettings().getMinMoney();
|
||||
if (money.subtract(amount).compareTo(minBalance) >= 0) {
|
||||
player.takeMoney(amount, sender);
|
||||
player.takeMoney(amount, sender, UserBalanceUpdateEvent.Cause.COMMAND_ECO);
|
||||
} else if (sender == null) {
|
||||
try {
|
||||
player.setMoney(minBalance);
|
||||
player.setMoney(minBalance, UserBalanceUpdateEvent.Cause.COMMAND_ECO);
|
||||
} catch (MaxMoneyException ex) {
|
||||
// Take shouldn't be able to throw a max money exception
|
||||
}
|
||||
@@ -90,7 +96,7 @@ public class Commandeco extends EssentialsLoopCommand {
|
||||
BigDecimal maxBalance = ess.getSettings().getMaxMoney();
|
||||
boolean underMinimum = (amount.compareTo(minBalance) < 0);
|
||||
boolean aboveMax = (amount.compareTo(maxBalance) > 0);
|
||||
player.setMoney(underMinimum ? minBalance : aboveMax ? maxBalance : amount);
|
||||
player.setMoney(underMinimum ? minBalance : aboveMax ? maxBalance : amount, UserBalanceUpdateEvent.Cause.COMMAND_ECO);
|
||||
player.sendMessage(tl("setBal", NumberUtil.displayCurrency(player.getMoney(), ess)));
|
||||
if (sender != null) {
|
||||
sender.sendMessage(tl("setBalOthers", player.getDisplayName(), NumberUtil.displayCurrency(player.getMoney(), ess)));
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandeditsign extends EssentialsCommand {
|
||||
public Commandeditsign() {
|
||||
super("editsign");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
if (args.length == 0 || (args.length > 1 && !NumberUtil.isInt(args[1]))) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
Block target = user.getBase().getTargetBlock(null, 5); //5 is a good number
|
||||
if (!(target.getState() instanceof Sign)) {
|
||||
throw new Exception(tl("editsignCommandTarget"));
|
||||
}
|
||||
Sign sign = (Sign) target.getState();
|
||||
try {
|
||||
if (args[0].equalsIgnoreCase("set") && args.length > 2) {
|
||||
int line = Integer.parseInt(args[1]) - 1;
|
||||
String text = FormatUtil.formatString(user, "essentials.editsign", getFinalArg(args, 2)).trim();
|
||||
if (ChatColor.stripColor(text).length() > 15 && !user.isAuthorized("essentials.editsign.unlimited")) {
|
||||
throw new Exception(tl("editsignCommandLimit"));
|
||||
}
|
||||
sign.setLine(line, text);
|
||||
sign.update();
|
||||
user.sendMessage(tl("editsignCommandSetSuccess", line + 1, text));
|
||||
} else if (args[0].equalsIgnoreCase("clear")) {
|
||||
if (args.length == 1) {
|
||||
for (int i = 0; i < 4; i++) { // A whole one line of line savings!
|
||||
sign.setLine(i, "");
|
||||
}
|
||||
sign.update();
|
||||
user.sendMessage(tl("editsignCommandClear"));
|
||||
} else {
|
||||
int line = Integer.parseInt(args[1]) - 1;
|
||||
sign.setLine(line, "");
|
||||
sign.update();
|
||||
user.sendMessage(tl("editsignCommandClearLine", line + 1));
|
||||
}
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw new Exception(tl("editsignCommandNoLine"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("set", "clear");
|
||||
} else if (args.length == 2) {
|
||||
return Lists.newArrayList("1", "2", "3", "4");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,96 +6,144 @@ import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.UserMap;
|
||||
import com.earth2me.essentials.utils.*;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
// This command has 4 undocumented behaviours #EasterEgg
|
||||
public class Commandessentials extends EssentialsCommand {
|
||||
|
||||
private final Sound NOTE_HARP = EnumUtil.valueOf(Sound.class, "BLOCK_NOTE_BLOCK_HARP", "BLOCK_NOTE_HARP", "NOTE_PIANO");
|
||||
private static final Sound NOTE_HARP = EnumUtil.valueOf(Sound.class, "BLOCK_NOTE_BLOCK_HARP", "BLOCK_NOTE_HARP", "NOTE_PIANO");
|
||||
private static final Sound MOO_SOUND = EnumUtil.valueOf(Sound.class, "COW_IDLE", "ENTITY_COW_MILK");
|
||||
|
||||
private static final String NYAN_TUNE = "1D#,1E,2F#,,2A#,1E,1D#,1E,2F#,2B,2D#,2E,2D#,2A#,2B,,2F#,,1D#,1E,2F#,2B,2C#,2A#,2B,2C#,2E,2D#,2E,2C#,,2F#,,2G#,,1D,1D#,,1C#,1D,1C#,1B,,1B,,1C#,,1D,,1D,1C#,1B,1C#,1D#,2F#,2G#,1D#,2F#,1C#,1D#,1B,1C#,1B,1D#,,2F#,,2G#,1D#,2F#,1C#,1D#,1B,1D,1D#,1D,1C#,1B,1C#,1D,,1B,1C#,1D#,2F#,1C#,1D,1C#,1B,1C#,,1B,,1C#,,2F#,,2G#,,1D,1D#,,1C#,1D,1C#,1B,,1B,,1C#,,1D,,1D,1C#,1B,1C#,1D#,2F#,2G#,1D#,2F#,1C#,1D#,1B,1C#,1B,1D#,,2F#,,2G#,1D#,2F#,1C#,1D#,1B,1D,1D#,1D,1C#,1B,1C#,1D,,1B,1C#,1D#,2F#,1C#,1D,1C#,1B,1C#,,1B,,1B,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1B,,";
|
||||
private static final String[] CONSOLE_MOO = new String[]{" (__)", " (oo)", " /------\\/", " / | ||", " * /\\---/\\", " ~~ ~~", "....\"Have you mooed today?\"..."};
|
||||
private static final String[] PLAYER_MOO = new String[]{" (__)", " (oo)", " /------\\/", " / | | |", " * /\\---/\\", " ~~ ~~", "....\"Have you mooed today?\"..."};
|
||||
|
||||
public Commandessentials() {
|
||||
super("essentials");
|
||||
}
|
||||
|
||||
private transient int taskid;
|
||||
private final transient Map<Player, Block> noteBlocks = new HashMap<Player, Block>();
|
||||
private transient TuneRunnable currentTune = null;
|
||||
|
||||
private final List<String> versionPlugins = Arrays.asList(
|
||||
"Vault",
|
||||
"LuckPerms",
|
||||
"PermissionsEx",
|
||||
"GroupManager"
|
||||
private static final List<String> versionPlugins = Arrays.asList(
|
||||
"Vault", // API
|
||||
"Reserve", // API
|
||||
"PlaceholderAPI", // API
|
||||
"CMI", // potential for issues
|
||||
"Towny", // past issues; admins should ensure latest
|
||||
"ChestShop", // past issues; admins should ensure latest
|
||||
"Citizens", // fires player events
|
||||
"LuckPerms", // permissions (recommended)
|
||||
"UltraPermissions",
|
||||
"PermissionsEx", // permissions (unsupported)
|
||||
"GroupManager", // permissions (unsupported)
|
||||
"bPermissions" // permissions (unsupported)
|
||||
);
|
||||
|
||||
private final List<String> officialPlugins = Arrays.asList(
|
||||
"EssentialsAntiBuild",
|
||||
"EssentialsChat",
|
||||
"EssentialsGeoIP",
|
||||
"EssentialsProtect",
|
||||
"EssentialsSpawn",
|
||||
"EssentialsXMPP"
|
||||
private static final List<String> officialPlugins = Arrays.asList(
|
||||
"EssentialsAntiBuild",
|
||||
"EssentialsChat",
|
||||
"EssentialsGeoIP",
|
||||
"EssentialsProtect",
|
||||
"EssentialsSpawn",
|
||||
"EssentialsXMPP"
|
||||
);
|
||||
|
||||
private final List<String> warnPlugins = Arrays.asList(
|
||||
"PermissionsEx",
|
||||
"GroupManager"
|
||||
private static final List<String> warnPlugins = Arrays.asList(
|
||||
"PermissionsEx",
|
||||
"GroupManager",
|
||||
"bPremissions"
|
||||
);
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
run_disabled(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("debug")) {
|
||||
run_debug(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("nya")) {
|
||||
run_nya(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("moo")) {
|
||||
run_moo(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("reset")) {
|
||||
run_reset(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("cleanup")) {
|
||||
run_cleanup(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("uuidconvert")) {
|
||||
run_uuidconvert(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("uuidtest")) {
|
||||
run_uuidtest(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("version")) {
|
||||
run_version(server, sender, commandLabel, args);
|
||||
} else {
|
||||
run_reload(server, sender, commandLabel, args);
|
||||
showUsage(sender);
|
||||
}
|
||||
|
||||
switch(args[0]) {
|
||||
// Info commands
|
||||
case "debug":
|
||||
case "verbose":
|
||||
runDebug(server, sender, commandLabel, args);
|
||||
break;
|
||||
|
||||
case "ver":
|
||||
case "version":
|
||||
runVersion(server, sender, commandLabel, args);
|
||||
break;
|
||||
|
||||
case "cmd":
|
||||
case "commands":
|
||||
runCommands(server, sender, commandLabel, args);
|
||||
break;
|
||||
|
||||
// Data commands
|
||||
case "reload":
|
||||
runReload(server, sender, commandLabel, args);
|
||||
break;
|
||||
case "reset":
|
||||
runReset(server, sender, commandLabel, args);
|
||||
break;
|
||||
case "cleanup":
|
||||
runCleanup(server, sender, commandLabel, args);
|
||||
break;
|
||||
case "uuidconvert":
|
||||
runUUIDConvert(server, sender, commandLabel, args);
|
||||
break;
|
||||
case "uuidtest":
|
||||
runUUIDTest(server, sender, commandLabel, args);
|
||||
break;
|
||||
|
||||
// "#EasterEgg"
|
||||
case "nya":
|
||||
case "nyan":
|
||||
runNya(server, sender, commandLabel, args);
|
||||
break;
|
||||
case "moo":
|
||||
runMoo(server, sender, commandLabel, args);
|
||||
break;
|
||||
default:
|
||||
showUsage(sender);
|
||||
}
|
||||
}
|
||||
|
||||
//If you do not supply an argument this command will list 'overridden' commands.
|
||||
private void run_disabled(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
sender.sendMessage("/<command> <reload/debug>");
|
||||
// Displays the command's usage.
|
||||
private void showUsage(final CommandSource sender) throws Exception {
|
||||
throw new NotEnoughArgumentsException("/<command> <reload/debug/commands>");
|
||||
}
|
||||
|
||||
// Lists commands that are being handed over to other plugins.
|
||||
private void runCommands(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
final StringBuilder disabledCommands = new StringBuilder();
|
||||
for (Map.Entry<String, String> entry : ess.getAlternativeCommandsHandler().disabledCommands().entrySet()) {
|
||||
if (disabledCommands.length() > 0) {
|
||||
disabledCommands.append(", ");
|
||||
disabledCommands.append("\n");
|
||||
}
|
||||
disabledCommands.append(entry.getKey()).append(" => ").append(entry.getValue());
|
||||
}
|
||||
if (disabledCommands.length() > 0) {
|
||||
sender.sendMessage(tl("blockList"));
|
||||
sender.sendMessage(disabledCommands.toString());
|
||||
} else {
|
||||
sender.sendMessage(tl("blockListEmpty"));
|
||||
}
|
||||
}
|
||||
|
||||
private void run_reset(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
// Resets the given player's user data.
|
||||
private void runReset(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
throw new Exception("/<command> reset <player>");
|
||||
}
|
||||
@@ -104,108 +152,59 @@ public class Commandessentials extends EssentialsCommand {
|
||||
sender.sendMessage("Reset Essentials userdata for player: " + user.getDisplayName());
|
||||
}
|
||||
|
||||
private void run_debug(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
// Toggles debug mode.
|
||||
private void runDebug(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
ess.getSettings().setDebug(!ess.getSettings().isDebug());
|
||||
sender.sendMessage("Essentials " + ess.getDescription().getVersion() + " debug mode " + (ess.getSettings().isDebug() ? "enabled" : "disabled"));
|
||||
}
|
||||
|
||||
private void run_reload(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
// Reloads all reloadable configs.
|
||||
private void runReload(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
ess.reload();
|
||||
sender.sendMessage(tl("essentialsReload", ess.getDescription().getVersion()));
|
||||
}
|
||||
|
||||
private void run_nya(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
final Map<String, Float> noteMap = new HashMap<String, Float>();
|
||||
noteMap.put("1F#", 0.5f);
|
||||
noteMap.put("1G", 0.53f);
|
||||
noteMap.put("1G#", 0.56f);
|
||||
noteMap.put("1A", 0.6f);
|
||||
noteMap.put("1A#", 0.63f);
|
||||
noteMap.put("1B", 0.67f);
|
||||
noteMap.put("1C", 0.7f);
|
||||
noteMap.put("1C#", 0.76f);
|
||||
noteMap.put("1D", 0.8f);
|
||||
noteMap.put("1D#", 0.84f);
|
||||
noteMap.put("1E", 0.9f);
|
||||
noteMap.put("1F", 0.94f);
|
||||
noteMap.put("2F#", 1.0f);
|
||||
noteMap.put("2G", 1.06f);
|
||||
noteMap.put("2G#", 1.12f);
|
||||
noteMap.put("2A", 1.18f);
|
||||
noteMap.put("2A#", 1.26f);
|
||||
noteMap.put("2B", 1.34f);
|
||||
noteMap.put("2C", 1.42f);
|
||||
noteMap.put("2C#", 1.5f);
|
||||
noteMap.put("2D", 1.6f);
|
||||
noteMap.put("2D#", 1.68f);
|
||||
noteMap.put("2E", 1.78f);
|
||||
noteMap.put("2F", 1.88f);
|
||||
final String tuneStr = "1D#,1E,2F#,,2A#,1E,1D#,1E,2F#,2B,2D#,2E,2D#,2A#,2B,,2F#,,1D#,1E,2F#,2B,2C#,2A#,2B,2C#,2E,2D#,2E,2C#,,2F#,,2G#,,1D,1D#,,1C#,1D,1C#,1B,,1B,,1C#,,1D,,1D,1C#,1B,1C#,1D#,2F#,2G#,1D#,2F#,1C#,1D#,1B,1C#,1B,1D#,,2F#,,2G#,1D#,2F#,1C#,1D#,1B,1D,1D#,1D,1C#,1B,1C#,1D,,1B,1C#,1D#,2F#,1C#,1D,1C#,1B,1C#,,1B,,1C#,,2F#,,2G#,,1D,1D#,,1C#,1D,1C#,1B,,1B,,1C#,,1D,,1D,1C#,1B,1C#,1D#,2F#,2G#,1D#,2F#,1C#,1D#,1B,1C#,1B,1D#,,2F#,,2G#,1D#,2F#,1C#,1D#,1B,1D,1D#,1D,1C#,1B,1C#,1D,,1B,1C#,1D#,2F#,1C#,1D,1C#,1B,1C#,,1B,,1B,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1B,,";
|
||||
final String[] tune = tuneStr.split(",");
|
||||
taskid = ess.scheduleSyncRepeatingTask(new Runnable() {
|
||||
int i = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final String note = tune[i];
|
||||
i++;
|
||||
if (i >= tune.length) {
|
||||
Commandessentials.this.stopTune();
|
||||
}
|
||||
if (note == null || note.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player onlinePlayer : ess.getOnlinePlayers()) {
|
||||
onlinePlayer.playSound(onlinePlayer.getLocation(), NOTE_HARP, 1, noteMap.get(note));
|
||||
}
|
||||
}
|
||||
}, 20, 2);
|
||||
}
|
||||
|
||||
private void stopTune() {
|
||||
ess.getScheduler().cancelTask(taskid);
|
||||
for (Block block : noteBlocks.values()) {
|
||||
if (block.getType() == Material.NOTE_BLOCK) {
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
// Pop tarts.
|
||||
private void runNya(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (currentTune != null) {
|
||||
currentTune.cancel();
|
||||
}
|
||||
noteBlocks.clear();
|
||||
|
||||
currentTune = new TuneRunnable(NYAN_TUNE, NOTE_HARP, ess::getOnlinePlayers);
|
||||
currentTune.runTaskTimer(ess, 20, 2);
|
||||
}
|
||||
|
||||
private final String[] consoleMoo = new String[]{" (__)", " (oo)", " /------\\/", " / | ||", " * /\\---/\\", " ~~ ~~", "....\"Have you mooed today?\"..."};
|
||||
private final String[] playerMoo = new String[]{" (__)", " (oo)", " /------\\/", " / | | |", " * /\\---/\\", " ~~ ~~", "....\"Have you mooed today?\"..."};
|
||||
|
||||
private void run_moo(final Server server, final CommandSource sender, final String command, final String args[]) {
|
||||
Sound moo = EnumUtil.valueOf(Sound.class, "COW_IDLE", "ENTITY_COW_MILK");
|
||||
|
||||
// Cow farts.
|
||||
private void runMoo(final Server server, final CommandSource sender, final String command, final String[] args) {
|
||||
if (args.length == 2 && args[1].equals("moo")) {
|
||||
for (String s : consoleMoo) {
|
||||
for (String s : CONSOLE_MOO) {
|
||||
logger.info(s);
|
||||
}
|
||||
for (Player player : ess.getOnlinePlayers()) {
|
||||
player.sendMessage(playerMoo);
|
||||
player.playSound(player.getLocation(), moo, 1, 1.0f);
|
||||
player.sendMessage(PLAYER_MOO);
|
||||
player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f);
|
||||
}
|
||||
} else {
|
||||
if (sender.isPlayer()) {
|
||||
sender.getSender().sendMessage(playerMoo);
|
||||
sender.getSender().sendMessage(PLAYER_MOO);
|
||||
final Player player = sender.getPlayer();
|
||||
player.playSound(player.getLocation(), moo, 1, 1.0f);
|
||||
player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f);
|
||||
|
||||
} else {
|
||||
sender.getSender().sendMessage(consoleMoo);
|
||||
sender.getSender().sendMessage(CONSOLE_MOO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void run_cleanup(final Server server, final CommandSource sender, final String command, final String args[]) throws Exception {
|
||||
// Cleans up inactive users.
|
||||
private void runCleanup(final Server server, final CommandSource sender, final String command, final String[] args) throws Exception {
|
||||
if (args.length < 2 || !NumberUtil.isInt(args[1])) {
|
||||
sender.sendMessage("This sub-command will delete users who havent logged in in the last <days> days.");
|
||||
sender.sendMessage("Optional parameters define the minium amount required to prevent deletion.");
|
||||
sender.sendMessage("Unless you define larger default values, this command wil ignore people who have more than 0 money/homes.");
|
||||
sender.sendMessage("This sub-command will delete users who haven't logged in in the last <days> days.");
|
||||
sender.sendMessage("Optional parameters define the minimum amount required to prevent deletion.");
|
||||
sender.sendMessage("Unless you define larger default values, this command will ignore people who have more than 0 money/homes.");
|
||||
throw new Exception("/<command> cleanup <days> [money] [homes]");
|
||||
}
|
||||
|
||||
sender.sendMessage(tl("cleaning"));
|
||||
|
||||
final long daysArg = Long.parseLong(args[1]);
|
||||
@@ -213,59 +212,58 @@ public class Commandessentials extends EssentialsCommand {
|
||||
final int homesArg = args.length >= 4 && NumberUtil.isInt(args[3]) ? Integer.parseInt(args[3]) : 0;
|
||||
final UserMap userMap = ess.getUserMap();
|
||||
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Long currTime = System.currentTimeMillis();
|
||||
for (UUID u : userMap.getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long lastLog = user.getLastLogout();
|
||||
if (lastLog == 0) {
|
||||
lastLog = user.getLastLogin();
|
||||
}
|
||||
if (lastLog == 0) {
|
||||
user.setLastLogin(currTime);
|
||||
}
|
||||
|
||||
if (user.isNPC()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long timeDiff = currTime - lastLog;
|
||||
long milliDays = daysArg * 24L * 60L * 60L * 1000L;
|
||||
int homeCount = user.getHomes().size();
|
||||
double moneyCount = user.getMoney().doubleValue();
|
||||
|
||||
if ((lastLog == 0) || (timeDiff < milliDays) || (homeCount > homesArg) || (moneyCount > moneyArg)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Deleting user: " + user.getName() + " Money: " + moneyCount + " Homes: " + homeCount + " Last seen: " + DateUtil.formatDateDiff(lastLog));
|
||||
}
|
||||
|
||||
user.reset();
|
||||
ess.runTaskAsynchronously(() -> {
|
||||
long currTime = System.currentTimeMillis();
|
||||
for (UUID u : userMap.getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
sender.sendMessage(tl("cleaned"));
|
||||
|
||||
long lastLog = user.getLastLogout();
|
||||
if (lastLog == 0) {
|
||||
lastLog = user.getLastLogin();
|
||||
}
|
||||
if (lastLog == 0) {
|
||||
user.setLastLogin(currTime);
|
||||
}
|
||||
|
||||
if (user.isNPC()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long timeDiff = currTime - lastLog;
|
||||
long milliDays = daysArg * 24L * 60L * 60L * 1000L;
|
||||
int homeCount = user.getHomes().size();
|
||||
double moneyCount = user.getMoney().doubleValue();
|
||||
|
||||
if ((lastLog == 0) || (timeDiff < milliDays) || (homeCount > homesArg) || (moneyCount > moneyArg)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Deleting user: " + user.getName() + " Money: " + moneyCount + " Homes: " + homeCount + " Last seen: " + DateUtil.formatDateDiff(lastLog));
|
||||
}
|
||||
|
||||
user.reset();
|
||||
}
|
||||
sender.sendMessage(tl("cleaned"));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void run_uuidconvert(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
sender.sendMessage("Starting Essentials UUID userdata conversion, this may lag the server.");
|
||||
// Forces a rerun of userdata UUID conversion.
|
||||
private void runUUIDConvert(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
sender.sendMessage("Starting Essentials UUID userdata conversion; this may lag the server.");
|
||||
|
||||
Boolean ignoreUFCache = (args.length > 2 && args[1].toLowerCase(Locale.ENGLISH).contains("ignore"));
|
||||
EssentialsUpgrade.uuidFileConvert(ess, ignoreUFCache);
|
||||
|
||||
sender.sendMessage("UUID conversion complete, check your server log for more information.");
|
||||
sender.sendMessage("UUID conversion complete. Check your server log for more information.");
|
||||
}
|
||||
|
||||
private void run_uuidtest(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
// Looks up various UUIDs for a user.
|
||||
private void runUUIDTest(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
throw new Exception("/<command> uuidtest <name>");
|
||||
}
|
||||
@@ -302,7 +300,8 @@ public class Commandessentials extends EssentialsCommand {
|
||||
sender.sendMessage("Offline Mode UUID: " + offlineuuid.toString());
|
||||
}
|
||||
|
||||
private void run_version(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
// Displays versions of EssentialsX and related plugins.
|
||||
private void runVersion(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.version")) return;
|
||||
|
||||
boolean isMismatched = false;
|
||||
@@ -369,47 +368,101 @@ public class Commandessentials extends EssentialsCommand {
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList();
|
||||
options.add("reload");
|
||||
options.add("debug");
|
||||
//options.add("nya");
|
||||
//options.add("moo");
|
||||
options.add("commands");
|
||||
options.add("version");
|
||||
options.add("reload");
|
||||
options.add("reset");
|
||||
options.add("cleanup");
|
||||
//options.add("uuidconvert");
|
||||
//options.add("uuidtest");
|
||||
options.add("version");
|
||||
//options.add("nya");
|
||||
//options.add("moo");
|
||||
return options;
|
||||
} else if (args[0].equalsIgnoreCase("debug")) {
|
||||
// No args
|
||||
} else if (args[0].equalsIgnoreCase("nya")) {
|
||||
// No args
|
||||
} else if (args[0].equalsIgnoreCase("moo")) {
|
||||
if (args.length == 2) {
|
||||
return Lists.newArrayList("moo");
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("reset")) {
|
||||
if (args.length == 2) {
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("cleanup")) {
|
||||
if (args.length == 2) {
|
||||
return COMMON_DURATIONS;
|
||||
} else if (args.length == 3 || args.length == 4) {
|
||||
return Lists.newArrayList("-1", "0");
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("uuidconvert")) {
|
||||
if (args.length == 2) {
|
||||
return Lists.newArrayList("ignoreUFCache");
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("uuidtest")) {
|
||||
if (args.length == 2) {
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("version")) {
|
||||
// No args
|
||||
} else {
|
||||
// No args
|
||||
}
|
||||
|
||||
switch (args[0]) {
|
||||
case "moo":
|
||||
if (args.length == 2) {
|
||||
return Lists.newArrayList("moo");
|
||||
}
|
||||
break;
|
||||
case "reset":
|
||||
case "uuidtest":
|
||||
if (args.length == 2) {
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
break;
|
||||
case "cleanup":
|
||||
if (args.length == 2) {
|
||||
return COMMON_DURATIONS;
|
||||
} else if (args.length == 3 || args.length == 4) {
|
||||
return Lists.newArrayList("-1", "0");
|
||||
}
|
||||
break;
|
||||
case "uuidconvert":
|
||||
if (args.length == 2) {
|
||||
return Lists.newArrayList("ignoreUFCache");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static class TuneRunnable extends BukkitRunnable {
|
||||
private static final Map<String, Float> noteMap = ImmutableMap.<String, Float>builder()
|
||||
.put("1F#", 0.5f)
|
||||
.put("1G", 0.53f)
|
||||
.put("1G#", 0.56f)
|
||||
.put("1A", 0.6f)
|
||||
.put("1A#", 0.63f)
|
||||
.put("1B", 0.67f)
|
||||
.put("1C", 0.7f)
|
||||
.put("1C#", 0.76f)
|
||||
.put("1D", 0.8f)
|
||||
.put("1D#", 0.84f)
|
||||
.put("1E", 0.9f)
|
||||
.put("1F", 0.94f)
|
||||
.put("2F#", 1.0f)
|
||||
.put("2G", 1.06f)
|
||||
.put("2G#", 1.12f)
|
||||
.put("2A", 1.18f)
|
||||
.put("2A#", 1.26f)
|
||||
.put("2B", 1.34f)
|
||||
.put("2C", 1.42f)
|
||||
.put("2C#", 1.5f)
|
||||
.put("2D", 1.6f)
|
||||
.put("2D#", 1.68f)
|
||||
.put("2E", 1.78f)
|
||||
.put("2F", 1.88f)
|
||||
.build();
|
||||
|
||||
private final String[] tune;
|
||||
private final Sound sound;
|
||||
private final Supplier<Collection<Player>> players;
|
||||
private int i = 0;
|
||||
|
||||
TuneRunnable(final String tuneStr, final Sound sound, final Supplier<Collection<Player>> players) {
|
||||
this.tune = tuneStr.split(",");
|
||||
this.sound = sound;
|
||||
this.players = players;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final String note = tune[i];
|
||||
i++;
|
||||
if (i >= tune.length) {
|
||||
cancel();
|
||||
}
|
||||
if (note == null || note.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player onlinePlayer : players.get()) {
|
||||
onlinePlayer.playSound(onlinePlayer.getLocation(), sound, 1, noteMap.get(note));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,223 +1,226 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.SetExpFix;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandexp extends EssentialsCommand {
|
||||
public Commandexp() {
|
||||
super("exp");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
showExp(user.getSource(), user);
|
||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("set") && user.isAuthorized("essentials.exp.set")) {
|
||||
if (args.length == 3 && user.isAuthorized("essentials.exp.set.others")) {
|
||||
expMatch(server, user.getSource(), args[1], args[2], false);
|
||||
} else {
|
||||
setExp(user.getSource(), user, args[1], false);
|
||||
}
|
||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("give") && user.isAuthorized("essentials.exp.give")) {
|
||||
if (args.length == 3 && user.isAuthorized("essentials.exp.give.others")) {
|
||||
expMatch(server, user.getSource(), args[1], args[2], true);
|
||||
} else {
|
||||
setExp(user.getSource(), user, args[1], true);
|
||||
}
|
||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("take") && user.isAuthorized("essentials.exp.take")) {
|
||||
if (args.length == 3 && user.isAuthorized("essentials.exp.take.others")) {
|
||||
expMatch(server, user.getSource(), args[1], "-" + args[2], true);
|
||||
} else {
|
||||
setExp(user.getSource(), user, "-" + args[1], true);
|
||||
}
|
||||
} else if (args.length < 3 && args[0].equalsIgnoreCase("reset") && user.isAuthorized("essentials.exp.reset")) {
|
||||
if (args.length == 2 && user.isAuthorized("essentials.exp.reset.others")) {
|
||||
expMatch(server, user.getSource(), args[1], "0", false);
|
||||
} else {
|
||||
setExp(user.getSource(), user, "0", false);
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("show")) {
|
||||
if (args.length >= 2 && user.isAuthorized("essentials.exp.others")) {
|
||||
String match = args[1].trim();
|
||||
showMatch(server, user.getSource(), match);
|
||||
} else {
|
||||
showExp(user.getSource(), user);
|
||||
}
|
||||
} else {
|
||||
if (args.length >= 1 && NumberUtil.isInt(args[0].toLowerCase(Locale.ENGLISH).replace("l", "")) && user.isAuthorized("essentials.exp.give")) {
|
||||
if (args.length >= 2 && user.isAuthorized("essentials.exp.give.others")) {
|
||||
expMatch(server, user.getSource(), args[1], args[0], true);
|
||||
} else {
|
||||
setExp(user.getSource(), user, args[0], true);
|
||||
}
|
||||
} else if (args.length >= 1 && user.isAuthorized("essentials.exp.others")) {
|
||||
String match = args[0].trim();
|
||||
showMatch(server, user.getSource(), match);
|
||||
} else {
|
||||
showExp(user.getSource(), user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
} else if (args.length > 2 && args[0].equalsIgnoreCase("set")) {
|
||||
expMatch(server, sender, args[1], args[2], false);
|
||||
} else if (args.length > 2 && args[0].equalsIgnoreCase("give")) {
|
||||
expMatch(server, sender, args[1], args[2], true);
|
||||
} else {
|
||||
String match = args[0].trim();
|
||||
if (args.length >= 2 && NumberUtil.isInt(args[0].toLowerCase(Locale.ENGLISH).replace("l", ""))) {
|
||||
match = args[1].trim();
|
||||
expMatch(server, sender, match, args[0], true);
|
||||
} else if (args.length == 1) {
|
||||
match = args[0].trim();
|
||||
}
|
||||
showMatch(server, sender, match);
|
||||
}
|
||||
}
|
||||
|
||||
private void showMatch(final Server server, final CommandSource sender, final String match) throws PlayerNotFoundException {
|
||||
boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
||||
boolean foundUser = false;
|
||||
final List<Player> matchedPlayers = server.matchPlayer(match);
|
||||
for (Player matchPlayer : matchedPlayers) {
|
||||
final User player = ess.getUser(matchPlayer);
|
||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(matchPlayer)) {
|
||||
continue;
|
||||
}
|
||||
foundUser = true;
|
||||
showExp(sender, player);
|
||||
}
|
||||
if (!foundUser) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
private void expMatch(final Server server, final CommandSource sender, final String match, String amount, final boolean give) throws NotEnoughArgumentsException, PlayerNotFoundException {
|
||||
boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
||||
boolean foundUser = false;
|
||||
final List<Player> matchedPlayers = server.matchPlayer(match);
|
||||
for (Player matchPlayer : matchedPlayers) {
|
||||
final User player = ess.getUser(matchPlayer);
|
||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(matchPlayer)) {
|
||||
continue;
|
||||
}
|
||||
foundUser = true;
|
||||
setExp(sender, player, amount, give);
|
||||
}
|
||||
if (!foundUser) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
private void showExp(final CommandSource sender, final User target) {
|
||||
sender.sendMessage(tl("exp", target.getDisplayName(), SetExpFix.getTotalExperience(target.getBase()), target.getBase().getLevel(), SetExpFix.getExpUntilNextLevel(target.getBase())));
|
||||
}
|
||||
|
||||
//TODO: Limit who can give negative exp?
|
||||
private void setExp(final CommandSource sender, final User target, String strAmount, final boolean give) throws NotEnoughArgumentsException {
|
||||
long amount;
|
||||
strAmount = strAmount.toLowerCase(Locale.ENGLISH);
|
||||
if (strAmount.contains("l")) {
|
||||
strAmount = strAmount.replaceAll("l", "");
|
||||
int neededLevel = Integer.parseInt(strAmount);
|
||||
if (give) {
|
||||
neededLevel += target.getBase().getLevel();
|
||||
}
|
||||
amount = (long) SetExpFix.getExpToLevel(neededLevel);
|
||||
SetExpFix.setTotalExperience(target.getBase(), 0);
|
||||
} else {
|
||||
amount = Long.parseLong(strAmount);
|
||||
if (amount > Integer.MAX_VALUE || amount < Integer.MIN_VALUE) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
}
|
||||
|
||||
if (give) {
|
||||
amount += SetExpFix.getTotalExperience(target.getBase());
|
||||
}
|
||||
if (amount > Integer.MAX_VALUE) {
|
||||
amount = (long) Integer.MAX_VALUE;
|
||||
}
|
||||
if (amount < 0l) {
|
||||
amount = 0l;
|
||||
}
|
||||
SetExpFix.setTotalExperience(target.getBase(), (int) amount);
|
||||
sender.sendMessage(tl("expSet", target.getDisplayName(), amount));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList("show");
|
||||
if (user.isAuthorized("essentials.exp.set")) {
|
||||
options.add("set");
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.give")) {
|
||||
options.add("give");
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.take")) {
|
||||
options.add("take");
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.reset")) {
|
||||
options.add("reset");
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2) {
|
||||
if ((args[0].equalsIgnoreCase("set") && user.isAuthorized("essentials.exp.set")) || (args[0].equalsIgnoreCase("give") && user.isAuthorized("essentials.exp.give"))) {
|
||||
String levellessArg = args[1].toLowerCase(Locale.ENGLISH).replace("l", "");
|
||||
if (NumberUtil.isInt(levellessArg)) {
|
||||
return Lists.newArrayList(levellessArg, args[1] + "l");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("show") && user.isAuthorized("essentials.exp.others")) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (args.length == 3 && (args[0].equalsIgnoreCase("set") && user.isAuthorized("essentials.exp.set.others")) || (args[0].equalsIgnoreCase("give") && user.isAuthorized("essentials.exp.give.others"))) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
// TODO: This seems somewhat buggy, both setting and showing - right now, ignoring that
|
||||
return Lists.newArrayList("set", "give", "show", "take", "reset");
|
||||
} else if (args.length == 2) {
|
||||
if (args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("give")) {
|
||||
String levellessArg = args[1].toLowerCase(Locale.ENGLISH).replace("l", "");
|
||||
if (NumberUtil.isInt(levellessArg)) {
|
||||
return Lists.newArrayList(levellessArg, args[1] + "l");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else { // even without 'show'
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
} else if (args.length == 3 && (args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("give"))) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.SetExpFix;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandexp extends EssentialsCommand {
|
||||
public Commandexp() {
|
||||
super("exp");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
showExp(user.getSource(), user);
|
||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("set") && user.isAuthorized("essentials.exp.set")) {
|
||||
if (args.length == 3 && user.isAuthorized("essentials.exp.set.others")) {
|
||||
expMatch(server, user.getSource(), args[1], args[2], false);
|
||||
} else {
|
||||
setExp(user.getSource(), user, args[1], false);
|
||||
}
|
||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("give") && user.isAuthorized("essentials.exp.give")) {
|
||||
if (args.length == 3 && user.isAuthorized("essentials.exp.give.others")) {
|
||||
expMatch(server, user.getSource(), args[1], args[2], true);
|
||||
} else {
|
||||
setExp(user.getSource(), user, args[1], true);
|
||||
}
|
||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("take") && user.isAuthorized("essentials.exp.take")) {
|
||||
if (args.length == 3 && user.isAuthorized("essentials.exp.take.others")) {
|
||||
expMatch(server, user.getSource(), args[1], "-" + args[2], true);
|
||||
} else {
|
||||
setExp(user.getSource(), user, "-" + args[1], true);
|
||||
}
|
||||
} else if (args.length < 3 && args[0].equalsIgnoreCase("reset") && user.isAuthorized("essentials.exp.reset")) {
|
||||
if (args.length == 2 && user.isAuthorized("essentials.exp.reset.others")) {
|
||||
expMatch(server, user.getSource(), args[1], "0", false);
|
||||
} else {
|
||||
setExp(user.getSource(), user, "0", false);
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("show")) {
|
||||
if (args.length >= 2 && user.isAuthorized("essentials.exp.others")) {
|
||||
String match = args[1].trim();
|
||||
showMatch(server, user.getSource(), match);
|
||||
} else {
|
||||
showExp(user.getSource(), user);
|
||||
}
|
||||
} else {
|
||||
if (args.length >= 1 && NumberUtil.isInt(args[0].toLowerCase(Locale.ENGLISH).replace("l", "")) && user.isAuthorized("essentials.exp.give")) {
|
||||
if (args.length >= 2 && user.isAuthorized("essentials.exp.give.others")) {
|
||||
expMatch(server, user.getSource(), args[1], args[0], true);
|
||||
} else {
|
||||
setExp(user.getSource(), user, args[0], true);
|
||||
}
|
||||
} else if (args.length >= 1 && user.isAuthorized("essentials.exp.others")) {
|
||||
String match = args[0].trim();
|
||||
showMatch(server, user.getSource(), match);
|
||||
} else {
|
||||
showExp(user.getSource(), user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
} else if (args.length > 2 && args[0].equalsIgnoreCase("set")) {
|
||||
expMatch(server, sender, args[1], args[2], false);
|
||||
} else if (args.length > 2 && args[0].equalsIgnoreCase("give")) {
|
||||
expMatch(server, sender, args[1], args[2], true);
|
||||
} else if (args.length > 2 && args[0].equalsIgnoreCase("take")) {
|
||||
expMatch(server, sender, args[1], "-" + args[2], true);
|
||||
} else if (args.length > 2 && args[0].equalsIgnoreCase("reset")) {
|
||||
expMatch(server, sender, args[1], "0", false);
|
||||
} else {
|
||||
String match = args[0].trim();
|
||||
if (args.length >= 2 && NumberUtil.isInt(args[0].toLowerCase(Locale.ENGLISH).replace("l", ""))) {
|
||||
match = args[1].trim();
|
||||
expMatch(server, sender, match, args[0], true);
|
||||
} else if (args.length == 1) {
|
||||
match = args[0].trim();
|
||||
}
|
||||
showMatch(server, sender, match);
|
||||
}
|
||||
}
|
||||
|
||||
private void showMatch(final Server server, final CommandSource sender, final String match) throws PlayerNotFoundException {
|
||||
boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
||||
boolean foundUser = false;
|
||||
final List<Player> matchedPlayers = server.matchPlayer(match);
|
||||
for (Player matchPlayer : matchedPlayers) {
|
||||
final User player = ess.getUser(matchPlayer);
|
||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(matchPlayer)) {
|
||||
continue;
|
||||
}
|
||||
foundUser = true;
|
||||
showExp(sender, player);
|
||||
}
|
||||
if (!foundUser) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
private void expMatch(final Server server, final CommandSource sender, final String match, String amount, final boolean give) throws NotEnoughArgumentsException, PlayerNotFoundException {
|
||||
boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
||||
boolean foundUser = false;
|
||||
final List<Player> matchedPlayers = server.matchPlayer(match);
|
||||
for (Player matchPlayer : matchedPlayers) {
|
||||
final User player = ess.getUser(matchPlayer);
|
||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(matchPlayer)) {
|
||||
continue;
|
||||
}
|
||||
foundUser = true;
|
||||
setExp(sender, player, amount, give);
|
||||
}
|
||||
if (!foundUser) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
private void showExp(final CommandSource sender, final User target) {
|
||||
sender.sendMessage(tl("exp", target.getDisplayName(), SetExpFix.getTotalExperience(target.getBase()), target.getBase().getLevel(), SetExpFix.getExpUntilNextLevel(target.getBase())));
|
||||
}
|
||||
|
||||
//TODO: Limit who can give negative exp?
|
||||
private void setExp(final CommandSource sender, final User target, String strAmount, final boolean give) throws NotEnoughArgumentsException {
|
||||
long amount;
|
||||
strAmount = strAmount.toLowerCase(Locale.ENGLISH);
|
||||
if (strAmount.contains("l")) {
|
||||
strAmount = strAmount.replaceAll("l", "");
|
||||
int neededLevel = Integer.parseInt(strAmount);
|
||||
if (give) {
|
||||
neededLevel += target.getBase().getLevel();
|
||||
}
|
||||
amount = SetExpFix.getExpToLevel(neededLevel);
|
||||
SetExpFix.setTotalExperience(target.getBase(), 0);
|
||||
} else {
|
||||
amount = Long.parseLong(strAmount);
|
||||
if (amount > Integer.MAX_VALUE || amount < Integer.MIN_VALUE) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
}
|
||||
|
||||
if (give) {
|
||||
amount += SetExpFix.getTotalExperience(target.getBase());
|
||||
}
|
||||
if (amount > Integer.MAX_VALUE) {
|
||||
amount = Integer.MAX_VALUE;
|
||||
}
|
||||
if (amount < 0L) {
|
||||
amount = 0L;
|
||||
}
|
||||
SetExpFix.setTotalExperience(target.getBase(), (int) amount);
|
||||
sender.sendMessage(tl("expSet", target.getDisplayName(), amount));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList("show");
|
||||
if (user.isAuthorized("essentials.exp.set")) {
|
||||
options.add("set");
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.give")) {
|
||||
options.add("give");
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.take")) {
|
||||
options.add("take");
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.reset")) {
|
||||
options.add("reset");
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2) {
|
||||
if ((args[0].equalsIgnoreCase("set") && user.isAuthorized("essentials.exp.set")) || (args[0].equalsIgnoreCase("give") && user.isAuthorized("essentials.exp.give")) || (args[0].equalsIgnoreCase("take") && user.isAuthorized("essentials.exp.take"))) {
|
||||
String levellessArg = args[1].toLowerCase(Locale.ENGLISH).replaceAll("l", "");
|
||||
if (NumberUtil.isInt(levellessArg)) {
|
||||
return Lists.newArrayList(levellessArg + "l");
|
||||
}
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.others")) {
|
||||
return getPlayers(server, user);
|
||||
}
|
||||
} else if (args.length == 3 && !(args[0].equalsIgnoreCase("show") || args[0].equalsIgnoreCase("reset"))) {
|
||||
String levellessArg = args[2].toLowerCase(Locale.ENGLISH).replaceAll("l", "");
|
||||
if (NumberUtil.isInt(levellessArg)) {
|
||||
return Lists.newArrayList(levellessArg + "l");
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
// TODO: This seems somewhat buggy, both setting and showing - right now, ignoring that
|
||||
return Lists.newArrayList("set", "give", "show", "take", "reset");
|
||||
} else if (args.length == 2) {
|
||||
if (args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("give")) {
|
||||
String levellessArg = args[1].toLowerCase(Locale.ENGLISH).replace("l", "");
|
||||
if (NumberUtil.isInt(levellessArg)) {
|
||||
return Lists.newArrayList(levellessArg, args[1] + "l");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else { // even without 'show'
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
} else if (args.length == 3 && (args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("give"))) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,13 +27,13 @@ public class Commandext extends EssentialsLoopCommand {
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
extPlayer(user.getBase());
|
||||
user.sendMessage(tl("extinguish"));
|
||||
if (args.length > 0 && user.isAuthorized("essentials.ext.others")) {
|
||||
loopOnlinePlayers(server, user.getSource(), true, true, args[0], null);
|
||||
return;
|
||||
}
|
||||
|
||||
loopOnlinePlayers(server, user.getSource(), true, true, args[0], null);
|
||||
extPlayer(user.getBase());
|
||||
user.sendMessage(tl("extinguish"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,7 +60,7 @@ public class Commandfeed extends EssentialsLoopCommand {
|
||||
throw new QuietAbortException();
|
||||
}
|
||||
|
||||
player.setFoodLevel(flce.getFoodLevel() > 20 ? 20 : flce.getFoodLevel());
|
||||
player.setFoodLevel(Math.min(flce.getFoodLevel(), 20));
|
||||
player.setSaturation(10);
|
||||
player.setExhaustion(0F);
|
||||
}
|
||||
|
||||
@@ -1,55 +1,101 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FloatUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandfireball extends EssentialsCommand {
|
||||
|
||||
public static final String FIREBALL_META_KEY = "ess_fireball_proj";
|
||||
|
||||
private static final Map<String, Class<? extends Projectile>> types;
|
||||
|
||||
static {
|
||||
ImmutableMap.Builder<String, Class<? extends Projectile>> builder = ImmutableMap.<String, Class<? extends Projectile>>builder()
|
||||
.put("fireball", Fireball.class)
|
||||
.put("small", SmallFireball.class)
|
||||
.put("large", LargeFireball.class)
|
||||
.put("arrow", Arrow.class)
|
||||
.put("skull", WitherSkull.class)
|
||||
.put("egg", Egg.class)
|
||||
.put("snowball", Snowball.class)
|
||||
.put("expbottle", ThrownExpBottle.class);
|
||||
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_R01)) {
|
||||
builder.put("dragon", DragonFireball.class)
|
||||
.put("splashpotion", SplashPotion.class)
|
||||
.put("lingeringpotion", LingeringPotion.class);
|
||||
}
|
||||
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) {
|
||||
builder.put("trident", Trident.class);
|
||||
}
|
||||
|
||||
types = builder.build();
|
||||
}
|
||||
|
||||
public Commandfireball() {
|
||||
super("fireball");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
Class<? extends Entity> type = Fireball.class;
|
||||
Projectile projectile;
|
||||
int speed = 2;
|
||||
if (args.length > 0) {
|
||||
if (args[0].equalsIgnoreCase("small")) {
|
||||
type = SmallFireball.class;
|
||||
} else if (args[0].equalsIgnoreCase("arrow")) {
|
||||
type = Arrow.class;
|
||||
} else if (args[0].equalsIgnoreCase("skull")) {
|
||||
type = WitherSkull.class;
|
||||
} else if (args[0].equalsIgnoreCase("egg")) {
|
||||
type = Egg.class;
|
||||
} else if (args[0].equalsIgnoreCase("snowball")) {
|
||||
type = Snowball.class;
|
||||
} else if (args[0].equalsIgnoreCase("expbottle")) {
|
||||
type = ThrownExpBottle.class;
|
||||
} else if (args[0].equalsIgnoreCase("large")) {
|
||||
type = LargeFireball.class;
|
||||
} else if (args[0].equalsIgnoreCase("splashpotion")) {
|
||||
type = SplashPotion.class;
|
||||
} else if (args[0].equalsIgnoreCase("lingeringpotion")) {
|
||||
type = LingeringPotion.class;
|
||||
String type = "fireball";
|
||||
double speed = 2;
|
||||
boolean ride = false;
|
||||
|
||||
if (args.length > 0 && types.containsKey(args[0])) {
|
||||
type = args[0];
|
||||
}
|
||||
|
||||
if (args.length > 1) {
|
||||
try {
|
||||
speed = FloatUtil.parseDouble(args[1]);
|
||||
speed = Double.max(0, Double.min(speed, ess.getSettings().getMaxProjectileSpeed()));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length > 2 && args[2].equalsIgnoreCase("ride") && user.isAuthorized("essentials.fireball.ride")) {
|
||||
ride = true;
|
||||
}
|
||||
|
||||
if (!user.isAuthorized("essentials.fireball." + type)) {
|
||||
throw new Exception(tl("noPerm", "essentials.fireball." + type));
|
||||
}
|
||||
|
||||
final Vector direction = user.getBase().getEyeLocation().getDirection().multiply(speed);
|
||||
projectile = (Projectile) user.getWorld().spawn(user.getBase().getEyeLocation().add(direction.getX(), direction.getY(), direction.getZ()), type);
|
||||
Projectile projectile = user.getWorld().spawn(user.getBase().getEyeLocation().add(direction.getX(), direction.getY(), direction.getZ()), types.get(type));
|
||||
projectile.setShooter(user.getBase());
|
||||
projectile.setVelocity(direction);
|
||||
projectile.setMetadata(FIREBALL_META_KEY, new FixedMetadataValue(ess, true));
|
||||
|
||||
if (ride) {
|
||||
projectile.addPassenger(user.getBase());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("small", "arrow", "skull", "egg", "snowball", "expbottle", "large", "splashpotion", "lingeringpotion");
|
||||
return types.keySet().stream()
|
||||
.filter(type -> user.isAuthorized("essentials.fireball." + type))
|
||||
.collect(Collectors.toList());
|
||||
} else if (args.length == 2) {
|
||||
return Lists.newArrayList("1", "2", "3", "4", "5");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -1,178 +1,177 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
//This command has quite a complicated syntax, in theory it has 4 seperate syntaxes which are all variable:
|
||||
//
|
||||
//1: /firework clear - This clears all of the effects on a firework stack
|
||||
//
|
||||
//2: /firework power <int> - This changes the base power of a firework
|
||||
//
|
||||
//3: /firework fire - This 'fires' a copy of the firework held.
|
||||
//3: /firework fire <int> - This 'fires' a number of copies of the firework held.
|
||||
//3: /firework fire <other> - This 'fires' a copy of the firework held, in the direction you are looking, #easteregg
|
||||
//
|
||||
//4: /firework [meta] - This will add an effect to the firework stack held
|
||||
//4: /firework color:<color> - The minimum you need to set an effect is 'color'
|
||||
//4: Full Syntax: color:<color[,color,..]> [fade:<color[,color,..]>] [shape:<shape>] [effect:<effect[,effect]>]
|
||||
//4: Possible Shapes: star, ball, large, creeper, burst
|
||||
//4: Possible Effects trail, twinkle
|
||||
|
||||
public class Commandfirework extends EssentialsCommand {
|
||||
|
||||
public Commandfirework() {
|
||||
super("firework");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final ItemStack stack = user.getItemInHand();
|
||||
if (MaterialUtil.isFirework(stack.getType())) {
|
||||
if (args.length > 0) {
|
||||
if (args[0].equalsIgnoreCase("clear")) {
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
fmeta.clearEffects();
|
||||
stack.setItemMeta(fmeta);
|
||||
user.sendMessage(tl("fireworkEffectsCleared"));
|
||||
} else if (args.length > 1 && (args[0].equalsIgnoreCase("power") || (args[0].equalsIgnoreCase("p")))) {
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
try {
|
||||
int power = Integer.parseInt(args[1]);
|
||||
fmeta.setPower(power > 3 ? 4 : power);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new Exception(tl("invalidFireworkFormat", args[1], args[0]));
|
||||
}
|
||||
stack.setItemMeta(fmeta);
|
||||
} else if ((args[0].equalsIgnoreCase("fire") || (args[0].equalsIgnoreCase("f"))) && user.isAuthorized("essentials.firework.fire")) {
|
||||
int amount = 1;
|
||||
boolean direction = false;
|
||||
if (args.length > 1) {
|
||||
if (NumberUtil.isInt(args[1])) {
|
||||
final int serverLimit = ess.getSettings().getSpawnMobLimit();
|
||||
amount = Integer.parseInt(args[1]);
|
||||
if (amount > serverLimit) {
|
||||
amount = serverLimit;
|
||||
user.sendMessage(tl("mobSpawnLimit"));
|
||||
}
|
||||
} else {
|
||||
direction = true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Firework firework = (Firework) user.getWorld().spawnEntity(user.getLocation(), EntityType.FIREWORK);
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
if (direction) {
|
||||
final Vector vector = user.getBase().getEyeLocation().getDirection().multiply(0.070);
|
||||
if (fmeta.getPower() > 1) {
|
||||
fmeta.setPower(1);
|
||||
}
|
||||
firework.setVelocity(vector);
|
||||
}
|
||||
firework.setFireworkMeta(fmeta);
|
||||
}
|
||||
} else {
|
||||
final MetaItemStack mStack = new MetaItemStack(stack);
|
||||
for (String arg : args) {
|
||||
try {
|
||||
mStack.addFireworkMeta(user.getSource(), true, arg, ess);
|
||||
} catch (Exception e) {
|
||||
user.sendMessage(tl("fireworkSyntax"));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (mStack.isValidFirework()) {
|
||||
FireworkMeta fmeta = (FireworkMeta) mStack.getItemStack().getItemMeta();
|
||||
FireworkEffect effect = mStack.getFireworkBuilder().build();
|
||||
if (fmeta.getEffects().size() > 0 && !user.isAuthorized("essentials.firework.multiple")) {
|
||||
throw new Exception(tl("multipleCharges"));
|
||||
}
|
||||
fmeta.addEffect(effect);
|
||||
stack.setItemMeta(fmeta);
|
||||
} else {
|
||||
user.sendMessage(tl("fireworkSyntax"));
|
||||
throw new Exception(tl("fireworkColor"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
} else {
|
||||
throw new Exception(tl("holdFirework"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
// Note: this enforces an order of color fade shape effect, which the actual command doesn't have. But that's fine.
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList();
|
||||
if (args[0].startsWith("color:")) {
|
||||
String prefix;
|
||||
if (args[0].contains(",")) {
|
||||
prefix = args[0].substring(0, args[0].lastIndexOf(',') + 1);
|
||||
} else {
|
||||
prefix = "color:";
|
||||
}
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
options.add(prefix + color.name().toLowerCase() + ",");
|
||||
}
|
||||
return options;
|
||||
}
|
||||
options.add("clear");
|
||||
options.add("power");
|
||||
options.add("color:");
|
||||
if (user.isAuthorized("essentials.firework.fire")) {
|
||||
options.add("fire");
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2) {
|
||||
if (args[0].equals("power")) {
|
||||
return Lists.newArrayList("1", "2", "3", "4");
|
||||
} else if (args[0].equals("fire")) {
|
||||
return Lists.newArrayList("1");
|
||||
} else if (args[0].startsWith("color:")) {
|
||||
List<String> options = Lists.newArrayList();
|
||||
if (!args[1].startsWith("fade:")) {
|
||||
args[1] = "fade:";
|
||||
}
|
||||
String prefix;
|
||||
if (args[1].contains(",")) {
|
||||
prefix = args[1].substring(0, args[1].lastIndexOf(',') + 1);
|
||||
} else {
|
||||
prefix = "fade:";
|
||||
}
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
options.add(prefix + color.name().toLowerCase() + ",");
|
||||
}
|
||||
return options;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (args.length == 3 && args[0].startsWith("color:")) {
|
||||
return Lists.newArrayList("shape:star", "shape:ball", "shape:large", "shape:creeper", "shape:burst");
|
||||
} else if (args.length == 4 && args[0].startsWith("color:")) {
|
||||
return Lists.newArrayList("effect:trail", "effect:twinkle", "effect:trail,twinkle", "effect:twinkle,trail");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
//This command has quite a complicated syntax, in theory it has 4 seperate syntaxes which are all variable:
|
||||
//
|
||||
//1: /firework clear - This clears all of the effects on a firework stack
|
||||
//
|
||||
//2: /firework power <int> - This changes the base power of a firework
|
||||
//
|
||||
//3: /firework fire - This 'fires' a copy of the firework held.
|
||||
//3: /firework fire <int> - This 'fires' a number of copies of the firework held.
|
||||
//3: /firework fire <other> - This 'fires' a copy of the firework held, in the direction you are looking, #easteregg
|
||||
//
|
||||
//4: /firework [meta] - This will add an effect to the firework stack held
|
||||
//4: /firework color:<color> - The minimum you need to set an effect is 'color'
|
||||
//4: Full Syntax: color:<color[,color,..]> [fade:<color[,color,..]>] [shape:<shape>] [effect:<effect[,effect]>]
|
||||
//4: Possible Shapes: star, ball, large, creeper, burst
|
||||
//4: Possible Effects trail, twinkle
|
||||
|
||||
public class Commandfirework extends EssentialsCommand {
|
||||
|
||||
public Commandfirework() {
|
||||
super("firework");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final ItemStack stack = user.getItemInHand();
|
||||
if (MaterialUtil.isFirework(stack.getType())) {
|
||||
if (args.length > 0) {
|
||||
if (args[0].equalsIgnoreCase("clear")) {
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
fmeta.clearEffects();
|
||||
stack.setItemMeta(fmeta);
|
||||
user.sendMessage(tl("fireworkEffectsCleared"));
|
||||
} else if (args.length > 1 && (args[0].equalsIgnoreCase("power") || (args[0].equalsIgnoreCase("p")))) {
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
try {
|
||||
int power = Integer.parseInt(args[1]);
|
||||
fmeta.setPower(power > 3 ? 4 : power);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new Exception(tl("invalidFireworkFormat", args[1], args[0]));
|
||||
}
|
||||
stack.setItemMeta(fmeta);
|
||||
} else if ((args[0].equalsIgnoreCase("fire") || (args[0].equalsIgnoreCase("f"))) && user.isAuthorized("essentials.firework.fire")) {
|
||||
int amount = 1;
|
||||
boolean direction = false;
|
||||
if (args.length > 1) {
|
||||
if (NumberUtil.isInt(args[1])) {
|
||||
final int serverLimit = ess.getSettings().getSpawnMobLimit();
|
||||
amount = Integer.parseInt(args[1]);
|
||||
if (amount > serverLimit) {
|
||||
amount = serverLimit;
|
||||
user.sendMessage(tl("mobSpawnLimit"));
|
||||
}
|
||||
} else {
|
||||
direction = true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Firework firework = (Firework) user.getWorld().spawnEntity(user.getLocation(), EntityType.FIREWORK);
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
if (direction) {
|
||||
final Vector vector = user.getBase().getEyeLocation().getDirection().multiply(0.070);
|
||||
if (fmeta.getPower() > 1) {
|
||||
fmeta.setPower(1);
|
||||
}
|
||||
firework.setVelocity(vector);
|
||||
}
|
||||
firework.setFireworkMeta(fmeta);
|
||||
}
|
||||
} else {
|
||||
final MetaItemStack mStack = new MetaItemStack(stack);
|
||||
for (String arg : args) {
|
||||
try {
|
||||
mStack.addFireworkMeta(user.getSource(), true, arg, ess);
|
||||
} catch (Exception e) {
|
||||
user.sendMessage(tl("fireworkSyntax"));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (mStack.isValidFirework()) {
|
||||
FireworkMeta fmeta = (FireworkMeta) mStack.getItemStack().getItemMeta();
|
||||
FireworkEffect effect = mStack.getFireworkBuilder().build();
|
||||
if (fmeta.getEffects().size() > 0 && !user.isAuthorized("essentials.firework.multiple")) {
|
||||
throw new Exception(tl("multipleCharges"));
|
||||
}
|
||||
fmeta.addEffect(effect);
|
||||
stack.setItemMeta(fmeta);
|
||||
} else {
|
||||
user.sendMessage(tl("fireworkSyntax"));
|
||||
throw new Exception(tl("fireworkColor"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
} else {
|
||||
throw new Exception(tl("holdFirework"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
// Note: this enforces an order of color fade shape effect, which the actual command doesn't have. But that's fine.
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList();
|
||||
if (args[0].startsWith("color:")) {
|
||||
String prefix;
|
||||
if (args[0].contains(",")) {
|
||||
prefix = args[0].substring(0, args[0].lastIndexOf(',') + 1);
|
||||
} else {
|
||||
prefix = "color:";
|
||||
}
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
options.add(prefix + color.name().toLowerCase() + ",");
|
||||
}
|
||||
return options;
|
||||
}
|
||||
options.add("clear");
|
||||
options.add("power");
|
||||
options.add("color:");
|
||||
if (user.isAuthorized("essentials.firework.fire")) {
|
||||
options.add("fire");
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2) {
|
||||
if (args[0].equals("power")) {
|
||||
return Lists.newArrayList("1", "2", "3", "4");
|
||||
} else if (args[0].equals("fire")) {
|
||||
return Lists.newArrayList("1");
|
||||
} else if (args[0].startsWith("color:")) {
|
||||
List<String> options = Lists.newArrayList();
|
||||
if (!args[1].startsWith("fade:")) {
|
||||
args[1] = "fade:";
|
||||
}
|
||||
String prefix;
|
||||
if (args[1].contains(",")) {
|
||||
prefix = args[1].substring(0, args[1].lastIndexOf(',') + 1);
|
||||
} else {
|
||||
prefix = "fade:";
|
||||
}
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
options.add(prefix + color.name().toLowerCase() + ",");
|
||||
}
|
||||
return options;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (args.length == 3 && args[0].startsWith("color:")) {
|
||||
return Lists.newArrayList("shape:star", "shape:ball", "shape:large", "shape:creeper", "shape:burst");
|
||||
} else if (args.length == 4 && args[0].startsWith("color:")) {
|
||||
return Lists.newArrayList("effect:trail", "effect:twinkle", "effect:trail,twinkle", "effect:twinkle,trail");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public class Commandgamemode extends EssentialsCommand {
|
||||
return mode;
|
||||
}
|
||||
|
||||
private List<String> STANDARD_OPTIONS = ImmutableList.of("creative", "survival", "adventure", "spectator", "toggle");
|
||||
private final List<String> STANDARD_OPTIONS = ImmutableList.of("creative", "survival", "adventure", "spectator", "toggle");
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
|
||||
@@ -2,11 +2,17 @@ package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -19,6 +25,31 @@ public class Commandhat extends EssentialsCommand {
|
||||
super("hat");
|
||||
}
|
||||
|
||||
/**
|
||||
* The prefix for hat prevention commands
|
||||
*/
|
||||
private static final String PERM_PREFIX = "essentials.hat.prevent-type.";
|
||||
|
||||
/**
|
||||
* Register permissions used by this command.
|
||||
*
|
||||
* @param toRegister The plugin manager to register permissions in.
|
||||
*/
|
||||
public static void registerPermissionsIfNecessary(PluginManager toRegister) {
|
||||
Permission hatPerm = toRegister.getPermission(PERM_PREFIX + "*");
|
||||
if (hatPerm != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImmutableMap.Builder<String, Boolean> children = ImmutableMap.builder();
|
||||
for (Material mat : Material.values()) {
|
||||
final String matPerm = PERM_PREFIX + mat.name().toLowerCase();
|
||||
children.put(matPerm, true);
|
||||
toRegister.addPermission(new Permission(matPerm, "Prevent using " + mat + " as a type of hat.", PermissionDefault.FALSE));
|
||||
}
|
||||
toRegister.addPermission(new Permission(PERM_PREFIX + "*", "Prevent all types of hats", PermissionDefault.FALSE, children.build()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length > 0 && (args[0].contains("rem") || args[0].contains("off") || args[0].equalsIgnoreCase("0"))) {
|
||||
@@ -26,6 +57,8 @@ public class Commandhat extends EssentialsCommand {
|
||||
final ItemStack head = inv.getHelmet();
|
||||
if (head == null || head.getType() == Material.AIR) {
|
||||
user.sendMessage(tl("hatEmpty"));
|
||||
} else if (VersionUtil.getServerBukkitVersion().isHigherThan(VersionUtil.v1_9_4_R01) && head.getEnchantments().containsKey(Enchantment.BINDING_CURSE) && !user.isAuthorized("essentials.hat.ignore-binding")) {
|
||||
user.sendMessage(tl("hatCurse"));
|
||||
} else {
|
||||
final ItemStack air = new ItemStack(Material.AIR);
|
||||
inv.setHelmet(air);
|
||||
@@ -35,9 +68,17 @@ public class Commandhat extends EssentialsCommand {
|
||||
} else {
|
||||
final ItemStack hand = user.getItemInHand();
|
||||
if (hand != null && hand.getType() != Material.AIR) {
|
||||
if (user.isAuthorized("essentials.hat.prevent-type." + hand.getType().name().toLowerCase())) {
|
||||
user.sendMessage(tl("hatFail"));
|
||||
return;
|
||||
}
|
||||
if (hand.getType().getMaxDurability() == 0) {
|
||||
final PlayerInventory inv = user.getBase().getInventory();
|
||||
final ItemStack head = inv.getHelmet();
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThan(VersionUtil.v1_9_4_R01) && head != null && head.getEnchantments().containsKey(Enchantment.BINDING_CURSE) && !user.isAuthorized("essentials.hat.ignore-binding")) {
|
||||
user.sendMessage(tl("hatCurse"));
|
||||
return;
|
||||
}
|
||||
inv.setHelmet(hand);
|
||||
inv.setItemInHand(head);
|
||||
user.sendMessage(tl("hatPlaced"));
|
||||
|
||||
@@ -75,8 +75,10 @@ public class Commandheal extends EssentialsLoopCommand {
|
||||
player.setFoodLevel(20);
|
||||
player.setFireTicks(0);
|
||||
user.sendMessage(tl("heal"));
|
||||
for (PotionEffect effect : player.getActivePotionEffects()) {
|
||||
player.removePotionEffect(effect.getType());
|
||||
if (ess.getSettings().isRemovingEffectsOnHeal()) {
|
||||
for (PotionEffect effect : player.getActivePotionEffects()) {
|
||||
player.removePotionEffect(effect.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.OfflinePlayer;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.ess3.api.events.UserTeleportHomeEvent;
|
||||
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.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
@@ -40,37 +43,71 @@ public class Commandhome extends EssentialsCommand {
|
||||
}
|
||||
try {
|
||||
if ("bed".equalsIgnoreCase(homeName) && user.isAuthorized("essentials.home.bed")) {
|
||||
final Location bed = player.getBase().getBedSpawnLocation();
|
||||
if (bed != null) {
|
||||
user.getTeleport().teleport(bed, charge, TeleportCause.COMMAND);
|
||||
throw new NoChargeException();
|
||||
} else {
|
||||
throw new Exception(tl("bedMissing"));
|
||||
if (!player.getBase().isOnline() || player.getBase() instanceof OfflinePlayer) {
|
||||
throw new Exception(tl("bedOffline"));
|
||||
}
|
||||
}
|
||||
goHome(user, player, homeName.toLowerCase(Locale.ENGLISH), charge);
|
||||
} catch (NotEnoughArgumentsException e) {
|
||||
Location bed = player.getBase().getBedSpawnLocation();
|
||||
final List<String> homes = player.getHomes();
|
||||
if (homes.isEmpty() && player.equals(user)) {
|
||||
user.getTeleport().respawn(charge, TeleportCause.COMMAND);
|
||||
} else if (homes.isEmpty()) {
|
||||
throw new Exception(tl("noHomeSetPlayer"));
|
||||
} else if (homes.size() == 1 && player.equals(user)) {
|
||||
goHome(user, player, homes.get(0), charge);
|
||||
} else {
|
||||
final int count = homes.size();
|
||||
if (user.isAuthorized("essentials.home.bed")) {
|
||||
if (bed != null) {
|
||||
homes.add(tl("bed"));
|
||||
PaperLib.getBedSpawnLocationAsync(player.getBase(), true).thenAccept(location -> {
|
||||
CompletableFuture<Boolean> future = getNewExceptionFuture(user.getSource(), commandLabel);
|
||||
if (location != null) {
|
||||
UserTeleportHomeEvent event = new UserTeleportHomeEvent(user, "bed", location, UserTeleportHomeEvent.HomeType.BED);
|
||||
server.getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
user.sendMessage(tl("teleportHome", "bed"));
|
||||
}
|
||||
});
|
||||
user.getAsyncTeleport().teleport(location, charge, TeleportCause.COMMAND, future);
|
||||
} else {
|
||||
homes.add(tl("bedNull"));
|
||||
showError(user.getBase(), new Exception(tl("bedMissing")), commandLabel);
|
||||
}
|
||||
}
|
||||
user.sendMessage(tl("homes", StringUtil.joinList(homes), count, getHomeLimit(player)));
|
||||
});
|
||||
return;
|
||||
}
|
||||
goHome(user, player, homeName.toLowerCase(Locale.ENGLISH), charge, getNewExceptionFuture(user.getSource(), commandLabel));
|
||||
} catch (NotEnoughArgumentsException e) {
|
||||
final User finalPlayer = player;
|
||||
CompletableFuture<Location> message = new CompletableFuture<>();
|
||||
message.thenAccept(bed -> {
|
||||
final List<String> homes = finalPlayer.getHomes();
|
||||
if (homes.isEmpty() && finalPlayer.equals(user)) {
|
||||
if (ess.getSettings().isSpawnIfNoHome()) {
|
||||
UserTeleportHomeEvent event = new UserTeleportHomeEvent(user, null, bed != null ? bed : finalPlayer.getWorld().getSpawnLocation(), bed != null ? UserTeleportHomeEvent.HomeType.BED : UserTeleportHomeEvent.HomeType.SPAWN);
|
||||
server.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
user.getAsyncTeleport().respawn(charge, TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel));
|
||||
}
|
||||
} else {
|
||||
showError(user.getBase(), new Exception(tl("noHomeSetPlayer")), commandLabel);
|
||||
}
|
||||
} else if (homes.isEmpty()) {
|
||||
showError(user.getBase(), new Exception(tl("noHomeSetPlayer")), commandLabel);
|
||||
} else if (homes.size() == 1 && finalPlayer.equals(user)) {
|
||||
try {
|
||||
goHome(user, finalPlayer, homes.get(0), charge, getNewExceptionFuture(user.getSource(), commandLabel));
|
||||
} catch (Exception exception) {
|
||||
showError(user.getBase(), exception, commandLabel);
|
||||
}
|
||||
} else {
|
||||
final int count = homes.size();
|
||||
if (user.isAuthorized("essentials.home.bed")) {
|
||||
if (bed != null) {
|
||||
homes.add(tl("bed"));
|
||||
} else {
|
||||
homes.add(tl("bedNull"));
|
||||
}
|
||||
}
|
||||
user.sendMessage(tl("homes", StringUtil.joinList(homes), count, getHomeLimit(finalPlayer)));
|
||||
}
|
||||
});
|
||||
if (!player.getBase().isOnline() || player.getBase() instanceof OfflinePlayer) {
|
||||
message.complete(null);
|
||||
return;
|
||||
}
|
||||
PaperLib.getBedSpawnLocationAsync(player.getBase(), true).thenAccept(message::complete);
|
||||
}
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
private String getHomeLimit(final User player) {
|
||||
@@ -83,7 +120,7 @@ public class Commandhome extends EssentialsCommand {
|
||||
return Integer.toString(ess.getSettings().getHomeLimit(player));
|
||||
}
|
||||
|
||||
private void goHome(final User user, final User player, final String home, final Trade charge) throws Exception {
|
||||
private void goHome(final User user, final User player, final String home, final Trade charge, CompletableFuture<Boolean> future) throws Exception {
|
||||
if (home.length() < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
@@ -94,36 +131,46 @@ public class Commandhome extends EssentialsCommand {
|
||||
if (user.getWorld() != loc.getWorld() && ess.getSettings().isWorldHomePermissions() && !user.isAuthorized("essentials.worlds." + loc.getWorld().getName())) {
|
||||
throw new Exception(tl("noPerm", "essentials.worlds." + loc.getWorld().getName()));
|
||||
}
|
||||
user.getTeleport().teleport(loc, charge, TeleportCause.COMMAND);
|
||||
user.sendMessage(tl("teleportHome", home));
|
||||
UserTeleportHomeEvent event = new UserTeleportHomeEvent(user, home, loc, UserTeleportHomeEvent.HomeType.HOME);
|
||||
user.getServer().getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
user.getAsyncTeleport().teleport(loc, charge, TeleportCause.COMMAND, future);
|
||||
future.thenAccept(success -> {
|
||||
if (success) {
|
||||
user.sendMessage(tl("teleportHome", home));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
boolean canVisitOthers = user.isAuthorized("essentials.home.others");
|
||||
|
||||
boolean canVisitBed = user.isAuthorized("essentials.home.bed");
|
||||
if (args.length == 1) {
|
||||
List<String> homes = user.getHomes();
|
||||
if (canVisitBed) {
|
||||
homes.add("bed");
|
||||
}
|
||||
if (canVisitOthers) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
List<String> homes = user.getHomes();
|
||||
if (user.isAuthorized("essentials.home.bed")) {
|
||||
homes.add("bed");
|
||||
int sepIndex = args[0].indexOf(':');
|
||||
if (sepIndex < 0) {
|
||||
getPlayers(server, user).forEach(player -> homes.add(player + ":"));
|
||||
} else {
|
||||
String namePart = args[0].substring(0, sepIndex);
|
||||
User otherUser;
|
||||
try {
|
||||
otherUser = getPlayer(server, new String[]{namePart}, 0, true, true);
|
||||
} catch (Exception ex) {
|
||||
return homes;
|
||||
}
|
||||
otherUser.getHomes().forEach(home -> homes.add(namePart + ":" + home));
|
||||
if (canVisitBed) {
|
||||
homes.add(namePart + ":bed");
|
||||
}
|
||||
}
|
||||
return homes;
|
||||
}
|
||||
} else if (args.length == 2 && canVisitOthers) {
|
||||
try {
|
||||
User otherUser = getPlayer(server, args, 0, true, true);
|
||||
List<String> homes = otherUser.getHomes();
|
||||
if (user.isAuthorized("essentials.home.bed")) {
|
||||
homes.add("bed");
|
||||
}
|
||||
return homes;
|
||||
} catch (Exception ex) {
|
||||
// No such user
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return homes;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.bukkit.Server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
@@ -18,8 +19,11 @@ public class Commandignore extends EssentialsCommand {
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String s : user._getIgnoredPlayers()) {
|
||||
sb.append(s).append(" ");
|
||||
for (UUID uuid : user._getIgnoredPlayers()) {
|
||||
User curUser = ess.getUser(uuid);
|
||||
if (curUser != null && curUser.getName() != null && !curUser.getName().trim().isEmpty()) {
|
||||
sb.append(curUser.getName()).append(" ");
|
||||
}
|
||||
}
|
||||
String ignoredList = sb.toString().trim();
|
||||
user.sendMessage(ignoredList.length() > 0 ? tl("ignoredList", ignoredList) : tl("noIgnored"));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
@@ -25,6 +26,9 @@ public class Commandinvsee extends EssentialsCommand {
|
||||
if (args.length > 1 && user.isAuthorized("essentials.invsee.equip")) {
|
||||
inv = server.createInventory(invUser.getBase(), 9, "Equipped");
|
||||
inv.setContents(invUser.getBase().getInventory().getArmorContents());
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_9_4_R01)) {
|
||||
inv.setItem(4, invUser.getBase().getInventory().getItemInOffHand());
|
||||
}
|
||||
} else {
|
||||
inv = invUser.getBase().getInventory();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commanditemlore extends EssentialsCommand {
|
||||
|
||||
public Commanditemlore() {
|
||||
super("itemlore");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
ItemStack item = user.getBase().getItemInHand();
|
||||
if (item.getType().name().contains("AIR")) {
|
||||
throw new Exception(tl("itemloreInvalidItem"));
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
ItemMeta im = item.getItemMeta();
|
||||
if (args[0].equalsIgnoreCase("add") && args.length > 1) {
|
||||
String line = FormatUtil.formatString(user, "essentials.itemlore", getFinalArg(args, 1)).trim();
|
||||
List<String> lore = im.hasLore() ? im.getLore() : new ArrayList<>();
|
||||
lore.add(line);
|
||||
im.setLore(lore);
|
||||
item.setItemMeta(im);
|
||||
user.sendMessage(tl("itemloreSuccess", line));
|
||||
} else if (args[0].equalsIgnoreCase("clear")) {
|
||||
im.setLore(new ArrayList<>());
|
||||
item.setItemMeta(im);
|
||||
user.sendMessage(tl("itemloreClear"));
|
||||
} else if (args[0].equalsIgnoreCase("set") && args.length > 2 && NumberUtil.isInt(args[1])) {
|
||||
if (!im.hasLore()) {
|
||||
throw new Exception(tl("itemloreNoLore"));
|
||||
}
|
||||
|
||||
int line = Integer.parseInt(args[1]);
|
||||
String newLine = FormatUtil.formatString(user, "essentials.itemlore", getFinalArg(args, 2)).trim();
|
||||
List<String> lore = im.getLore();
|
||||
try {
|
||||
lore.set(line - 1, newLine);
|
||||
} catch (Exception e) {
|
||||
throw new Exception(tl("itemloreNoLine", line), e);
|
||||
}
|
||||
im.setLore(lore);
|
||||
item.setItemMeta(im);
|
||||
user.sendMessage(tl("itemloreSuccessLore", line, newLine));
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("add", "set", "clear");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,15 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.I18n;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commanditemname extends EssentialsCommand {
|
||||
|
||||
public Commanditemname() {
|
||||
|
||||
@@ -4,8 +4,6 @@ import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
|
||||
@@ -46,8 +46,7 @@ public class Commandjump extends EssentialsCommand {
|
||||
|
||||
final Trade charge = new Trade(this.getName(), ess);
|
||||
charge.isAffordableFor(user);
|
||||
user.getTeleport().teleport(loc, charge, TeleportCause.COMMAND);
|
||||
throw new NoChargeException();
|
||||
user.getAsyncTeleport().teleport(loc, charge, TeleportCause.COMMAND, getNewExceptionFuture(user.getSource(), commandLabel));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,18 +32,13 @@ public class Commandkill extends EssentialsLoopCommand {
|
||||
if (sender.isPlayer() && user.isAuthorized("essentials.kill.exempt") && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.kill.force")) {
|
||||
throw new PlayerExemptException(tl("killExempt", matchPlayer.getDisplayName()));
|
||||
}
|
||||
final EntityDamageEvent ede = new EntityDamageEvent(matchPlayer, sender.isPlayer() && sender.getPlayer().getName().equals(matchPlayer.getName()) ? EntityDamageEvent.DamageCause.SUICIDE : EntityDamageEvent.DamageCause.CUSTOM, Short.MAX_VALUE);
|
||||
final EntityDamageEvent ede = new EntityDamageEvent(matchPlayer, sender.isPlayer() && sender.getPlayer().getName().equals(matchPlayer.getName()) ? EntityDamageEvent.DamageCause.SUICIDE : EntityDamageEvent.DamageCause.CUSTOM, Float.MAX_VALUE);
|
||||
server.getPluginManager().callEvent(ede);
|
||||
if (ede.isCancelled() && sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.kill.force")) {
|
||||
return;
|
||||
}
|
||||
ede.getEntity().setLastDamageCause(ede);
|
||||
matchPlayer.damage(Short.MAX_VALUE);
|
||||
|
||||
if (matchPlayer.getHealth() > 0) {
|
||||
matchPlayer.setHealth(0);
|
||||
}
|
||||
|
||||
matchPlayer.setHealth(0);
|
||||
sender.sendMessage(tl("kill", matchPlayer.getDisplayName()));
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ public class Commandkit extends EssentialsCommand {
|
||||
}
|
||||
String[] kitList = kitNames.split(",");
|
||||
|
||||
List<Kit> kits = new ArrayList<Kit>();
|
||||
List<Kit> kits = new ArrayList<>();
|
||||
|
||||
for (final String kitName : kitList) {
|
||||
if (kitName.isEmpty()) {
|
||||
@@ -81,8 +81,9 @@ public class Commandkit extends EssentialsCommand {
|
||||
|
||||
kit.checkDelay(userFrom);
|
||||
kit.checkAffordable(userFrom);
|
||||
if (!kit.expandItems(userTo))
|
||||
continue;
|
||||
kit.setTime(userFrom);
|
||||
kit.expandItems(userTo);
|
||||
kit.chargeUser(userTo);
|
||||
|
||||
if (!userFrom.equals(userTo)) {
|
||||
|
||||
@@ -24,11 +24,10 @@ public class Commandlightning extends EssentialsLoopCommand {
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
User user;
|
||||
if (sender.isPlayer()) {
|
||||
user = ess.getUser(sender.getPlayer());
|
||||
if ((args.length < 1 || user != null && !user.isAuthorized("essentials.lightning.others"))) {
|
||||
user.getWorld().strikeLightning(user.getBase().getTargetBlock((Set<Material>) null, 600).getLocation());
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
if ((args.length < 1 || !user.isAuthorized("essentials.lightning.others"))) {
|
||||
user.getWorld().strikeLightning(user.getBase().getTargetBlock(null, 600).getLocation());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +35,7 @@ public class Commandlightning extends EssentialsLoopCommand {
|
||||
if (args.length > 1) {
|
||||
try {
|
||||
power = Integer.parseInt(args[1]);
|
||||
} catch (NumberFormatException ex) {
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
loopOnlinePlayers(server, sender, true, true, args[0], null);
|
||||
@@ -64,6 +63,7 @@ public class Commandlightning extends EssentialsLoopCommand {
|
||||
return super.getTabCompleteOptions(server, user, commandLabel, args);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
|
||||
@@ -57,14 +57,14 @@ public class Commandlist extends EssentialsCommand {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<User> outputUserList = new ArrayList<>();
|
||||
List<User> outputUserList;
|
||||
final List<User> matchedList = playerList.get(configGroup);
|
||||
|
||||
// If the group value is an int, then we might need to truncate it
|
||||
if (NumberUtil.isInt(groupValue)) {
|
||||
if (matchedList != null && !matchedList.isEmpty()) {
|
||||
playerList.remove(configGroup);
|
||||
outputUserList.addAll(matchedList);
|
||||
outputUserList = new ArrayList<>(matchedList);
|
||||
int limit = Integer.parseInt(groupValue);
|
||||
if (matchedList.size() > limit) {
|
||||
sender.sendMessage(PlayerList.outputFormat(oConfigGroup, tl("groupNumber", matchedList.size(), commandLabel, FormatUtil.stripFormat(configGroup))));
|
||||
@@ -86,7 +86,7 @@ public class Commandlist extends EssentialsCommand {
|
||||
}
|
||||
|
||||
Set<String> var = playerList.keySet();
|
||||
String[] onlineGroups = var.toArray(new String[var.size()]);
|
||||
String[] onlineGroups = var.toArray(new String[0]);
|
||||
Arrays.sort(onlineGroups, String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
// If we have an asterisk group, then merge all remaining groups
|
||||
@@ -98,7 +98,7 @@ public class Commandlist extends EssentialsCommand {
|
||||
for (String key : asterisk) {
|
||||
playerList.put(key, asteriskUsers);
|
||||
}
|
||||
onlineGroups = asterisk.toArray(new String[asterisk.size()]);
|
||||
onlineGroups = asterisk.toArray(new String[0]);
|
||||
}
|
||||
|
||||
// If we have any groups remaining after the custom groups loop through and display them
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.textreader.TextPager;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -48,7 +49,11 @@ public class Commandmail extends EssentialsCommand {
|
||||
}
|
||||
|
||||
if (user.isMuted()) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
String dateDiff = user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
}
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
|
||||
User u = getPlayer(server, args[1], true, true);
|
||||
|
||||
@@ -2,6 +2,7 @@ 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.FormatUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@@ -24,7 +25,11 @@ public class Commandme extends EssentialsCommand {
|
||||
@Override
|
||||
public void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
if (user.isMuted()) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
String dateDiff = user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
}
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
|
||||
if (args.length < 1) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@@ -17,22 +19,37 @@ public class Commandmore extends EssentialsCommand {
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final ItemStack stack = user.getItemInHand();
|
||||
if (stack == null) {
|
||||
if (stack == null || stack.getType() == Material.AIR) {
|
||||
throw new Exception(tl("cantSpawnItem", "Air"));
|
||||
}
|
||||
|
||||
if (stack.getAmount() >= ((user.isAuthorized("essentials.oversizedstacks")) ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize())) {
|
||||
boolean canOversized = user.isAuthorized("essentials.oversizedstacks");
|
||||
if (stack.getAmount() >= ((canOversized) ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize())) {
|
||||
throw new Exception(tl("fullStack"));
|
||||
}
|
||||
|
||||
final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
|
||||
if (!user.canSpawnItem(stack.getType())) {
|
||||
throw new Exception(tl("cantSpawnItem", itemname));
|
||||
}
|
||||
if (user.isAuthorized("essentials.oversizedstacks")) {
|
||||
stack.setAmount(ess.getSettings().getOversizedStackSize());
|
||||
|
||||
int newStackSize = stack.getAmount();
|
||||
if (args.length >= 1) {
|
||||
if (!NumberUtil.isPositiveInt(args[0])) {
|
||||
throw new Exception(tl("nonZeroPosNumber"));
|
||||
}
|
||||
newStackSize += Integer.parseInt(args[0]);
|
||||
|
||||
if (newStackSize > ((canOversized) ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize())) {
|
||||
user.sendMessage(tl(canOversized ? "fullStackDefaultOversize" : "fullStackDefault", canOversized ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize()));
|
||||
newStackSize = canOversized ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize();
|
||||
}
|
||||
} else if (canOversized) {
|
||||
newStackSize = ess.getSettings().getOversizedStackSize();
|
||||
} else {
|
||||
stack.setAmount(stack.getMaxStackSize());
|
||||
newStackSize = stack.getMaxStackSize();
|
||||
}
|
||||
stack.setAmount(newStackSize);
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.Console;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.messaging.IMessageRecipient;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandmsg extends EssentialsLoopCommand {
|
||||
|
||||
public Commandmsg() {
|
||||
@@ -20,7 +20,7 @@ public class Commandmsg extends EssentialsLoopCommand {
|
||||
|
||||
@Override
|
||||
public void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
|
||||
if (args.length < 2 || args[0].trim().length() < 2 || args[1].trim().isEmpty()) {
|
||||
if (args.length < 2 || args[0].trim().isEmpty() || args[1].trim().isEmpty()) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,11 @@ public class Commandmsg extends EssentialsLoopCommand {
|
||||
if (sender.isPlayer()) {
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
if (user.isMuted()) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
String dateDiff = user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
}
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
message = FormatUtil.formatMessage(user, "essentials.msg", message);
|
||||
canWildcard = user.isAuthorized("essentials.msg.multiple");
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.earth2me.essentials.utils.DateUtil;
|
||||
import net.ess3.api.events.MuteStatusChangeEvent;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@@ -40,25 +41,33 @@ public class Commandmute extends EssentialsCommand {
|
||||
throw new Exception(tl("muteExempt"));
|
||||
}
|
||||
}
|
||||
|
||||
long muteTimestamp = 0;
|
||||
String time;
|
||||
String muteReason = null;
|
||||
|
||||
if (args.length > 1) {
|
||||
time = args[1];
|
||||
try {
|
||||
muteTimestamp = DateUtil.parseDateDiff(time, true);
|
||||
muteReason = getFinalArg(args, 2);
|
||||
} catch (Exception e) {
|
||||
muteReason = getFinalArg(args, 1);
|
||||
}
|
||||
final long maxMuteLength = ess.getSettings().getMaxMute() * 1000;
|
||||
if (maxMuteLength > 0 && ((muteTimestamp - GregorianCalendar.getInstance().getTimeInMillis()) > maxMuteLength) && sender.isPlayer() && !(ess.getUser(sender.getPlayer()).isAuthorized("essentials.mute.unlimited"))) {
|
||||
sender.sendMessage(tl("oversizedMute"));
|
||||
throw new NoChargeException();
|
||||
}
|
||||
}
|
||||
|
||||
final boolean willMute = (args.length > 1) || !user.getMuted();
|
||||
final User controller = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : null;
|
||||
final MuteStatusChangeEvent event = new MuteStatusChangeEvent(user, controller, willMute);
|
||||
final MuteStatusChangeEvent event = new MuteStatusChangeEvent(user, controller, willMute, muteTimestamp, muteReason);
|
||||
ess.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
long muteTimestamp = 0;
|
||||
|
||||
if (args.length > 1) {
|
||||
final String time = args[1];
|
||||
String muteReason;
|
||||
try {
|
||||
muteTimestamp = DateUtil.parseDateDiff(time, true);
|
||||
muteReason = getFinalArg(args, 2);
|
||||
} catch (Exception e) {
|
||||
muteReason = getFinalArg(args, 1);
|
||||
}
|
||||
|
||||
if (muteReason != null) {
|
||||
user.setMuteReason(muteReason.isEmpty() ? null : muteReason);
|
||||
user.setMuted(true);
|
||||
} else {
|
||||
|
||||
@@ -38,13 +38,13 @@ public class Commandnear extends EssentialsCommand {
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
otherUser = getPlayer(server, user, args, 0);
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
if (args.length > 1 && otherUser != null) {
|
||||
try {
|
||||
radius = Long.parseLong(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ public class Commandnear extends EssentialsCommand {
|
||||
if (args.length > 1) {
|
||||
try {
|
||||
radius = Long.parseLong(args[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
sender.sendMessage(tl("nearbyPlayers", getLocal(server, otherUser, radius)));
|
||||
@@ -88,7 +88,7 @@ public class Commandnear extends EssentialsCommand {
|
||||
Queue<User> nearbyPlayers = new PriorityQueue<>((o1, o2) -> (int) (o1.getLocation().distanceSquared(loc) - o2.getLocation().distanceSquared(loc)));
|
||||
|
||||
for (User player : ess.getOnlineUsers()) {
|
||||
if (!player.equals(user) && (!player.isHidden(user.getBase()) || showHidden || user.getBase().canSee(player.getBase()))) {
|
||||
if (!player.equals(user) && !player.isAuthorized("essentials.near.exclude") && (!player.isHidden(user.getBase()) || showHidden || user.getBase().canSee(player.getBase()))) {
|
||||
final Location playerLoc = player.getLocation();
|
||||
if (playerLoc.getWorld() != world) {
|
||||
continue;
|
||||
|
||||
@@ -83,10 +83,17 @@ public class Commandnick extends EssentialsLoopCommand {
|
||||
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())) {
|
||||
throw new Exception(tl("nickNamesOnlyColorChanges"));
|
||||
} else if (user != null && !user.isAuthorized("essentials.nick.blacklist.bypass") && isNickBanned(newNick)) {
|
||||
throw new Exception(tl("nickNameBlacklist", nick));
|
||||
}
|
||||
return newNick;
|
||||
}
|
||||
|
||||
private boolean isNickBanned(String newNick) {
|
||||
return ess.getSettings().getNickBlacklist().stream()
|
||||
.anyMatch(entry -> entry.test(newNick));
|
||||
}
|
||||
|
||||
private int getNickLength(final String nick) {
|
||||
return ess.getSettings().ignoreColorsInMaxLength() ? ChatColor.stripColor(nick).length() : nick.length();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.earth2me.essentials.utils.StringUtil;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import net.ess3.api.events.UserBalanceUpdateEvent;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -49,7 +50,7 @@ public class Commandpay extends EssentialsLoopCommand {
|
||||
}
|
||||
loopOnlinePlayers(server, user.getSource(), false, user.isAuthorized("essentials.pay.multiple"), args[0], args);
|
||||
if (informToConfirm) {
|
||||
String cmd = "/" + commandLabel + " " + StringUtil.joinList(" ", (Object[]) args);
|
||||
String cmd = "/" + commandLabel + " " + StringUtil.joinList(" ", args);
|
||||
user.sendMessage(tl("confirmPayment", NumberUtil.displayCurrency(amount, ess), cmd));
|
||||
}
|
||||
}
|
||||
@@ -58,7 +59,7 @@ public class Commandpay extends EssentialsLoopCommand {
|
||||
protected void updatePlayer(final Server server, final CommandSource sender, final User player, final String[] args) throws ChargeException {
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
try {
|
||||
if (!player.isAcceptingPay()) {
|
||||
if (!player.isAcceptingPay() || (ess.getSettings().isPayExcludesIgnoreList() && player.isIgnoredPlayer(user))) {
|
||||
sender.sendMessage(tl("notAcceptingPay", player.getDisplayName()));
|
||||
return;
|
||||
}
|
||||
@@ -73,7 +74,7 @@ public class Commandpay extends EssentialsLoopCommand {
|
||||
user.getConfirmingPayments().put(player, amount);
|
||||
return;
|
||||
}
|
||||
user.payUser(player, amount);
|
||||
user.payUser(player, amount, UserBalanceUpdateEvent.Cause.COMMAND_PAY);
|
||||
user.getConfirmingPayments().remove(player);
|
||||
Trade.log("Command", "Pay", "Player", user.getName(), new Trade(amount, ess), player.getName(), new Trade(amount, ess), user.getLocation(), ess);
|
||||
} catch (MaxMoneyException ex) {
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.I18n;
|
||||
import com.earth2me.essentials.User;
|
||||
|
||||
import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandpaytoggle extends EssentialsCommand {
|
||||
|
||||
public Commandpaytoggle() {
|
||||
|
||||
@@ -1,31 +1,22 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.Potions;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
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;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.*;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
|
||||
|
||||
public class Commandpotion extends EssentialsCommand {
|
||||
public Commandpotion() {
|
||||
|
||||
@@ -85,7 +85,7 @@ public class Commandpowertool extends EssentialsCommand {
|
||||
// Replace all commands with this one
|
||||
powertools.clear();
|
||||
} else {
|
||||
powertools = new ArrayList<String>();
|
||||
powertools = new ArrayList<>();
|
||||
}
|
||||
|
||||
powertools.add(command);
|
||||
@@ -122,7 +122,7 @@ public class Commandpowertool extends EssentialsCommand {
|
||||
for (String tool : powertools) {
|
||||
options.add("r:" + tool);
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception ignored) {}
|
||||
return options;
|
||||
} else if (args[0].startsWith("a:")) {
|
||||
return tabCompleteCommand(user.getSource(), server, args[0].substring(2), args, 1);
|
||||
@@ -151,7 +151,7 @@ public class Commandpowertool extends EssentialsCommand {
|
||||
for (String tool : powertools) {
|
||||
options.add("r:" + tool);
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception ignored) {}
|
||||
return options;
|
||||
} else if (args[2].startsWith("a:")) {
|
||||
return tabCompleteCommand(sender, server, args[2].substring(2), args, 3);
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.Console;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.messaging.IMessageRecipient;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
@@ -28,7 +29,11 @@ public class Commandr extends EssentialsCommand {
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
|
||||
if (user.isMuted()) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
String dateDiff = user.getMuteTimeout() > 0 ? DateUtil.formatDateDiff(user.getMuteTimeout()) : null;
|
||||
if (dateDiff == null) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
}
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReasonTime", dateDiff, user.getMuteReason()) : tl("voiceSilencedTime", dateDiff));
|
||||
}
|
||||
|
||||
message = FormatUtil.formatMessage(user, "essentials.msg", message);
|
||||
|
||||
@@ -1,195 +1,193 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
|
||||
|
||||
public class Commandrecipe extends EssentialsCommand {
|
||||
|
||||
private static final Material FIREWORK_ROCKET = EnumUtil.getMaterial("FIREWORK_ROCKET", "FIREWORK");
|
||||
private static final Material FIREWORK_STAR = EnumUtil.getMaterial("FIREWORK_STAR", "FIREWORK_CHARGE");
|
||||
private static final Material GUNPOWDER = EnumUtil.getMaterial("GUNPOWDER", "SULPHUR");
|
||||
|
||||
public Commandrecipe() {
|
||||
super("recipe");
|
||||
}
|
||||
|
||||
private void disableCommandForVersion1_12() throws Exception {
|
||||
VersionUtil.BukkitVersion version = VersionUtil.getServerBukkitVersion();
|
||||
if (version.isHigherThanOrEqualTo(VersionUtil.v1_12_0_R01)
|
||||
&& !ess.getSettings().isForceEnableRecipe()) {
|
||||
throw new Exception("Please use the recipe book in your inventory.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
disableCommandForVersion1_12();
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final ItemStack itemType = ess.getItemDb().get(args[0]);
|
||||
int recipeNo = 0;
|
||||
|
||||
if (args.length > 1) {
|
||||
if (NumberUtil.isInt(args[1])) {
|
||||
recipeNo = Integer.parseInt(args[1]) - 1;
|
||||
} else {
|
||||
throw new Exception(tl("invalidNumber"));
|
||||
}
|
||||
}
|
||||
|
||||
final List<Recipe> recipesOfType = ess.getServer().getRecipesFor(itemType);
|
||||
if (recipesOfType.size() < 1) {
|
||||
throw new Exception(tl("recipeNone", getMaterialName(itemType)));
|
||||
}
|
||||
|
||||
if (recipeNo < 0 || recipeNo >= recipesOfType.size()) {
|
||||
throw new Exception(tl("recipeBadIndex"));
|
||||
}
|
||||
|
||||
final Recipe selectedRecipe = recipesOfType.get(recipeNo);
|
||||
sender.sendMessage(tl("recipe", getMaterialName(itemType), recipeNo + 1, recipesOfType.size()));
|
||||
|
||||
if (selectedRecipe instanceof FurnaceRecipe) {
|
||||
furnaceRecipe(sender, (FurnaceRecipe) selectedRecipe);
|
||||
} else if (selectedRecipe instanceof ShapedRecipe) {
|
||||
shapedRecipe(sender, (ShapedRecipe) selectedRecipe, sender.isPlayer());
|
||||
} else if (selectedRecipe instanceof ShapelessRecipe) {
|
||||
if (recipesOfType.size() == 1 && (itemType.getType() == FIREWORK_ROCKET)) {
|
||||
ShapelessRecipe shapelessRecipe = new ShapelessRecipe(itemType);
|
||||
shapelessRecipe.addIngredient(GUNPOWDER);
|
||||
shapelessRecipe.addIngredient(Material.PAPER);
|
||||
shapelessRecipe.addIngredient(FIREWORK_STAR);
|
||||
shapelessRecipe(sender, shapelessRecipe, sender.isPlayer());
|
||||
} else {
|
||||
shapelessRecipe(sender, (ShapelessRecipe) selectedRecipe, sender.isPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
if (recipesOfType.size() > 1 && args.length == 1) {
|
||||
sender.sendMessage(tl("recipeMore", commandLabel, args[0], getMaterialName(itemType)));
|
||||
}
|
||||
}
|
||||
|
||||
public void furnaceRecipe(final CommandSource sender, final FurnaceRecipe recipe) {
|
||||
sender.sendMessage(tl("recipeFurnace", getMaterialName(recipe.getInput())));
|
||||
}
|
||||
|
||||
public void shapedRecipe(final CommandSource sender, final ShapedRecipe recipe, final boolean showWindow) {
|
||||
final Map<Character, ItemStack> recipeMap = recipe.getIngredientMap();
|
||||
|
||||
if (showWindow) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
user.getBase().closeInventory();
|
||||
user.setRecipeSee(true);
|
||||
final InventoryView view = user.getBase().openWorkbench(null, true);
|
||||
final String[] recipeShape = recipe.getShape();
|
||||
final Map<Character, ItemStack> ingredientMap = recipe.getIngredientMap();
|
||||
for (int j = 0; j < recipeShape.length; j++) {
|
||||
for (int k = 0; k < recipeShape[j].length(); k++) {
|
||||
final ItemStack item = ingredientMap.get(recipeShape[j].toCharArray()[k]);
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
if (item.getDurability() == Short.MAX_VALUE) {
|
||||
item.setDurability((short) 0);
|
||||
}
|
||||
view.getTopInventory().setItem(j * 3 + k + 1, item);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final HashMap<Material, String> colorMap = new HashMap<>();
|
||||
int i = 1;
|
||||
for (Character c : "abcdefghi".toCharArray()) {
|
||||
ItemStack item = recipeMap.get(c);
|
||||
if (!colorMap.containsKey(item == null ? null : item.getType())) {
|
||||
colorMap.put(item == null ? null : item.getType(), String.valueOf(i++));
|
||||
}
|
||||
}
|
||||
final Material[][] materials = new Material[3][3];
|
||||
for (int j = 0; j < recipe.getShape().length; j++) {
|
||||
for (int k = 0; k < recipe.getShape()[j].length(); k++) {
|
||||
ItemStack item = recipe.getIngredientMap().get(recipe.getShape()[j].toCharArray()[k]);
|
||||
materials[j][k] = item == null ? null : item.getType();
|
||||
}
|
||||
}
|
||||
sender.sendMessage(tl("recipeGrid", colorMap.get(materials[0][0]), colorMap.get(materials[0][1]), colorMap.get(materials[0][2])));
|
||||
sender.sendMessage(tl("recipeGrid", colorMap.get(materials[1][0]), colorMap.get(materials[1][1]), colorMap.get(materials[1][2])));
|
||||
sender.sendMessage(tl("recipeGrid", colorMap.get(materials[2][0]), colorMap.get(materials[2][1]), colorMap.get(materials[2][2])));
|
||||
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (Material items : colorMap.keySet().toArray(new Material[colorMap.size()])) {
|
||||
s.append(tl("recipeGridItem", colorMap.get(items), getMaterialName(items)));
|
||||
}
|
||||
sender.sendMessage(tl("recipeWhere", s.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public void shapelessRecipe(final CommandSource sender, final ShapelessRecipe recipe, final boolean showWindow) {
|
||||
final List<ItemStack> ingredients = recipe.getIngredientList();
|
||||
if (showWindow) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
user.setRecipeSee(true);
|
||||
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) {
|
||||
item.setDurability((short) 0);
|
||||
}
|
||||
view.setItem(i + 1, item);
|
||||
}
|
||||
|
||||
} else {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (int i = 0; i < ingredients.size(); i++) {
|
||||
s.append(getMaterialName(ingredients.get(i)));
|
||||
if (i != ingredients.size() - 1) {
|
||||
s.append(",");
|
||||
}
|
||||
s.append(" ");
|
||||
}
|
||||
sender.sendMessage(tl("recipeShapeless", s.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public String getMaterialName(final ItemStack stack) {
|
||||
if (stack == null) {
|
||||
return tl("recipeNothing");
|
||||
}
|
||||
return getMaterialName(stack.getType());
|
||||
}
|
||||
|
||||
public String getMaterialName(final Material type) {
|
||||
if (type == null) {
|
||||
return tl("recipeNothing");
|
||||
}
|
||||
return type.toString().replace("_", " ").toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getItems();
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandrecipe extends EssentialsCommand {
|
||||
|
||||
private static final Material FIREWORK_ROCKET = EnumUtil.getMaterial("FIREWORK_ROCKET", "FIREWORK");
|
||||
private static final Material FIREWORK_STAR = EnumUtil.getMaterial("FIREWORK_STAR", "FIREWORK_CHARGE");
|
||||
private static final Material GUNPOWDER = EnumUtil.getMaterial("GUNPOWDER", "SULPHUR");
|
||||
|
||||
public Commandrecipe() {
|
||||
super("recipe");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
// On versions at or above 1.12, we need recipe book API
|
||||
if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_12_0_R01)) {
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent");
|
||||
} catch (ClassNotFoundException e) {
|
||||
sender.sendMessage(tl("unsupportedFeature"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final ItemStack itemType = ess.getItemDb().get(args[0]);
|
||||
int recipeNo = 0;
|
||||
|
||||
if (args.length > 1) {
|
||||
if (NumberUtil.isInt(args[1])) {
|
||||
recipeNo = Integer.parseInt(args[1]) - 1;
|
||||
} else {
|
||||
throw new Exception(tl("invalidNumber"));
|
||||
}
|
||||
}
|
||||
|
||||
final List<Recipe> recipesOfType = ess.getServer().getRecipesFor(itemType);
|
||||
if (recipesOfType.size() < 1) {
|
||||
throw new Exception(tl("recipeNone", getMaterialName(itemType)));
|
||||
}
|
||||
|
||||
if (recipeNo < 0 || recipeNo >= recipesOfType.size()) {
|
||||
throw new Exception(tl("recipeBadIndex"));
|
||||
}
|
||||
|
||||
final Recipe selectedRecipe = recipesOfType.get(recipeNo);
|
||||
sender.sendMessage(tl("recipe", getMaterialName(itemType), recipeNo + 1, recipesOfType.size()));
|
||||
|
||||
if (selectedRecipe instanceof FurnaceRecipe) {
|
||||
furnaceRecipe(sender, (FurnaceRecipe) selectedRecipe);
|
||||
} else if (selectedRecipe instanceof ShapedRecipe) {
|
||||
shapedRecipe(sender, (ShapedRecipe) selectedRecipe, sender.isPlayer());
|
||||
} else if (selectedRecipe instanceof ShapelessRecipe) {
|
||||
if (recipesOfType.size() == 1 && (itemType.getType() == FIREWORK_ROCKET)) {
|
||||
ShapelessRecipe shapelessRecipe = new ShapelessRecipe(itemType);
|
||||
shapelessRecipe.addIngredient(GUNPOWDER);
|
||||
shapelessRecipe.addIngredient(Material.PAPER);
|
||||
shapelessRecipe.addIngredient(FIREWORK_STAR);
|
||||
shapelessRecipe(sender, shapelessRecipe, sender.isPlayer());
|
||||
} else {
|
||||
shapelessRecipe(sender, (ShapelessRecipe) selectedRecipe, sender.isPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
if (recipesOfType.size() > 1 && args.length == 1) {
|
||||
sender.sendMessage(tl("recipeMore", commandLabel, args[0], getMaterialName(itemType)));
|
||||
}
|
||||
}
|
||||
|
||||
public void furnaceRecipe(final CommandSource sender, final FurnaceRecipe recipe) {
|
||||
sender.sendMessage(tl("recipeFurnace", getMaterialName(recipe.getInput())));
|
||||
}
|
||||
|
||||
public void shapedRecipe(final CommandSource sender, final ShapedRecipe recipe, final boolean showWindow) {
|
||||
final Map<Character, ItemStack> recipeMap = recipe.getIngredientMap();
|
||||
|
||||
if (showWindow) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
user.getBase().closeInventory();
|
||||
user.setRecipeSee(true);
|
||||
final InventoryView view = user.getBase().openWorkbench(null, true);
|
||||
final String[] recipeShape = recipe.getShape();
|
||||
final Map<Character, ItemStack> ingredientMap = recipe.getIngredientMap();
|
||||
for (int j = 0; j < recipeShape.length; j++) {
|
||||
for (int k = 0; k < recipeShape[j].length(); k++) {
|
||||
final ItemStack item = ingredientMap.get(recipeShape[j].toCharArray()[k]);
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
if (item.getDurability() == Short.MAX_VALUE) {
|
||||
item.setDurability((short) 0);
|
||||
}
|
||||
view.getTopInventory().setItem(j * 3 + k + 1, item);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final HashMap<Material, String> colorMap = new HashMap<>();
|
||||
int i = 1;
|
||||
for (Character c : "abcdefghi".toCharArray()) {
|
||||
ItemStack item = recipeMap.get(c);
|
||||
if (!colorMap.containsKey(item == null ? null : item.getType())) {
|
||||
colorMap.put(item == null ? null : item.getType(), String.valueOf(i++));
|
||||
}
|
||||
}
|
||||
final Material[][] materials = new Material[3][3];
|
||||
for (int j = 0; j < recipe.getShape().length; j++) {
|
||||
for (int k = 0; k < recipe.getShape()[j].length(); k++) {
|
||||
ItemStack item = recipe.getIngredientMap().get(recipe.getShape()[j].toCharArray()[k]);
|
||||
materials[j][k] = item == null ? null : item.getType();
|
||||
}
|
||||
}
|
||||
sender.sendMessage(tl("recipeGrid", colorMap.get(materials[0][0]), colorMap.get(materials[0][1]), colorMap.get(materials[0][2])));
|
||||
sender.sendMessage(tl("recipeGrid", colorMap.get(materials[1][0]), colorMap.get(materials[1][1]), colorMap.get(materials[1][2])));
|
||||
sender.sendMessage(tl("recipeGrid", colorMap.get(materials[2][0]), colorMap.get(materials[2][1]), colorMap.get(materials[2][2])));
|
||||
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (Material items : colorMap.keySet().toArray(new Material[0])) {
|
||||
s.append(tl("recipeGridItem", colorMap.get(items), getMaterialName(items)));
|
||||
}
|
||||
sender.sendMessage(tl("recipeWhere", s.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public void shapelessRecipe(final CommandSource sender, final ShapelessRecipe recipe, final boolean showWindow) {
|
||||
final List<ItemStack> ingredients = recipe.getIngredientList();
|
||||
if (showWindow) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
user.setRecipeSee(true);
|
||||
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) {
|
||||
item.setDurability((short) 0);
|
||||
}
|
||||
view.setItem(i + 1, item);
|
||||
}
|
||||
|
||||
} else {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (int i = 0; i < ingredients.size(); i++) {
|
||||
s.append(getMaterialName(ingredients.get(i)));
|
||||
if (i != ingredients.size() - 1) {
|
||||
s.append(",");
|
||||
}
|
||||
s.append(" ");
|
||||
}
|
||||
sender.sendMessage(tl("recipeShapeless", s.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
public String getMaterialName(final ItemStack stack) {
|
||||
if (stack == null) {
|
||||
return tl("recipeNothing");
|
||||
}
|
||||
return getMaterialName(stack.getType());
|
||||
}
|
||||
|
||||
public String getMaterialName(final Material type) {
|
||||
if (type == null) {
|
||||
return tl("recipeNothing");
|
||||
}
|
||||
return type.toString().replace("_", " ").toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getItems();
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.Mob;
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.*;
|
||||
@@ -126,8 +127,8 @@ public class Commandremove extends EssentialsCommand {
|
||||
|
||||
for (ToRemove toRemove : removeTypes) {
|
||||
|
||||
// We should skip any TAMED animals unless we are specifially targetting them.
|
||||
if (e instanceof Tameable && ((Tameable) e).isTamed() && !removeTypes.contains(ToRemove.TAMED)) {
|
||||
// We should skip any animals tamed by players unless we are specifially targetting them.
|
||||
if (e instanceof Tameable && ((Tameable) e).isTamed() && (((Tameable) e).getOwner() instanceof Player || ((Tameable) e).getOwner() instanceof OfflinePlayer) && !removeTypes.contains(ToRemove.TAMED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 325 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user