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.5"); 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 }