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 }