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.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 File[] var4 = var3; 107 int var5 = var3.length; 108 109 for (int var6 = 0; var6 < var5; ++var6) 110 { 111 File var7 = var4[var6]; 112 113 if (var7.isDirectory()) 114 { 115 this.loadResource(var7, par2Str + var7.getName() + "/"); 116 } 117 else 118 { 119 try 120 { 121 this.mc.installResource(par2Str + var7.getName(), var7); 122 } 123 catch (Exception var9) 124 { 125 System.out.println("Failed to add " + par2Str + var7.getName()); 126 } 127 } 128 } 129 } 130 131 /** 132 * Downloads the resource and saves it to disk then installs it. 133 */ 134 private void downloadAndInstallResource(URL par1URL, String par2Str, long par3, int par5) 135 { 136 try 137 { 138 int var6 = par2Str.indexOf("/"); 139 String var7 = par2Str.substring(0, var6); 140 141 if (!var7.equals("sound") && !var7.equals("newsound")) 142 { 143 if (par5 != 1) 144 { 145 return; 146 } 147 } 148 else if (par5 != 0) 149 { 150 return; 151 } 152 153 File var8 = new File(this.resourcesFolder, par2Str); 154 155 if (!var8.exists() || var8.length() != par3) 156 { 157 var8.getParentFile().mkdirs(); 158 String var9 = par2Str.replaceAll(" ", "%20"); 159 this.downloadResource(new URL(par1URL, var9), var8, par3); 160 161 if (this.closing) 162 { 163 return; 164 } 165 } 166 167 this.mc.installResource(par2Str, var8); 168 } 169 catch (Exception var10) 170 { 171 var10.printStackTrace(); 172 } 173 } 174 175 /** 176 * Downloads the resource and saves it to disk. 177 */ 178 private void downloadResource(URL par1URL, File par2File, long par3) throws IOException 179 { 180 byte[] var5 = new byte[4096]; 181 //Add a timeout of 60 seconds to getting the list, MC stalls without sound for some users. 182 URLConnection con = par1URL.openConnection(); 183 con.setConnectTimeout(60000); 184 con.setReadTimeout(60000); 185 DataInputStream var6 = new DataInputStream(con.getInputStream()); 186 DataOutputStream var7 = new DataOutputStream(new FileOutputStream(par2File)); 187 boolean var8 = false; 188 189 do 190 { 191 int var9; 192 193 if ((var9 = var6.read(var5)) < 0) 194 { 195 var6.close(); 196 var7.close(); 197 return; 198 } 199 200 var7.write(var5, 0, var9); 201 } 202 while (!this.closing); 203 } 204 205 /** 206 * Called when Minecraft is closing down. 207 */ 208 public void closeMinecraft() 209 { 210 this.closing = true; 211 } 212 }