package crazypants.enderio.teleport.anchor; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.annotation.Nonnull; import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import com.enderio.core.common.util.PlayerUtil; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import crazypants.enderio.TileEntityEio; import crazypants.enderio.api.teleport.ITravelAccessable; import crazypants.enderio.api.teleport.TravelSource; import crazypants.enderio.machine.painter.IPaintableTileEntity; import crazypants.util.UserIdent; public class TileTravelAnchor extends TileEntityEio implements ITravelAccessable, IPaintableTileEntity { private static final String KEY_SOURCE_BLOCK_ID = "sourceBlock"; private static final String KEY_SOURCE_BLOCK_META = "sourceBlockMeta"; private Block sourceBlock; private int sourceBlockMetadata; private AccessMode accessMode = AccessMode.PUBLIC; private ItemStack[] password = new ItemStack[5]; private ItemStack itemLabel; private String label; private @Nonnull UserIdent owner = UserIdent.nobody; private List<UserIdent> authorisedUsers = new ArrayList<UserIdent>(); @Override public boolean canBlockBeAccessed(EntityPlayer playerName) { if(accessMode == AccessMode.PUBLIC) { return true; } // Covers protected and private access modes return owner.equals(playerName.getGameProfile()) || authorisedUsers.contains(playerName.getGameProfile()); } @Override public void clearAuthorisedUsers() { authorisedUsers.clear(); } private boolean checkPassword(ItemStack[] pwd) { if(pwd == null || pwd.length != password.length) { return false; } for (int i = 0; i < pwd.length; i++) { ItemStack pw = password[i]; ItemStack tst = pwd[i]; if(pw == null && tst != null) { return false; } if(pw != null) { if(tst == null || !ItemStack.areItemStacksEqual(pw, tst)) { return false; } } } return true; } @Override public boolean getRequiresPassword(EntityPlayer playerName) { return getAccessMode() == AccessMode.PROTECTED && !canUiBeAccessed(playerName) && !authorisedUsers.contains(PlayerUtil.getPlayerUUID(playerName.getGameProfile().getName())); } @Override public boolean authoriseUser(EntityPlayer username, ItemStack[] password) { if(checkPassword(password)) { authorisedUsers.add(UserIdent.create(username.getGameProfile())); return true; } return false; } @Override public boolean canUiBeAccessed(EntityPlayer playerName) { return owner.equals(playerName.getGameProfile()); } @Override public boolean canSeeBlock(EntityPlayer playerName) { if(accessMode != AccessMode.PRIVATE) { return true; } return owner.equals(playerName.getGameProfile()); } @Override public AccessMode getAccessMode() { return accessMode; } @Override public void setAccessMode(AccessMode accessMode) { this.accessMode = accessMode; } @Override public ItemStack[] getPassword() { return password; } @Override public void setPassword(ItemStack[] password) { this.password = password; } @Override public ItemStack getItemLabel() { return itemLabel; } @Override public void setItemLabel(ItemStack lableIcon) { this.itemLabel = lableIcon; } @Override public String getLabel() { return label; } @Override public void setLabel(String label) { this.label = label; } @Override @Deprecated public UUID getPlacedBy() { return owner.getUUID(); } @Override public @Nonnull UserIdent getOwner() { return owner; } @Override public void setPlacedBy(EntityPlayer player) { if (player != null) { this.owner = UserIdent.create(player.getGameProfile()); } else { this.owner = UserIdent.nobody; } } @Override public boolean shouldUpdate() { return false; } @Override @SideOnly(Side.CLIENT) public double getMaxRenderDistanceSquared() { return TravelSource.getMaxDistanceSq(); } @Override public boolean shouldRenderInPass(int pass) { return pass == 1; } @Override public Block getSourceBlock() { return sourceBlock; } @Override public void setSourceBlock(Block sourceBlock) { this.sourceBlock = sourceBlock; } @Override public int getSourceBlockMetadata() { return sourceBlockMetadata; } @Override public void setSourceBlockMetadata(int sourceBlockMetadata) { this.sourceBlockMetadata = sourceBlockMetadata; } @Override protected void readCustomNBT(NBTTagCompound root) { if(root.hasKey("accessMode")) { accessMode = AccessMode.values()[root.getShort("accessMode")]; } else { //keep behavior the same for blocks placed prior to this update accessMode = AccessMode.PUBLIC; } if (root.hasKey("placedBy")) { owner = UserIdent.create(root.getString("placedBy")); } else { owner = UserIdent.readfromNbt(root, "owner"); } for (int i = 0; i < password.length; i++) { if(root.hasKey("password" + i)) { NBTTagCompound stackRoot = (NBTTagCompound) root.getTag("password" + i); password[i] = ItemStack.loadItemStackFromNBT(stackRoot); } else { password[i] = null; } } authorisedUsers.clear(); if (root.hasKey("authorisedUsers")) { String userStr = root.getString("authorisedUsers"); if(userStr != null && userStr.length() > 0) { String[] users = userStr.split(","); for (String user : users) { if(user != null) { user = user.trim(); if(user.length() > 0) { authorisedUsers.add(UserIdent.create(user)); } } } } } else { int userIdx = 0; while (UserIdent.existsInNbt(root, "authorisedUser" + userIdx)) { UserIdent.readfromNbt(root, "authorisedUser" + userIdx); userIdx++; } } if(root.hasKey("itemLabel")) { NBTTagCompound stackRoot = (NBTTagCompound) root.getTag("itemLabel"); itemLabel = ItemStack.loadItemStackFromNBT(stackRoot); } else { itemLabel = null; } String sourceBlockStr = root.getString(KEY_SOURCE_BLOCK_ID); sourceBlock = Block.getBlockFromName(sourceBlockStr); sourceBlockMetadata = root.getInteger(KEY_SOURCE_BLOCK_META); label = root.getString("label"); if(label == null || label.trim().length() == 0) { label = null; } } @Override protected void writeCustomNBT(NBTTagCompound root) { root.setShort("accessMode", (short) accessMode.ordinal()); owner.saveToNbt(root, "owner"); for (int i = 0; i < password.length; i++) { ItemStack stack = password[i]; if(stack != null) { NBTTagCompound stackRoot = new NBTTagCompound(); stack.writeToNBT(stackRoot); root.setTag("password" + i, stackRoot); } } int userIdx = 0; for (UserIdent user : authorisedUsers) { if(user != null) { user.saveToNbt(root, "authorisedUser" + userIdx); userIdx++; } } if(itemLabel != null) { NBTTagCompound labelRoot = new NBTTagCompound(); itemLabel.writeToNBT(labelRoot); root.setTag("itemLabel", labelRoot); } if(sourceBlock != null) { root.setString(KEY_SOURCE_BLOCK_ID, Block.blockRegistry.getNameForObject(sourceBlock)); } root.setInteger(KEY_SOURCE_BLOCK_META, sourceBlockMetadata); if(label != null && label.trim().length() > 0) { root.setString("label", label); } } @Override public Packet getDescriptionPacket() { NBTTagCompound tag = new NBTTagCompound(); writeCustomNBT(tag); return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, tag); } @Override public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { readCustomNBT(pkt.func_148857_g()); } }