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