    001package net.minecraft.client.texturepacks;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.io.File;
    006import java.util.ArrayList;
    007import java.util.Arrays;
    008import java.util.Collections;
    009import java.util.HashMap;
    010import java.util.Iterator;
    011import java.util.List;
    012import java.util.Map;
    013import net.minecraft.client.Minecraft;
    014import net.minecraft.client.gui.GuiProgress;
    015import net.minecraft.client.multiplayer.ServerData;
    016import net.minecraft.util.HttpUtil;
    017
    018@SideOnly(Side.CLIENT)
    019public class TexturePackList
    020{
    021    /**
    022     * An instance of TexturePackDefault for the always available builtin texture pack.
    023     */
    024    private static final ITexturePack defaultTexturePack = new TexturePackDefault();
    025
    026    /** The Minecraft instance. */
    027    private final Minecraft mc;
    028
    029    /** The directory the texture packs will be loaded from. */
    030    private final File texturePackDir;
    031
    032    /** Folder for the multi-player texturepacks. Returns File. */
    033    private final File mpTexturePackFolder;
    034
    035    /** The list of the available texture packs. */
    036    private List availableTexturePacks = new ArrayList();
    037
    038    /**
    039     * A mapping of texture IDs to TexturePackBase objects used by updateAvaliableTexturePacks() to avoid reloading
    040     * texture packs that haven't changed on disk.
    041     */
    042    private Map texturePackCache = new HashMap();
    043
    044    /** The TexturePack that will be used. */
    045    private ITexturePack selectedTexturePack;
    046
    047    /** True if a texture pack is downloading in the background. */
    048    private boolean isDownloading;
    049
    050    public TexturePackList(File par1File, Minecraft par2Minecraft)
    051    {
    052        this.mc = par2Minecraft;
    053        this.texturePackDir = new File(par1File, "texturepacks");
    054        this.mpTexturePackFolder = new File(par1File, "texturepacks-mp-cache");
    055        this.createTexturePackDirs();
    056        this.updateAvaliableTexturePacks();
    057    }
    058
    059    /**
    060     * Create the "texturepacks" and "texturepacks-mp-cache" directories if they don't already exist.
    061     */
    062    private void createTexturePackDirs()
    063    {
    064        if (!this.texturePackDir.isDirectory())
    065        {
    066            this.texturePackDir.delete();
    067            this.texturePackDir.mkdirs();
    068        }
    069
    070        if (!this.mpTexturePackFolder.isDirectory())
    071        {
    072            this.mpTexturePackFolder.delete();
    073            this.mpTexturePackFolder.mkdirs();
    074        }
    075    }
    076
    077    /**
    078     * Sets the new TexturePack to be used, returning true if it has actually changed, false if nothing changed.
    079     */
    080    public boolean setTexturePack(ITexturePack par1ITexturePack)
    081    {
    082        if (par1ITexturePack == this.selectedTexturePack)
    083        {
    084            return false;
    085        }
    086        else
    087        {
    088            this.isDownloading = false;
    089            this.selectedTexturePack = par1ITexturePack;
    090            this.mc.gameSettings.skin = par1ITexturePack.getTexturePackFileName();
    091            this.mc.gameSettings.saveOptions();
    092            return true;
    093        }
    094    }
    095
    096    /**
    097     * filename must end in .zip
    098     */
    099    public void requestDownloadOfTexture(String par1Str)
    100    {
    101        String s1 = par1Str.substring(par1Str.lastIndexOf("/") + 1);
    102
    103        if (s1.contains("?"))
    104        {
    105            s1 = s1.substring(0, s1.indexOf("?"));
    106        }
    107
    108        if (s1.endsWith(".zip"))
    109        {
    110            File file1 = new File(this.mpTexturePackFolder, s1);
    111            this.downloadTexture(par1Str, file1);
    112        }
    113    }
    114
    115    private void downloadTexture(String par1Str, File par2File)
    116    {
    117        HashMap hashmap = new HashMap();
    118        GuiProgress guiprogress = new GuiProgress();
    119        hashmap.put("X-Minecraft-Username", this.mc.session.username);
    120        hashmap.put("X-Minecraft-Version", "1.5");
    121        hashmap.put("X-Minecraft-Supported-Resolutions", "16");
    122        this.isDownloading = true;
    123        this.mc.displayGuiScreen(guiprogress);
    124        HttpUtil.downloadTexturePack(par2File, par1Str, new TexturePackDownloadSuccess(this), hashmap, 10000000, guiprogress);
    125    }
    126
    127    /**
    128     * Return true if a texture pack is downloading in the background.
    129     */
    130    public boolean getIsDownloading()
    131    {
    132        return this.isDownloading;
    133    }
    134
    135    /**
    136     * Called from Minecraft.loadWorld() if getIsDownloading() returned true to prepare the downloaded texture for
    137     * usage.
    138     */
    139    public void onDownloadFinished()
    140    {
    141        this.isDownloading = false;
    142        this.updateAvaliableTexturePacks();
    143        this.mc.scheduleTexturePackRefresh();
    144    }
    145
    146    /**
    147     * check the texture packs the client has installed
    148     */
    149    public void updateAvaliableTexturePacks()
    150    {
    151        ArrayList arraylist = new ArrayList();
    152        this.selectedTexturePack = defaultTexturePack;
    153        arraylist.add(defaultTexturePack);
    154        Iterator iterator = this.getTexturePackDirContents().iterator();
    155
    156        while (iterator.hasNext())
    157        {
    158            File file1 = (File)iterator.next();
    159            String s = this.generateTexturePackID(file1);
    160
    161            if (s != null)
    162            {
    163                Object object = (ITexturePack)this.texturePackCache.get(s);
    164
    165                if (object == null)
    166                {
    167                    object = file1.isDirectory() ? new TexturePackFolder(s, file1, defaultTexturePack) : new TexturePackCustom(s, file1, defaultTexturePack);
    168                    this.texturePackCache.put(s, object);
    169                }
    170
    171                if (((ITexturePack)object).getTexturePackFileName().equals(this.mc.gameSettings.skin))
    172                {
    173                    this.selectedTexturePack = (ITexturePack)object;
    174                }
    175
    176                arraylist.add(object);
    177            }
    178        }
    179
    180        this.availableTexturePacks.removeAll(arraylist);
    181        iterator = this.availableTexturePacks.iterator();
    182
    183        while (iterator.hasNext())
    184        {
    185            ITexturePack itexturepack = (ITexturePack)iterator.next();
    186            itexturepack.deleteTexturePack(this.mc.renderEngine);
    187            this.texturePackCache.remove(itexturepack.getTexturePackID());
    188        }
    189
    190        this.availableTexturePacks = arraylist;
    191    }
    192
    193    /**
    194     * Generate an internal texture pack ID from the file/directory name, last modification time, and file size. Returns
    195     * null if the file/directory is not a texture pack.
    196     */
    197    private String generateTexturePackID(File par1File)
    198    {
    199        return par1File.isFile() && par1File.getName().toLowerCase().endsWith(".zip") ? par1File.getName() + ":" + par1File.length() + ":" + par1File.lastModified() : (par1File.isDirectory() && (new File(par1File, "pack.txt")).exists() ? par1File.getName() + ":folder:" + par1File.lastModified() : null);
    200    }
    201
    202    /**
    203     * Return a List<File> of file/directories in the texture pack directory.
    204     */
    205    private List getTexturePackDirContents()
    206    {
    207        return this.texturePackDir.exists() && this.texturePackDir.isDirectory() ? Arrays.asList(this.texturePackDir.listFiles()) : Collections.emptyList();
    208    }
    209
    210    /**
    211     * Returns a list of the available texture packs.
    212     */
    213    public List availableTexturePacks()
    214    {
    215        return Collections.unmodifiableList(this.availableTexturePacks);
    216    }
    217
    218    public ITexturePack getSelectedTexturePack()
    219    {
    220        return this.selectedTexturePack;
    221    }
    222
    223    public boolean func_77300_f()
    224    {
    225        if (!this.mc.gameSettings.serverTextures)
    226        {
    227            return false;
    228        }
    229        else
    230        {
    231            ServerData serverdata = this.mc.getServerData();
    232            return serverdata == null ? true : serverdata.func_78840_c();
    233        }
    234    }
    235
    236    public boolean getAcceptsTextures()
    237    {
    238        if (!this.mc.gameSettings.serverTextures)
    239        {
    240            return false;
    241        }
    242        else
    243        {
    244            ServerData serverdata = this.mc.getServerData();
    245            return serverdata == null ? false : serverdata.getAcceptsTextures();
    246        }
    247    }
    248
    249    static boolean func_77301_a(TexturePackList par0TexturePackList)
    250    {
    251        return par0TexturePackList.isDownloading;
    252    }
    253
    254    /**
    255     * Set the selectedTexturePack field (Inner class static accessor method).
    256     */
    257    static ITexturePack setSelectedTexturePack(TexturePackList par0TexturePackList, ITexturePack par1ITexturePack)
    258    {
    259        return par0TexturePackList.selectedTexturePack = par1ITexturePack;
    260    }
    261
    262    /**
    263     * Generate an internal texture pack ID from the file/directory name, last modification time, and file size. Returns
    264     * null if the file/directory is not a texture pack. (Inner class static accessor method).
    265     */
    266    static String generateTexturePackID(TexturePackList par0TexturePackList, File par1File)
    267    {
    268        return par0TexturePackList.generateTexturePackID(par1File);
    269    }
    270
    271    static ITexturePack func_98143_h()
    272    {
    273        return defaultTexturePack;
    274    }
    275
    276    static Minecraft getMinecraft(TexturePackList par0TexturePackList)
    277    {
    278        return par0TexturePackList.mc;
    279    }
    280}