001 package net.minecraft.util; 002 003 import cpw.mods.fml.relauncher.Side; 004 import cpw.mods.fml.relauncher.SideOnly; 005 import java.io.DataInputStream; 006 import java.io.DataOutputStream; 007 import java.io.File; 008 import java.io.FileOutputStream; 009 import java.io.IOException; 010 import java.net.URL; 011 import java.net.URLConnection; 012 013 import javax.xml.parsers.DocumentBuilder; 014 import javax.xml.parsers.DocumentBuilderFactory; 015 import net.minecraft.client.Minecraft; 016 import org.w3c.dom.Document; 017 import org.w3c.dom.Element; 018 import org.w3c.dom.Node; 019 import org.w3c.dom.NodeList; 020 021 @SideOnly(Side.CLIENT) 022 public class ThreadDownloadResources extends Thread 023 { 024 /** The folder to store the resources in. */ 025 public File resourcesFolder; 026 027 /** A reference to the Minecraft object. */ 028 private Minecraft mc; 029 030 /** Set to true when Minecraft is closing down. */ 031 private boolean closing = false; 032 033 public ThreadDownloadResources(File par1File, Minecraft par2Minecraft) 034 { 035 this.mc = par2Minecraft; 036 this.setName("Resource download thread"); 037 this.setDaemon(true); 038 this.resourcesFolder = new File(par1File, "resources/"); 039 040 if (!this.resourcesFolder.exists() && !this.resourcesFolder.mkdirs()) 041 { 042 throw new RuntimeException("The working directory could not be created: " + this.resourcesFolder); 043 } 044 } 045 046 public void run() 047 { 048 try 049 { 050 URL var1 = new URL("http://s3.amazonaws.com/MinecraftResources/"); 051 DocumentBuilderFactory var2 = DocumentBuilderFactory.newInstance(); 052 DocumentBuilder var3 = var2.newDocumentBuilder(); 053 //Add a timeout of 60 seconds to getting the list, MC stalls without sound for some users. 054 URLConnection con = var1.openConnection(); 055 con.setConnectTimeout(60000); 056 con.setReadTimeout(60000); 057 Document var4 = var3.parse(con.getInputStream()); 058 NodeList var5 = var4.getElementsByTagName("Contents"); 059 060 for (int var6 = 0; var6 < 2; ++var6) 061 { 062 for (int var7 = 0; var7 < var5.getLength(); ++var7) 063 { 064 Node var8 = var5.item(var7); 065 066 if (var8.getNodeType() == 1) 067 { 068 Element var9 = (Element)var8; 069 String var10 = var9.getElementsByTagName("Key").item(0).getChildNodes().item(0).getNodeValue(); 070 long var11 = Long.parseLong(var9.getElementsByTagName("Size").item(0).getChildNodes().item(0).getNodeValue()); 071 072 if (var11 > 0L) 073 { 074 this.downloadAndInstallResource(var1, var10, var11, var6); 075 076 if (this.closing) 077 { 078 return; 079 } 080 } 081 } 082 } 083 } 084 } 085 catch (Exception var13) 086 { 087 this.loadResource(this.resourcesFolder, ""); 088 var13.printStackTrace(); 089 } 090 } 091 092 /** 093 * Reloads the resource folder and passes the resources to Minecraft to install. 094 */ 095 public void reloadResources() 096 { 097 this.loadResource(this.resourcesFolder, ""); 098 } 099 100 /** 101 * Loads a resource and passes it to Minecraft to install. 102 */ 103 private void loadResource(File par1File, String par2Str) 104 { 105 File[] var3 = par1File.listFiles(); 106 107 for (int var4 = 0; var4 < var3.length; ++var4) 108 { 109 if (var3[var4].isDirectory()) 110 { 111 this.loadResource(var3[var4], par2Str + var3[var4].getName() + "/"); 112 } 113 else 114 { 115 try 116 { 117 this.mc.installResource(par2Str + var3[var4].getName(), var3[var4]); 118 } 119 catch (Exception var6) 120 { 121 System.out.println("Failed to add " + par2Str + var3[var4].getName()); 122 } 123 } 124 } 125 } 126 127 /** 128 * Downloads the resource and saves it to disk then installs it. 129 */ 130 private void downloadAndInstallResource(URL par1URL, String par2Str, long par3, int par5) 131 { 132 try 133 { 134 int var6 = par2Str.indexOf("/"); 135 String var7 = par2Str.substring(0, var6); 136 137 if (var7.equalsIgnoreCase("sound3")) 138 { 139 if (par5 != 0) 140 { 141 return; 142 } 143 } 144 else if (par5 != 1) 145 { 146 return; 147 } 148 149 File var8 = new File(this.resourcesFolder, par2Str); 150 151 if (!var8.exists() || var8.length() != par3) 152 { 153 var8.getParentFile().mkdirs(); 154 String var9 = par2Str.replaceAll(" ", "%20"); 155 this.downloadResource(new URL(par1URL, var9), var8, par3); 156 157 if (this.closing) 158 { 159 return; 160 } 161 } 162 163 this.mc.installResource(par2Str, var8); 164 } 165 catch (Exception var10) 166 { 167 var10.printStackTrace(); 168 } 169 } 170 171 /** 172 * Downloads the resource and saves it to disk. 173 */ 174 private void downloadResource(URL par1URL, File par2File, long par3) throws IOException 175 { 176 byte[] var5 = new byte[4096]; 177 //Add a timeout of 60 seconds to getting the list, MC stalls without sound for some users. 178 URLConnection con = par1URL.openConnection(); 179 con.setConnectTimeout(60000); 180 con.setReadTimeout(60000); 181 DataInputStream var6 = new DataInputStream(con.getInputStream()); 182 DataOutputStream var7 = new DataOutputStream(new FileOutputStream(par2File)); 183 boolean var8 = false; 184 185 do 186 { 187 int var9; 188 189 if ((var9 = var6.read(var5)) < 0) 190 { 191 var6.close(); 192 var7.close(); 193 return; 194 } 195 196 var7.write(var5, 0, var9); 197 } 198 while (!this.closing); 199 } 200 201 /** 202 * Called when Minecraft is closing down. 203 */ 204 public void closeMinecraft() 205 { 206 this.closing = true; 207 } 208 }