2011-03-19 23:39:51 +01:00
|
|
|
package com.earth2me.essentials.commands;
|
|
|
|
|
2013-10-16 21:59:39 +02:00
|
|
|
import com.earth2me.essentials.CommandSource;
|
2014-04-17 03:18:28 +02:00
|
|
|
import com.earth2me.essentials.EssentialsUpgrade;
|
2012-09-14 03:30:24 +02:00
|
|
|
import com.earth2me.essentials.User;
|
2013-02-19 21:33:04 +01:00
|
|
|
import com.earth2me.essentials.UserMap;
|
2020-10-03 19:46:05 +02:00
|
|
|
import com.earth2me.essentials.utils.DateUtil;
|
|
|
|
import com.earth2me.essentials.utils.EnumUtil;
|
|
|
|
import com.earth2me.essentials.utils.FloatUtil;
|
|
|
|
import com.earth2me.essentials.utils.NumberUtil;
|
|
|
|
import com.earth2me.essentials.utils.VersionUtil;
|
2014-04-27 00:49:38 +02:00
|
|
|
import com.google.common.base.Charsets;
|
2019-08-05 16:25:55 +02:00
|
|
|
import com.google.common.collect.ImmutableMap;
|
2017-06-11 02:17:43 +02:00
|
|
|
import com.google.common.collect.Lists;
|
2021-05-14 18:01:50 +02:00
|
|
|
import org.bukkit.ChatColor;
|
2021-06-18 17:24:43 +02:00
|
|
|
import org.bukkit.Location;
|
2011-03-19 23:39:51 +01:00
|
|
|
import org.bukkit.Server;
|
2013-02-19 21:33:04 +01:00
|
|
|
import org.bukkit.Sound;
|
2021-06-18 17:24:43 +02:00
|
|
|
import org.bukkit.World;
|
2011-06-23 19:34:51 +02:00
|
|
|
import org.bukkit.entity.Player;
|
2020-02-10 10:05:32 +01:00
|
|
|
import org.bukkit.plugin.Plugin;
|
|
|
|
import org.bukkit.plugin.PluginDescriptionFile;
|
|
|
|
import org.bukkit.plugin.PluginManager;
|
2019-08-05 16:25:55 +02:00
|
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
2011-03-19 23:39:51 +01:00
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Locale;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.UUID;
|
2020-02-10 10:05:32 +01:00
|
|
|
import java.util.function.Supplier;
|
2021-06-18 17:24:43 +02:00
|
|
|
import java.util.stream.Collectors;
|
2020-02-10 10:05:32 +01:00
|
|
|
|
|
|
|
import static com.earth2me.essentials.I18n.tl;
|
|
|
|
|
2012-10-06 04:31:34 +02:00
|
|
|
// This command has 4 undocumented behaviours #EasterEgg
|
2015-04-15 06:06:16 +02:00
|
|
|
public class Commandessentials extends EssentialsCommand {
|
2018-12-31 13:19:22 +01:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
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");
|
|
|
|
|
2021-06-18 17:24:43 +02:00
|
|
|
private static final String HOMES_USAGE = "/<command> homes (fix | delete [world])";
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
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,,";
|
2020-10-03 19:46:05 +02:00
|
|
|
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?\"..."};
|
2020-02-10 10:05:32 +01:00
|
|
|
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)
|
2021-07-01 15:43:35 +02:00
|
|
|
"bPermissions", // permissions (unsupported)
|
|
|
|
"DiscordSRV" // potential for issues if EssentialsXDiscord is installed
|
2020-02-10 10:05:32 +01:00
|
|
|
);
|
|
|
|
private static final List<String> officialPlugins = Arrays.asList(
|
|
|
|
"EssentialsAntiBuild",
|
|
|
|
"EssentialsChat",
|
2021-07-01 15:43:35 +02:00
|
|
|
"EssentialsDiscord",
|
2020-02-10 10:05:32 +01:00
|
|
|
"EssentialsGeoIP",
|
|
|
|
"EssentialsProtect",
|
|
|
|
"EssentialsSpawn",
|
|
|
|
"EssentialsXMPP"
|
|
|
|
);
|
|
|
|
private static final List<String> warnPlugins = Arrays.asList(
|
|
|
|
"PermissionsEx",
|
|
|
|
"GroupManager",
|
2021-01-19 03:22:04 +01:00
|
|
|
"bPermissions"
|
2020-02-10 10:05:32 +01:00
|
|
|
);
|
2020-10-03 19:46:05 +02:00
|
|
|
private transient TuneRunnable currentTune = null;
|
|
|
|
|
|
|
|
public Commandessentials() {
|
|
|
|
super("essentials");
|
|
|
|
}
|
2020-02-10 10:05:32 +01:00
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
@Override
|
|
|
|
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
|
|
|
if (args.length == 0) {
|
2019-08-05 16:25:55 +02:00
|
|
|
showUsage(sender);
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
switch (args[0]) {
|
2019-08-05 16:25:55 +02:00
|
|
|
// 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;
|
2020-10-03 19:46:05 +02:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// 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;
|
2021-06-18 17:24:43 +02:00
|
|
|
case "homes":
|
|
|
|
runHomes(server, sender, commandLabel, args);
|
|
|
|
break;
|
2019-08-05 16:25:55 +02:00
|
|
|
case "uuidconvert":
|
|
|
|
runUUIDConvert(server, sender, commandLabel, args);
|
|
|
|
break;
|
|
|
|
case "uuidtest":
|
|
|
|
runUUIDTest(server, sender, commandLabel, args);
|
|
|
|
break;
|
2020-10-03 19:46:05 +02:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// "#EasterEgg"
|
|
|
|
case "nya":
|
|
|
|
case "nyan":
|
|
|
|
runNya(server, sender, commandLabel, args);
|
|
|
|
break;
|
|
|
|
case "moo":
|
|
|
|
runMoo(server, sender, commandLabel, args);
|
|
|
|
break;
|
|
|
|
default:
|
2020-10-03 19:46:05 +02:00
|
|
|
showUsage(sender);
|
|
|
|
break;
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// Displays the command's usage.
|
|
|
|
private void showUsage(final CommandSource sender) throws Exception {
|
2021-06-18 17:24:43 +02:00
|
|
|
throw new NotEnoughArgumentsException();
|
2019-08-05 16:25:55 +02:00
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// 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) {
|
2020-12-30 20:59:38 +01:00
|
|
|
if (ess.getAlternativeCommandsHandler().disabledCommands().size() == 0) {
|
2019-08-05 16:25:55 +02:00
|
|
|
sender.sendMessage(tl("blockListEmpty"));
|
2020-12-30 20:59:38 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sender.sendMessage(tl("blockList"));
|
|
|
|
for (final Map.Entry<String, String> entry : ess.getAlternativeCommandsHandler().disabledCommands().entrySet()) {
|
|
|
|
sender.sendMessage(entry.getKey() + " => " + entry.getValue());
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// Resets the given player's user data.
|
|
|
|
private void runReset(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (args.length < 2) {
|
|
|
|
throw new Exception("/<command> reset <player>");
|
|
|
|
}
|
|
|
|
final User user = getPlayer(server, args, 1, true, true);
|
|
|
|
user.reset();
|
|
|
|
sender.sendMessage("Reset Essentials userdata for player: " + user.getDisplayName());
|
|
|
|
}
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// Toggles debug mode.
|
|
|
|
private void runDebug(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
2015-04-15 06:06:16 +02:00
|
|
|
ess.getSettings().setDebug(!ess.getSettings().isDebug());
|
|
|
|
sender.sendMessage("Essentials " + ess.getDescription().getVersion() + " debug mode " + (ess.getSettings().isDebug() ? "enabled" : "disabled"));
|
|
|
|
}
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// Reloads all reloadable configs.
|
|
|
|
private void runReload(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
2015-04-15 06:06:16 +02:00
|
|
|
ess.reload();
|
|
|
|
sender.sendMessage(tl("essentialsReload", ess.getDescription().getVersion()));
|
|
|
|
}
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// Pop tarts.
|
|
|
|
private void runNya(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
|
|
|
if (currentTune != null) {
|
|
|
|
currentTune.cancel();
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
currentTune = new TuneRunnable(NYAN_TUNE, NOTE_HARP, ess::getOnlinePlayers);
|
|
|
|
currentTune.runTaskTimer(ess, 20, 2);
|
|
|
|
}
|
2018-12-06 18:44:22 +01:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// Cow farts.
|
2020-04-25 14:08:57 +02:00
|
|
|
private void runMoo(final Server server, final CommandSource sender, final String command, final String[] args) {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (args.length == 2 && args[1].equals("moo")) {
|
2020-10-03 19:46:05 +02:00
|
|
|
for (final String s : CONSOLE_MOO) {
|
2015-04-15 06:06:16 +02:00
|
|
|
logger.info(s);
|
|
|
|
}
|
2020-10-03 19:46:05 +02:00
|
|
|
for (final Player player : ess.getOnlinePlayers()) {
|
2019-08-05 16:25:55 +02:00
|
|
|
player.sendMessage(PLAYER_MOO);
|
|
|
|
player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (sender.isPlayer()) {
|
2019-08-05 16:25:55 +02:00
|
|
|
sender.getSender().sendMessage(PLAYER_MOO);
|
2015-04-15 06:06:16 +02:00
|
|
|
final Player player = sender.getPlayer();
|
2019-08-05 16:25:55 +02:00
|
|
|
player.playSound(player.getLocation(), MOO_SOUND, 1, 1.0f);
|
2015-04-15 06:06:16 +02:00
|
|
|
|
|
|
|
} else {
|
2019-08-05 16:25:55 +02:00
|
|
|
sender.getSender().sendMessage(CONSOLE_MOO);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// Cleans up inactive users.
|
2020-04-25 14:08:57 +02:00
|
|
|
private void runCleanup(final Server server, final CommandSource sender, final String command, final String[] args) throws Exception {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (args.length < 2 || !NumberUtil.isInt(args[1])) {
|
2019-08-05 16:25:55 +02:00
|
|
|
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.");
|
2015-04-15 06:06:16 +02:00
|
|
|
throw new Exception("/<command> cleanup <days> [money] [homes]");
|
|
|
|
}
|
2019-08-05 16:25:55 +02:00
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
sender.sendMessage(tl("cleaning"));
|
|
|
|
|
|
|
|
final long daysArg = Long.parseLong(args[1]);
|
2015-06-05 04:32:36 +02:00
|
|
|
final double moneyArg = args.length >= 3 ? FloatUtil.parseDouble(args[2].replaceAll("[^0-9\\.]", "")) : 0;
|
2015-04-15 06:06:16 +02:00
|
|
|
final int homesArg = args.length >= 4 && NumberUtil.isInt(args[3]) ? Integer.parseInt(args[3]) : 0;
|
|
|
|
final UserMap userMap = ess.getUserMap();
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
ess.runTaskAsynchronously(() -> {
|
2020-10-03 19:46:05 +02:00
|
|
|
final long currTime = System.currentTimeMillis();
|
|
|
|
for (final UUID u : userMap.getAllUniqueUsers()) {
|
2019-08-05 16:25:55 +02:00
|
|
|
final User user = ess.getUserMap().getUser(u);
|
|
|
|
if (user == null) {
|
|
|
|
continue;
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
long lastLog = user.getLastLogout();
|
|
|
|
if (lastLog == 0) {
|
|
|
|
lastLog = user.getLastLogin();
|
|
|
|
}
|
|
|
|
if (lastLog == 0) {
|
|
|
|
user.setLastLogin(currTime);
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
if (user.isNPC()) {
|
|
|
|
continue;
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
final long timeDiff = currTime - lastLog;
|
|
|
|
final long milliDays = daysArg * 24L * 60L * 60L * 1000L;
|
|
|
|
final int homeCount = user.getHomes().size();
|
|
|
|
final double moneyCount = user.getMoney().doubleValue();
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
if ((lastLog == 0) || (timeDiff < milliDays) || (homeCount > homesArg) || (moneyCount > moneyArg)) {
|
|
|
|
continue;
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().info("Deleting user: " + user.getName() + " Money: " + moneyCount + " Homes: " + homeCount + " Last seen: " + DateUtil.formatDateDiff(lastLog));
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
2019-08-05 16:25:55 +02:00
|
|
|
|
|
|
|
user.reset();
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
2019-08-05 16:25:55 +02:00
|
|
|
sender.sendMessage(tl("cleaned"));
|
2015-04-15 06:06:16 +02:00
|
|
|
});
|
2021-06-18 17:24:43 +02:00
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2021-06-18 17:24:43 +02:00
|
|
|
private void runHomes(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
|
|
|
if (args.length < 2) {
|
|
|
|
sender.sendMessage("This sub-command provides a utility to mass-delete homes based on user options:");
|
|
|
|
sender.sendMessage("Use \"fix\" to delete all homes inside non-existent or unloaded worlds.");
|
|
|
|
sender.sendMessage("Use \"delete\" to delete all existing homes.");
|
|
|
|
sender.sendMessage("Use \"delete <worldname>\" to delete all homes inside a specific world.");
|
|
|
|
throw new Exception(HOMES_USAGE);
|
|
|
|
}
|
|
|
|
|
|
|
|
final UserMap userMap = ess.getUserMap();
|
|
|
|
switch (args[1]) {
|
|
|
|
case "fix":
|
|
|
|
sender.sendMessage(tl("fixingHomes"));
|
|
|
|
ess.runTaskAsynchronously(() -> {
|
|
|
|
for (final UUID u : userMap.getAllUniqueUsers()) {
|
|
|
|
final User user = ess.getUserMap().getUser(u);
|
|
|
|
if (user == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for (String homeName : user.getHomes()) {
|
|
|
|
try {
|
|
|
|
if (user.getHome(homeName) == null) {
|
|
|
|
user.delHome(homeName);
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
ess.getLogger().info("Unable to delete home " + homeName + " for " + user.getName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sender.sendMessage(tl("fixedHomes"));
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case "delete":
|
|
|
|
final boolean filterByWorld = args.length >= 3;
|
|
|
|
if (filterByWorld && server.getWorld(args[2]) == null) {
|
|
|
|
throw new Exception(tl("invalidWorld"));
|
|
|
|
}
|
|
|
|
sender.sendMessage(filterByWorld ? tl("deletingHomesWorld", args[2]) : tl("deletingHomes"));
|
|
|
|
ess.runTaskAsynchronously(() -> {
|
|
|
|
for (final UUID u : userMap.getAllUniqueUsers()) {
|
|
|
|
final User user = ess.getUserMap().getUser(u);
|
|
|
|
if (user == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for (String homeName : user.getHomes()) {
|
|
|
|
try {
|
|
|
|
final Location home = user.getHome(homeName);
|
|
|
|
if (!filterByWorld || (home != null && home.getWorld() != null && home.getWorld().getName().equals(args[2]))) {
|
|
|
|
user.delHome(homeName);
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
ess.getLogger().info("Unable to delete home " + homeName + " for " + user.getName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sender.sendMessage(filterByWorld ? tl("deletedHomesWorld", args[2]) : tl("deletedHomes"));
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new Exception(HOMES_USAGE);
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// 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.");
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
final Boolean ignoreUFCache = args.length > 2 && args[1].toLowerCase(Locale.ENGLISH).contains("ignore");
|
2015-04-15 06:06:16 +02:00
|
|
|
EssentialsUpgrade.uuidFileConvert(ess, ignoreUFCache);
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
sender.sendMessage("UUID conversion complete. Check your server log for more information.");
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// Looks up various UUIDs for a user.
|
|
|
|
private void runUUIDTest(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (args.length < 2) {
|
|
|
|
throw new Exception("/<command> uuidtest <name>");
|
|
|
|
}
|
2020-10-03 19:46:05 +02:00
|
|
|
final String name = args[1];
|
2015-04-15 06:06:16 +02:00
|
|
|
sender.sendMessage("Looking up UUID for " + name);
|
|
|
|
|
|
|
|
UUID onlineUUID = null;
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
for (final Player player : ess.getOnlinePlayers()) {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (player.getName().equalsIgnoreCase(name)) {
|
|
|
|
onlineUUID = player.getUniqueId();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
final UUID essUUID = ess.getUserMap().getUser(name).getConfigUUID();
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
final org.bukkit.OfflinePlayer player = ess.getServer().getOfflinePlayer(name);
|
|
|
|
final UUID bukkituuid = player.getUniqueId();
|
2015-04-15 06:06:16 +02:00
|
|
|
sender.sendMessage("Bukkit Lookup: " + bukkituuid.toString());
|
|
|
|
|
|
|
|
if (onlineUUID != null && onlineUUID != bukkituuid) {
|
|
|
|
sender.sendMessage("Online player: " + onlineUUID.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (essUUID != null && essUUID != bukkituuid) {
|
|
|
|
sender.sendMessage("Essentials config: " + essUUID.toString());
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
final UUID npcuuid = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
2015-04-15 06:06:16 +02:00
|
|
|
sender.sendMessage("NPC UUID: " + npcuuid.toString());
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
final UUID offlineuuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8));
|
2015-04-15 06:06:16 +02:00
|
|
|
sender.sendMessage("Offline Mode UUID: " + offlineuuid.toString());
|
|
|
|
}
|
2017-06-11 02:17:43 +02:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
// Displays versions of EssentialsX and related plugins.
|
|
|
|
private void runVersion(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
2018-03-07 04:25:51 +01:00
|
|
|
if (sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.version")) return;
|
|
|
|
|
2020-02-10 10:05:32 +01:00
|
|
|
boolean isMismatched = false;
|
|
|
|
boolean isVaultInstalled = false;
|
|
|
|
boolean isUnsupported = false;
|
2020-10-19 22:26:38 +02:00
|
|
|
final VersionUtil.SupportStatus supportStatus = VersionUtil.getServerSupportStatus();
|
2020-02-10 10:05:32 +01:00
|
|
|
final PluginManager pm = server.getPluginManager();
|
|
|
|
final String essVer = pm.getPlugin("Essentials").getDescription().getVersion();
|
|
|
|
|
2020-10-19 22:26:38 +02:00
|
|
|
final String serverMessageKey;
|
|
|
|
if (supportStatus.isSupported()) {
|
|
|
|
serverMessageKey = "versionOutputFine";
|
|
|
|
} else if (supportStatus == VersionUtil.SupportStatus.UNSTABLE) {
|
|
|
|
serverMessageKey = "versionOutputUnsupported";
|
|
|
|
} else {
|
|
|
|
serverMessageKey = "versionOutputWarn";
|
|
|
|
}
|
|
|
|
|
|
|
|
sender.sendMessage(tl(serverMessageKey, "Server", server.getBukkitVersion() + " " + server.getVersion()));
|
2021-05-14 18:01:50 +02:00
|
|
|
sender.sendMessage(tl(serverMessageKey, "Brand", server.getName()));
|
2020-02-10 10:05:32 +01:00
|
|
|
sender.sendMessage(tl("versionOutputFine", "EssentialsX", essVer));
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
for (final Plugin plugin : pm.getPlugins()) {
|
2020-02-10 10:05:32 +01:00
|
|
|
final PluginDescriptionFile desc = plugin.getDescription();
|
|
|
|
String name = desc.getName();
|
2020-10-03 19:46:05 +02:00
|
|
|
final String version = desc.getVersion();
|
2020-02-10 10:05:32 +01:00
|
|
|
|
|
|
|
if (name.startsWith("Essentials") && !name.equalsIgnoreCase("Essentials")) {
|
|
|
|
if (officialPlugins.contains(name)) {
|
|
|
|
name = name.replace("Essentials", "EssentialsX");
|
|
|
|
|
|
|
|
if (!version.equalsIgnoreCase(essVer)) {
|
|
|
|
isMismatched = true;
|
|
|
|
sender.sendMessage(tl("versionOutputWarn", name, version));
|
|
|
|
} else {
|
|
|
|
sender.sendMessage(tl("versionOutputFine", name, version));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
sender.sendMessage(tl("versionOutputUnsupported", name, version));
|
|
|
|
isUnsupported = true;
|
|
|
|
}
|
|
|
|
}
|
2018-03-07 04:25:51 +01:00
|
|
|
|
2020-02-10 10:05:32 +01:00
|
|
|
if (versionPlugins.contains(name)) {
|
|
|
|
if (warnPlugins.contains(name)) {
|
|
|
|
sender.sendMessage(tl("versionOutputUnsupported", name, version));
|
|
|
|
isUnsupported = true;
|
|
|
|
} else {
|
|
|
|
sender.sendMessage(tl("versionOutputFine", name, version));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (name.equals("Vault")) isVaultInstalled = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isMismatched) {
|
|
|
|
sender.sendMessage(tl("versionMismatchAll"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isVaultInstalled) {
|
|
|
|
sender.sendMessage(tl("versionOutputVaultMissing"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isUnsupported) {
|
|
|
|
sender.sendMessage(tl("versionOutputUnsupportedPlugins"));
|
|
|
|
}
|
2018-12-06 18:41:32 +01:00
|
|
|
|
2020-10-19 22:26:38 +02:00
|
|
|
switch (supportStatus) {
|
2021-01-19 13:40:05 +01:00
|
|
|
case NMS_CLEANROOM:
|
2021-05-14 18:01:50 +02:00
|
|
|
sender.sendMessage(ChatColor.DARK_RED + tl("serverUnsupportedCleanroom"));
|
2021-01-19 13:40:05 +01:00
|
|
|
break;
|
|
|
|
case DANGEROUS_FORK:
|
2021-05-14 18:01:50 +02:00
|
|
|
sender.sendMessage(ChatColor.DARK_RED + tl("serverUnsupportedDangerous"));
|
2021-01-19 13:40:05 +01:00
|
|
|
break;
|
2020-10-19 22:26:38 +02:00
|
|
|
case UNSTABLE:
|
2021-05-14 18:01:50 +02:00
|
|
|
sender.sendMessage(ChatColor.DARK_RED + tl("serverUnsupportedMods"));
|
2020-10-19 22:26:38 +02:00
|
|
|
break;
|
|
|
|
case OUTDATED:
|
2021-05-14 18:01:50 +02:00
|
|
|
sender.sendMessage(ChatColor.RED + tl("serverUnsupported"));
|
2020-10-19 22:26:38 +02:00
|
|
|
break;
|
|
|
|
case LIMITED:
|
2021-05-14 18:01:50 +02:00
|
|
|
sender.sendMessage(ChatColor.RED + tl("serverUnsupportedLimitedApi"));
|
2020-10-19 22:26:38 +02:00
|
|
|
break;
|
2018-03-07 04:25:51 +01:00
|
|
|
}
|
2021-01-19 13:40:05 +01:00
|
|
|
if (VersionUtil.getSupportStatusClass() != null) {
|
2021-05-14 18:01:50 +02:00
|
|
|
sender.sendMessage(ChatColor.RED + tl("serverUnsupportedClass", VersionUtil.getSupportStatusClass()));
|
2021-01-19 13:40:05 +01:00
|
|
|
}
|
2021-03-06 17:29:42 +01:00
|
|
|
|
|
|
|
sender.sendMessage(tl("versionFetching"));
|
|
|
|
ess.runTaskAsynchronously(() -> {
|
|
|
|
for (String str : ess.getUpdateChecker().getVersionMessages(true, true)) {
|
|
|
|
sender.sendMessage(str);
|
|
|
|
}
|
|
|
|
});
|
2018-03-07 04:25:51 +01:00
|
|
|
}
|
|
|
|
|
2017-06-11 02:17:43 +02:00
|
|
|
@Override
|
|
|
|
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
|
|
|
if (args.length == 1) {
|
2020-10-03 19:46:05 +02:00
|
|
|
final List<String> options = Lists.newArrayList();
|
2019-08-05 16:25:55 +02:00
|
|
|
options.add("reload");
|
2021-06-18 17:24:43 +02:00
|
|
|
options.add("version");
|
|
|
|
options.add("commands");
|
|
|
|
options.add("debug");
|
2017-06-11 02:17:43 +02:00
|
|
|
options.add("reset");
|
|
|
|
options.add("cleanup");
|
2021-06-18 17:24:43 +02:00
|
|
|
options.add("homes");
|
2017-06-11 02:17:43 +02:00
|
|
|
//options.add("uuidconvert");
|
|
|
|
//options.add("uuidtest");
|
2019-08-05 16:25:55 +02:00
|
|
|
//options.add("nya");
|
|
|
|
//options.add("moo");
|
2017-06-11 02:17:43 +02:00
|
|
|
return options;
|
2019-08-05 16:25:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2021-06-18 17:24:43 +02:00
|
|
|
case "homes":
|
|
|
|
if (args.length == 2) {
|
|
|
|
return Lists.newArrayList("fix", "delete");
|
|
|
|
} else if (args.length == 3 && args[1].equalsIgnoreCase("delete")) {
|
|
|
|
return server.getWorlds().stream().map(World::getName).collect(Collectors.toList());
|
|
|
|
}
|
|
|
|
break;
|
2019-08-05 16:25:55 +02:00
|
|
|
case "uuidconvert":
|
|
|
|
if (args.length == 2) {
|
|
|
|
return Lists.newArrayList("ignoreUFCache");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
}
|
2020-10-03 19:46:05 +02:00
|
|
|
|
2019-08-05 16:25:55 +02:00
|
|
|
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();
|
2017-06-11 02:17:43 +02:00
|
|
|
}
|
2019-08-05 16:25:55 +02:00
|
|
|
if (note == null || note.isEmpty()) {
|
|
|
|
return;
|
2017-06-11 02:17:43 +02:00
|
|
|
}
|
2019-08-05 16:25:55 +02:00
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
for (final Player onlinePlayer : players.get()) {
|
2019-08-05 16:25:55 +02:00
|
|
|
onlinePlayer.playSound(onlinePlayer.getLocation(), sound, 1, noteMap.get(note));
|
2017-06-11 02:17:43 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-03-19 23:39:51 +01:00
|
|
|
}
|