package openblocks.common;
import static openmods.utils.CommandUtils.filterPrefixes;
import static openmods.utils.CommandUtils.fiterPlayerNames;
import static openmods.utils.CommandUtils.getPlayer;
import com.google.common.collect.Lists;
import java.io.File;
import java.util.List;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.SyntaxErrorException;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.ChunkCoordinates;
import openblocks.api.InventoryEvent.SubInventory;
import openblocks.common.PlayerInventoryStore.LoadedInventories;
import openmods.Log;
import openmods.utils.BlockUtils;
import openmods.utils.InventoryUtils;
public class CommandInventory implements ICommand {
private static final String COMMAND_RESTORE = "restore";
private static final String COMMAND_SPAWN = "spawn";
private static final String COMMAND_STORE = "store";
private static final String NAME = "ob_inventory";
private static final String ID_MAIN_INVENTORY = "main";
private static final List<String> SUB_COMMANDS = Lists.newArrayList(COMMAND_STORE, COMMAND_RESTORE, COMMAND_SPAWN);
@Override
public int compareTo(Object o) {
return NAME.compareTo(((ICommand)o).getCommandName());
}
@Override
public String getCommandName() {
return NAME;
}
@Override
public String getCommandUsage(ICommandSender icommandsender) {
return NAME + " store <player> OR " +
NAME + " restore <player> <file without 'inventory-' and '.dat'> OR " +
NAME + " spawn <file without 'inventory-' and '.dat'> [<sub_inventory OR '" + ID_MAIN_INVENTORY + "'>, [<index of item>]]";
}
@Override
@SuppressWarnings("rawtypes")
public List getCommandAliases() {
return null;
}
@Override
public void processCommand(ICommandSender sender, String[] args) {
if (args.length < 1) throw new SyntaxErrorException();
String subCommand = args[0];
if (subCommand.equalsIgnoreCase(COMMAND_RESTORE)) {
if (args.length != 3) throw new SyntaxErrorException();
String playerName = args[1];
String id = args[2];
EntityPlayerMP player = getPlayer(sender, playerName);
final boolean success;
try {
success = PlayerInventoryStore.instance.restoreInventory(player, id);
} catch (Exception e) {
Log.warn(e, "Failed to restore inventory, player %s, file %s", playerName, id);
throw new CommandException("openblocks.misc.cant_restore_player", playerName);
}
if (success) sender.addChatMessage(new ChatComponentTranslation("openblocks.misc.restored_inventory", playerName));
else throw new CommandException("openblocks.misc.cant_restore_player", playerName);
} else if (subCommand.equalsIgnoreCase(COMMAND_STORE)) {
if (args.length != 2) throw new SyntaxErrorException();
String playerName = args[1];
EntityPlayerMP player = getPlayer(sender, playerName);
try {
File result = PlayerInventoryStore.instance.storePlayerInventory(player, "command");
sender.addChatMessage(new ChatComponentTranslation(
"openblocks.misc.stored_inventory",
result.getAbsolutePath()));
} catch (Exception e) {
Log.warn(e, "Failed to store inventory, player %s, file %s", playerName);
throw new CommandException("openblocks.misc.cant_store", playerName);
}
} else if (subCommand.equalsIgnoreCase(COMMAND_SPAWN)) {
if (args.length != 2 && args.length != 3 && args.length != 4) throw new SyntaxErrorException();
final String id = args[1];
final String target = (args.length > 2)? args[2] : ID_MAIN_INVENTORY;
LoadedInventories loadedInventories = loadInventories(sender, id);
if (loadedInventories == null) throw new CommandException("openblocks.misc.cant_restore_inventory");
final List<ItemStack> toRestore;
if (ID_MAIN_INVENTORY.equals(target)) {
final IInventory inventory = loadedInventories.mainInventory;
if (inventory == null) throw new CommandException("openblocks.misc.cant_restore_inventory");
if (args.length == 4) {
final int item = getSlotId(args[3]);
final ItemStack stack = inventory.getStackInSlot(item);
if (stack == null) throw new CommandException("openblocks.misc.empty_slot");
toRestore = Lists.newArrayList(stack);
} else {
toRestore = InventoryUtils.getInventoryContents(inventory);
}
} else {
SubInventory inventory = loadedInventories.subInventories.get(target);
if (inventory == null) throw new CommandException("openblocks.misc.invalid_sub_inventory", target);
if (args.length == 4) {
final int item = getSlotId(args[3]);
final ItemStack stack = inventory.getItemStack(item);
if (stack == null) throw new CommandException("openblocks.misc.empty_slot");
toRestore = Lists.newArrayList(stack);
} else {
toRestore = Lists.newArrayList(inventory.asMap().values());
}
}
final ChunkCoordinates coords = sender.getPlayerCoordinates();
for (ItemStack stack : toRestore)
if (stack != null) BlockUtils.dropItemStackInWorld(sender.getEntityWorld(), coords.posX, coords.posY, coords.posZ, stack);
} else throw new SyntaxErrorException();
}
private static LoadedInventories loadInventories(ICommandSender sender, String id) {
try {
return PlayerInventoryStore.instance.loadInventories(sender.getEntityWorld(), id);
} catch (Exception e) {
Log.warn(e, "Failed to restore inventory, file %s", id);
throw new CommandException("openblocks.misc.cant_restore_inventory");
}
}
private static int getSlotId(String item) {
try {
return Integer.parseInt(item);
} catch (Exception t) {
throw new CommandException("openblocks.misc.invalid_index");
}
}
@Override
public boolean canCommandSenderUseCommand(ICommandSender sender) {
return sender.canCommandSenderUseCommand(4, NAME);
}
@SuppressWarnings("rawtypes")
@Override
public List addTabCompletionOptions(ICommandSender sender, String[] args) {
if (args.length == 0) return null;
if (args.length == 1) return filterPrefixes(args[0], SUB_COMMANDS);
final String subCommand = args[0];
if (subCommand.equals(COMMAND_SPAWN)) {
if (args.length == 2) return PlayerInventoryStore.instance.getMatchedDumps(sender.getEntityWorld(), args[1]);
if (args.length == 3) {
final String fileId = args[1];
try {
LoadedInventories inventories = PlayerInventoryStore.instance.loadInventories(sender.getEntityWorld(), fileId);
if (inventories == null) return null;
List<String> result = Lists.newArrayList(ID_MAIN_INVENTORY);
result.addAll(inventories.subInventories.keySet());
return filterPrefixes(args[2], result);
} catch (Exception e) {
// just ignore, don't spam
}
}
} else {
if (args.length == 2) return fiterPlayerNames(args[1]);
if (args.length == 3) {
String prefix = args[2];
if (subCommand.equalsIgnoreCase(COMMAND_RESTORE)) return PlayerInventoryStore.instance.getMatchedDumps(sender.getEntityWorld(), prefix);
}
}
return null;
}
@Override
public boolean isUsernameIndex(String[] args, int index) {
if (args.length > 1 && args[0].equals(COMMAND_SPAWN)) return false;
return index == 1;
}
}