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.equalsIgnoreCase("sound3"))
142 {
143 if (par5 != 0)
144 {
145 return;
146 }
147 }
148 else if (par5 != 1)
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 }