package skinsrestorer.velocity.command; import co.aikar.commands.*; import co.aikar.commands.annotation.*; import co.aikar.commands.velocity.contexts.OnlinePlayer; import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.proxy.Player; import net.kyori.text.serializer.legacy.LegacyComponentSerializer; import skinsrestorer.shared.exception.SkinRequestException; import skinsrestorer.shared.interfaces.ISkinCommand; import skinsrestorer.shared.storage.Config; import skinsrestorer.shared.storage.CooldownStorage; import skinsrestorer.shared.storage.Locale; import skinsrestorer.shared.utils.C; import skinsrestorer.velocity.SkinsRestorer; import java.util.concurrent.TimeUnit; /** * Created by McLive on 17.02.2019. */ @SuppressWarnings("deprecation") @CommandAlias("skin") @CommandPermission("%skin") public class SkinCommand extends BaseCommand { private final SkinsRestorer plugin; public SkinCommand(SkinsRestorer plugin) { this.plugin = plugin; } @Default public void onDefault(CommandSource source) { this.onHelp(source, this.getCurrentCommandManager().generateCommandHelp()); } @Default @CommandPermission("%skinSet") @Description("%helpSkinSet") @Syntax("<skin/url>") public void onSkinSetShort(Player p, @Single String skin) { this.onSkinSetOther(p, new OnlinePlayer(p), skin); } @HelpCommand public void onHelp(CommandSource commandSource, CommandHelp help) { if (Config.USE_OLD_SKIN_HELP) sendHelp(commandSource); else help.showHelp(); } @Subcommand("clear") @CommandPermission("%skinClear") @Description("%helpSkinClear") public void onSkinClear(Player p) { this.onSkinClearOther(p, new OnlinePlayer(p)); } @Subcommand("clear") @CommandPermission("%skinClearOther") @CommandCompletion("@players") @Description("%helpSkinClearOther") public void onSkinClearOther(CommandSource source, OnlinePlayer target) { plugin.getService().execute(() -> { Player p = target.getPlayer(); String skin = plugin.getSkinStorage().getDefaultSkinNameIfEnabled(p.getUsername(), true); // remove users custom skin and set default skin / his skin plugin.getSkinStorage().removePlayerSkin(p.getUsername()); if (this.setSkin(source, p, skin, false)) { if (!getSenderName(source).equals(target.getPlayer().getUsername())) source.sendMessage(plugin.deserialize(Locale.SKIN_CLEAR_ISSUER.replace("%player", target.getPlayer().getUsername()))); else source.sendMessage(plugin.deserialize(Locale.SKIN_CLEAR_SUCCESS)); } }); } @Subcommand("update") @CommandPermission("%skinUpdate") @Description("%helpSkinUpdate") public void onSkinUpdate(Player p) { this.onSkinUpdateOther(p, new OnlinePlayer(p)); } @Subcommand("update") @CommandPermission("%skinUpdateOther") @CommandCompletion("@players") @Description("%helpSkinUpdateOther") public void onSkinUpdateOther(CommandSource source, OnlinePlayer target) { plugin.getService().execute(() -> { Player p = target.getPlayer(); String skin = plugin.getSkinStorage().getPlayerSkin(p.getUsername()); // User has no custom skin set, get the default skin name / his skin if (skin == null) skin = plugin.getSkinStorage().getDefaultSkinNameIfEnabled(p.getUsername(), true); if (!plugin.getSkinStorage().forceUpdateSkinData(skin)) { source.sendMessage(plugin.deserialize(Locale.ERROR_UPDATING_SKIN)); return; } if (this.setSkin(source, p, skin, false)) { if (!getSenderName(source).equals(target.getPlayer().getUsername())) source.sendMessage(plugin.deserialize(Locale.SUCCESS_UPDATING_SKIN_OTHER.replace("%player", target.getPlayer().getUsername()))); else source.sendMessage(plugin.deserialize(Locale.SUCCESS_UPDATING_SKIN)); } }); } @Subcommand("set") @CommandPermission("%skinSet") @Description("%helpSkinSet") @Syntax("<skin/url>") public void onSkinSet(Player p, String skin) { this.onSkinSetOther(p, new OnlinePlayer(p), skin); } @Subcommand("set") @CommandPermission("%skinSetOther") @CommandCompletion("@players") @Description("%helpSkinSetOther") @Syntax("<target> <skin/url>") public void onSkinSetOther(CommandSource source, OnlinePlayer target, String skin) { if (Config.PER_SKIN_PERMISSIONS && Config.USE_NEW_PERMISSIONS) { if (!source.hasPermission("skinsrestorer.skin." + skin)) { if (!getSenderName(source).equals(target.getPlayer().getUsername()) || (!source.hasPermission("skinsrestorer.ownskin") && !skin.equalsIgnoreCase(getSenderName(source)))) { source.sendMessage(LegacyComponentSerializer.legacy().deserialize(Locale.PLAYER_HAS_NO_PERMISSION_SKIN)); return; } } } plugin.getService().execute(() -> { if (this.setSkin(source, target.getPlayer(), skin)) { if (!getSenderName(source).equals(target.getPlayer().getUsername())) { source.sendMessage(LegacyComponentSerializer.legacy().deserialize(Locale.ADMIN_SET_SKIN.replace("%player", target.getPlayer().getUsername()))); } } }); } private boolean setSkin(CommandSource source, Player p, String skin) { return this.setSkin(source, p, skin, true); } // if save is false, we won't save the skin skin name // because default skin names shouldn't be saved as the users custom skin private boolean setSkin(CommandSource source, Player p, String skin, boolean save) { if (!C.validUsername(skin) && !C.validUrl(skin)) { source.sendMessage(plugin.deserialize(Locale.INVALID_PLAYER.replace("%player", skin))); return false; } if (Config.DISABLED_SKINS_ENABLED) if (!source.hasPermission("skinsrestorer.bypassdisabled")) { for (String dskin : Config.DISABLED_SKINS) if (skin.equalsIgnoreCase(dskin)) { source.sendMessage(plugin.deserialize(Locale.SKIN_DISABLED)); return false; } } if (!source.hasPermission("skinsrestorer.bypasscooldown") && CooldownStorage.hasCooldown(getSenderName(source))) { source.sendMessage(plugin.deserialize(Locale.SKIN_COOLDOWN_NEW.replace("%s", "" + CooldownStorage.getCooldown(getSenderName(source))))); return false; } CooldownStorage.resetCooldown(getSenderName(source)); CooldownStorage.setCooldown(getSenderName(source), Config.SKIN_CHANGE_COOLDOWN, TimeUnit.SECONDS); String oldSkinName = plugin.getSkinStorage().getPlayerSkin(p.getUsername()); plugin.getService().execute(() -> { if (C.validUsername(skin)) { try { plugin.getMojangAPI().getUUID(skin); if (save) { plugin.getSkinStorage().setPlayerSkin(p.getUsername(), skin); plugin.getSkinApplier().applySkin(p, p.getUsername()); } else { plugin.getSkinApplier().applySkin(p, skin); } p.sendMessage(plugin.deserialize(Locale.SKIN_CHANGE_SUCCESS)); } catch (SkinRequestException e) { source.sendMessage(plugin.deserialize(e.getReason())); // set custom skin name back to old one if there is an exception this.rollback(p, oldSkinName, save); } catch (Exception e) { e.printStackTrace(); // set custom skin name back to old one if there is an exception this.rollback(p, oldSkinName, save); } } if (C.validUrl(skin)) { if (!source.hasPermission("skinsrestorer.command.set.url") && !Config.SKINWITHOUTPERM) { source.sendMessage(plugin.deserialize(Locale.PLAYER_HAS_NO_PERMISSION_URL)); return; } try { source.sendMessage(plugin.deserialize(Locale.MS_UPDATING_SKIN)); String skinentry = " "+p.getUsername(); // so won't overwrite premium playernames if (skinentry.length() > 16) // max len of 16 char skinentry = skinentry.substring(0, 16); plugin.getSkinStorage().setSkinData(skinentry, plugin.getMineSkinAPI().genSkin(skin), Long.toString(System.currentTimeMillis() + (100L * 365 * 24 * 60 * 60 * 1000))); // "generate" and save skin for 100 years plugin.getSkinStorage().setPlayerSkin(p.getUsername(), skinentry); // set player to "whitespaced" name then reload skin plugin.getSkinApplier().applySkin(p, skinentry); p.sendMessage(plugin.deserialize(Locale.SKIN_CHANGE_SUCCESS)); } catch (SkinRequestException e) { source.sendMessage(plugin.deserialize(e.getReason())); // set custom skin name back to old one if there is an exception this.rollback(p, oldSkinName, save); } catch (Exception e) { e.printStackTrace(); // set custom skin name back to old one if there is an exception this.rollback(p, oldSkinName, save); } } }); return true; } private void rollback(Player p, String oldSkinName, boolean save) { if (save) plugin.getSkinStorage().setPlayerSkin(p.getUsername(), oldSkinName != null ? oldSkinName : p.getUsername()); } private boolean checkPerm(Player p, String perm) { return p.hasPermission(perm) || Config.SKINWITHOUTPERM; } private void sendHelp(CommandSource commandSource) { if (!Locale.SR_LINE.isEmpty()) commandSource.sendMessage(plugin.deserialize(Locale.SR_LINE)); commandSource.sendMessage(plugin.deserialize(Locale.HELP_PLAYER.replace("%ver%", plugin.getVersion()))); if (!Locale.SR_LINE.isEmpty()) commandSource.sendMessage(plugin.deserialize(Locale.SR_LINE)); } private String getSenderName(CommandSource source) { return source instanceof Player ? ((Player) source).getUsername() : "CONSOLE"; } }