com.goncalomb.bukkit.nbteditor.commands.CommandBOS.java Source code

Java tutorial

Introduction

Here is the source code for com.goncalomb.bukkit.nbteditor.commands.CommandBOS.java

Source

/*
 * Copyright (C) 2013-2016 Gonalo Baltazar <me@goncalomb.com>
 *
 * This file is part of NBTEditor.
 *
 * NBTEditor is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * NBTEditor is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with NBTEditor.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.goncalomb.bukkit.nbteditor.commands;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.CommandBlock;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.util.StringUtil;

import com.goncalomb.bukkit.mylib.command.MyCommand;
import com.goncalomb.bukkit.mylib.command.MyCommandException;
import com.goncalomb.bukkit.mylib.command.MyCommandManager;
import com.goncalomb.bukkit.mylib.namemaps.EntityTypeMap;
import com.goncalomb.bukkit.mylib.utils.Utils;
import com.goncalomb.bukkit.mylib.utils.UtilsMc;
import com.goncalomb.bukkit.nbteditor.bos.BookOfSouls;
import com.goncalomb.bukkit.nbteditor.nbt.EntityNBT;
import com.goncalomb.bukkit.nbteditor.nbt.FallingBlockNBT;
import com.goncalomb.bukkit.nbteditor.nbt.MobNBT;
import com.goncalomb.bukkit.nbteditor.nbt.attributes.Attribute;
import com.goncalomb.bukkit.nbteditor.nbt.attributes.AttributeContainer;
import com.goncalomb.bukkit.nbteditor.nbt.attributes.AttributeType;
import com.goncalomb.bukkit.nbteditor.nbt.variable.NBTVariable;
import com.goncalomb.bukkit.nbteditor.nbt.variable.NBTVariableContainer;

public class CommandBOS extends MyCommand {

    public CommandBOS() {
        super("bookofsouls", "bos");
    }

    static BookOfSouls getBos(Player player) throws MyCommandException {
        return getBos(player, false);
    }

    static BookOfSouls getBos(Player player, boolean nullIfMissing) throws MyCommandException {
        ItemStack item = player.getItemInHand();
        if (BookOfSouls.isValidBook(item)) {
            BookOfSouls bos = BookOfSouls.getFromBook(item);
            if (bos != null) {
                return bos;
            }
            throw new MyCommandException("cThat Book of Souls is corrupted!");
        } else if (!nullIfMissing) {
            throw new MyCommandException("cYou must be holding a Book of Souls!");
        }
        return null;
    }

    static List<String> findBosVars(Player player, String prefix) {
        ItemStack item = player.getItemInHand();
        if (BookOfSouls.isValidBook(item)) {
            BookOfSouls bos = BookOfSouls.getFromBook(item);
            if (bos != null) {
                List<String> names = new ArrayList<String>();
                for (NBTVariableContainer container : bos.getEntityNBT().getAllVariables()) {
                    for (String name : container.getVarNames()) {
                        if (StringUtil.startsWithIgnoreCase(name, prefix)) {
                            names.add(name);
                        }
                    }
                }
                Collections.sort(names, String.CASE_INSENSITIVE_ORDER);
                return names;
            }
        }
        return null;
    }

    @Command(args = "get", type = CommandType.PLAYER_ONLY, maxargs = 1, usage = "<entity>")
    public boolean getCommand(CommandSender sender, String[] args) throws MyCommandException {
        if (args.length == 1) {
            EntityType entityType = EntityTypeMap.getByName(args[0]);
            if (entityType != null && EntityNBT.isValidType(entityType)) {
                PlayerInventory inv = CommandUtils.checkFullInventory((Player) sender);
                BookOfSouls bos = new BookOfSouls(EntityNBT.fromEntityType(entityType));
                inv.addItem(bos.getBook());
                sender.sendMessage("aEnjoy your Book of Souls.");
                if (entityType == EntityType.ENDERMAN) {
                    sender.sendMessage(ChatColor.YELLOW
                            + "(Enderman's carring block id is limited to 127 due to a minecraft bug)");
                }
                return true;
            }
            sender.sendMessage("cInvalid entity!");
        }
        sender.sendMessage(
                "7Entities: " + StringUtils.join(EntityTypeMap.getNames(EntityNBT.getValidEntityTypes()), ", "));
        return false;
    }

    @TabComplete(args = "get")
    public List<String> get_tab(CommandSender sender, String[] args) {
        return (args.length == 1
                ? Utils.getElementsWithPrefix(EntityTypeMap.getNames(EntityNBT.getValidEntityTypes()), args[0],
                        true)
                : null);
    }

    @Command(args = "getempty", type = CommandType.PLAYER_ONLY)
    public boolean getemptyCommand(CommandSender sender, String[] args) throws MyCommandException {
        CommandUtils.checkFullInventory((Player) sender).addItem(BookOfSouls.getEmpty());
        sender.sendMessage("aEnjoy your Book of Souls.");
        return true;
    }

    @Command(args = "var", type = CommandType.PLAYER_ONLY, minargs = 1, maxargs = Integer.MAX_VALUE, usage = "<variable> [value]")
    public boolean varCommand(CommandSender sender, String[] args) throws MyCommandException {
        BookOfSouls bos = getBos((Player) sender);
        NBTVariable variable = bos.getEntityNBT().getVariable(args[0]);
        if (variable != null) {
            if (args.length >= 2) {
                if (bos.getEntityNBT() instanceof FallingBlockNBT
                        && ((FallingBlockNBT) bos.getEntityNBT()).hasTileEntityData()
                        && variable.getName().equals("block")) {
                    sender.sendMessage(
                            "eThis BoS has special block data associated, you cannot change the 'block' variable.");
                    return true;
                }
                String value = UtilsMc.parseColors(StringUtils.join(args, " ", 1, args.length));
                if (variable.setValue(value, (Player) sender)) {
                    bos.saveBook();
                    sender.sendMessage("aVariable updated.");
                    return true;
                } else {
                    sender.sendMessage(MessageFormat.format("cInvalid format for variable {0}!", args[0]));
                }
            }
            sender.sendMessage(ChatColor.YELLOW + variable.getFormat());
        } else {
            sender.sendMessage(MessageFormat.format("cThat Entity doesn''t have the variable {0}!", args[0]));
        }
        return true;
    }

    @TabComplete(args = "var")
    public List<String> var_tab(CommandSender sender, String[] args) throws MyCommandException /* Never throws */ {
        if (args.length == 1) {
            return findBosVars((Player) sender, args[0]);
        } else if (args.length == 2) {
            BookOfSouls bos = getBos((Player) sender, true);
            if (bos != null) {
                NBTVariable variable = bos.getEntityNBT().getVariable(args[0]);
                if (variable != null) {
                    List<String> possibleValues = variable.getPossibleValues();
                    if (possibleValues != null) {
                        return Utils.getElementsWithPrefix(possibleValues, args[1]);
                    }
                }
            }
        }
        return null;
    }

    @Command(args = "clearvar", type = CommandType.PLAYER_ONLY, minargs = 1, usage = "<variable>")
    public boolean clearvarCommand(CommandSender sender, String[] args) throws MyCommandException {
        BookOfSouls bos = getBos((Player) sender);
        NBTVariable variable = bos.getEntityNBT().getVariable(args[0]);
        if (variable != null) {
            variable.clear();
            bos.saveBook();
            sender.sendMessage("aVariable cleared.");
        } else {
            sender.sendMessage(MessageFormat.format("cInvalid format for variable {0}!", args[0]));
        }
        return true;
    }

    @TabComplete(args = "clearvar")
    public List<String> clearvar_tab(CommandSender sender, String[] args) {
        return findBosVars((Player) sender, args[0]);
    }

    @Command(args = "riding", type = CommandType.PLAYER_ONLY)
    public boolean ridingCommand(CommandSender sender, String[] args) throws MyCommandException {
        Player player = (Player) sender;
        BookOfSouls bos = getBos(player);
        bos.openRidingInventory(player);
        return true;
    }

    @Command(args = "items", type = CommandType.PLAYER_ONLY)
    public boolean itemsCommand(CommandSender sender, String[] args) throws MyCommandException {
        Player player = (Player) sender;
        BookOfSouls bos = getBos(player);
        if (!bos.openInventory(player)) {
            player.sendMessage(
                    "cThat must be a Mob, ArmorStand, Item, ThrownPotion, AreaEffectCloud, TippedArrow, FireworkRocket, MinecartChest or MinecartHopper entity!");
        }
        return true;
    }

    @Command(args = "offers", type = CommandType.PLAYER_ONLY, maxargs = 1, usage = "[page]")
    public boolean offersCommand(CommandSender sender, String[] args) throws MyCommandException {
        Player player = (Player) sender;
        int page = 0;
        if (args.length == 1) {
            page = CommandUtils.parseInt(args[0], 9, 0);
        }
        if (!getBos(player).openOffersInventory(player, page)) {
            player.sendMessage("cThat must be a Villager entity!");
        } else {
            player.sendMessage("eEach column represents one offer.");
        }
        return true;
    }

    @Command(args = "attr add", type = CommandType.PLAYER_ONLY, maxargs = 2, usage = "<attribute> <base>")
    public boolean attr_addCommand(CommandSender sender, String[] args) throws MyCommandException {
        if (args.length == 2) {
            BookOfSouls bos = getBos((Player) sender);
            EntityNBT entityNbt = bos.getEntityNBT();
            if (!(entityNbt instanceof MobNBT)) {
                sender.sendMessage("cThat must be a Mob entity!");
                return true;
            } else {
                AttributeType attributeType = AttributeType.getByName(args[0]);
                if (attributeType == null) {
                    sender.sendMessage("cInvalid attribute!");
                } else {
                    double base;
                    try {
                        base = Double.parseDouble(args[1]);
                    } catch (NumberFormatException e) {
                        sender.sendMessage("cBase must be a number!");
                        return true;
                    }
                    AttributeContainer attributes = ((MobNBT) entityNbt).getAttributes();
                    attributes.setAttribute(new Attribute(attributeType, base));
                    ((MobNBT) entityNbt).setAttributes(attributes);
                    bos.saveBook();
                    sender.sendMessage("aEntity attribute added.");
                    return true;
                }
            }
        }
        sender.sendMessage("7Attributes: " + StringUtils.join(AttributeType.values(), ", "));
        return false;
    }

    @TabComplete(args = "attr add")
    public List<String> tab_attr_add(CommandSender sender, String[] args) {
        return (args.length == 1
                ? Utils.getElementsWithPrefixGeneric(Arrays.asList(AttributeType.values()), args[0], true)
                : null);
    }

    @Command(args = "attr del", type = CommandType.PLAYER_ONLY, maxargs = 1, usage = "<attribute>")
    public boolean attr_delCommand(CommandSender sender, String[] args) throws MyCommandException {
        if (args.length == 1) {
            BookOfSouls bos = getBos((Player) sender);
            EntityNBT entityNbt = bos.getEntityNBT();
            if (!(entityNbt instanceof MobNBT)) {
                sender.sendMessage("cThat must be a Mob entity!");
                return true;
            } else {
                AttributeType attributeType = AttributeType.getByName(args[0]);
                if (attributeType == null) {
                    sender.sendMessage("cInvalid attribute!");
                } else {
                    AttributeContainer attributes = ((MobNBT) entityNbt).getAttributes();
                    if (attributes.removeAttribute(attributeType) != null) {
                        ((MobNBT) entityNbt).setAttributes(attributes);
                        bos.saveBook();
                        sender.sendMessage("aEntity attribute removed.");
                        return true;
                    }
                    sender.sendMessage(MessageFormat.format("cThis entity does no have the attribute {0}!",
                            attributeType.toString()));
                    return true;
                }
            }
        }
        sender.sendMessage("7Attributes: " + StringUtils.join(AttributeType.values(), ", "));
        return false;
    }

    @TabComplete(args = "attr del")
    public List<String> tab_del_add(CommandSender sender, String[] args) {
        if (args.length == 1) {
            ItemStack item = ((Player) sender).getItemInHand();
            if (BookOfSouls.isValidBook(item)) {
                BookOfSouls bos = BookOfSouls.getFromBook(item);
                if (bos != null) {
                    EntityNBT entityNbt = bos.getEntityNBT();
                    if (entityNbt instanceof MobNBT) {
                        return Utils.getElementsWithPrefixGeneric(((MobNBT) entityNbt).getAttributes().types(),
                                args[0], true);
                    }
                }
            }
        }
        return null;
    }

    @Command(args = "attr delall", type = CommandType.PLAYER_ONLY)
    public boolean attr_delallCommand(CommandSender sender, String[] args) throws MyCommandException {
        BookOfSouls bos = getBos((Player) sender);
        EntityNBT entityNbt = bos.getEntityNBT();
        if (entityNbt instanceof MobNBT) {
            ((MobNBT) entityNbt).setAttributes(null);
            bos.saveBook();
            sender.sendMessage("aEntity attributes cleared.");
            return true;
        }
        sender.sendMessage("cThat must be a Mob entity!");
        return true;
    }

    @Command(args = "tocommand", type = CommandType.PLAYER_ONLY)
    public boolean tocommandCommand(CommandSender sender, String[] args) throws MyCommandException {
        BookOfSouls bos = getBos((Player) sender);
        Block block = UtilsMc.getTargetBlock((Player) sender, 5);
        if (block.getType() == Material.COMMAND) {
            EntityNBT entityNbt = bos.getEntityNBT();
            String command = "summon";
            if (!MyCommandManager.isVanillaCommand(command)) {
                sender.sendMessage(MessageFormat
                        .format("7Non-vanilla /{0} command detected, using /minecraft:{0}.", command));
                command = "minecraft:" + command;
            }
            command = "/" + command + " " + EntityTypeMap.getName(entityNbt.getEntityType()) + " ~ ~1 ~ "
                    + entityNbt.getMetadataString();
            // We spare 50 characters of space so people can change the position.
            if (command.length() > 32767 - 50) {
                sender.sendMessage("cEntity too complex!");
                return true;
            }
            CommandBlock commandBlock = (CommandBlock) block.getState();
            commandBlock.setCommand(command);
            commandBlock.update();
            sender.sendMessage("aCommand set.");
            return true;
        }
        sender.sendMessage("cNo Command Block in sight!");
        return true;
    }

    @Command(args = "refresh", type = CommandType.PLAYER_ONLY)
    public boolean refreshCommand(CommandSender sender, String[] args) throws MyCommandException {
        BookOfSouls bos = getBos((Player) sender);
        bos.saveBook(true);
        sender.sendMessage("aBook of Souls refreshed.");
        return true;
    }

}