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.1"); 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 isDownloading(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}