001    package net.minecraft.client.texturepacks;
002    
003    import cpw.mods.fml.relauncher.Side;
004    import cpw.mods.fml.relauncher.SideOnly;
005    import java.io.File;
006    import java.util.ArrayList;
007    import java.util.Arrays;
008    import java.util.Collections;
009    import java.util.HashMap;
010    import java.util.Iterator;
011    import java.util.List;
012    import java.util.Map;
013    import net.minecraft.client.Minecraft;
014    import net.minecraft.client.gui.GuiProgress;
015    import net.minecraft.client.multiplayer.ServerData;
016    import net.minecraft.util.HttpUtil;
017    
018    @SideOnly(Side.CLIENT)
019    public 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 var2 = par1Str.substring(par1Str.lastIndexOf("/") + 1);
102    
103            if (var2.contains("?"))
104            {
105                var2 = var2.substring(0, var2.indexOf("?"));
106            }
107    
108            if (var2.endsWith(".zip"))
109            {
110                File var3 = new File(this.mpTexturePackFolder, var2);
111                this.downloadTexture(par1Str, var3);
112            }
113        }
114    
115        private void downloadTexture(String par1Str, File par2File)
116        {
117            HashMap var3 = new HashMap();
118            GuiProgress var4 = new GuiProgress();
119            var3.put("X-Minecraft-Username", this.mc.session.username);
120            var3.put("X-Minecraft-Version", "1.4.7");
121            var3.put("X-Minecraft-Supported-Resolutions", "16");
122            this.isDownloading = true;
123            this.mc.displayGuiScreen(var4);
124            HttpUtil.downloadTexturePack(par2File, par1Str, new TexturePackDownloadSuccess(this), var3, 10000000, var4);
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 var1 = new ArrayList();
152            this.selectedTexturePack = defaultTexturePack;
153            var1.add(defaultTexturePack);
154            Iterator var2 = this.getTexturePackDirContents().iterator();
155    
156            while (var2.hasNext())
157            {
158                File var3 = (File)var2.next();
159                String var4 = this.generateTexturePackID(var3);
160    
161                if (var4 != null)
162                {
163                    Object var5 = (ITexturePack)this.texturePackCache.get(var4);
164    
165                    if (var5 == null)
166                    {
167                        var5 = var3.isDirectory() ? new TexturePackFolder(var4, var3) : new TexturePackCustom(var4, var3);
168                        this.texturePackCache.put(var4, var5);
169                    }
170    
171                    if (((ITexturePack)var5).getTexturePackFileName().equals(this.mc.gameSettings.skin))
172                    {
173                        this.selectedTexturePack = (ITexturePack)var5;
174                    }
175    
176                    var1.add(var5);
177                }
178            }
179    
180            this.availableTexturePacks.removeAll(var1);
181            var2 = this.availableTexturePacks.iterator();
182    
183            while (var2.hasNext())
184            {
185                ITexturePack var6 = (ITexturePack)var2.next();
186                var6.deleteTexturePack(this.mc.renderEngine);
187                this.texturePackCache.remove(var6.getTexturePackID());
188            }
189    
190            this.availableTexturePacks = var1;
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 var1 = this.mc.getServerData();
232                return var1 == null ? true : var1.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 var1 = this.mc.getServerData();
245                return var1 == null ? false : var1.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 Minecraft getMinecraft(TexturePackList par0TexturePackList)
272        {
273            return par0TexturePackList.mc;
274        }
275    }