PageRenderTime 4070ms CodeModel.GetById 37ms RepoModel.GetById 11ms app.codeStats 0ms

/src/main/java/org/spoutcraft/launcher/UpdateThread.java

https://bitbucket.org/dotblank/westeroscraftlauncher
Java | 637 lines | 499 code | 70 blank | 68 comment | 125 complexity | e596938d8ed0074e497b079f5ec7ba20 MD5 | raw file
  1. /*
  2. * This file is part of Westeroscraft Launcher.
  3. *
  4. * Copyright (c) 2011 Spout LLC <http://www.spout.org/>
  5. * Westeroscraft Launcher is licensed under the Spout License Version 1.
  6. *
  7. * Westeroscraft Launcher is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * In addition, 180 days after any changes are published, you can use the
  13. * software, incorporating those changes, under the terms of the MIT license,
  14. * as described in the Spout License Version 1.
  15. *
  16. * Westeroscraft Launcher is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public License,
  22. * the MIT license and the Spout License Version 1 along with this program.
  23. * If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
  24. * License and see <http://spout.in/licensev1> for the full license,
  25. * including the MIT license.
  26. */
  27. /*
  28. * This file is part of Spoutcraft Launcher.
  29. *
  30. * Copyright (c) 2011 Spout LLC <http://www.spout.org/>
  31. * Spoutcraft Launcher is licensed under the Spout License Version 1.
  32. *
  33. * Spoutcraft Launcher is free software: you can redistribute it and/or modify
  34. * it under the terms of the GNU Lesser General Public License as published by
  35. * the Free Software Foundation, either version 3 of the License, or
  36. * (at your option) any later version.
  37. *
  38. * In addition, 180 days after any changes are published, you can use the
  39. * software, incorporating those changes, under the terms of the MIT license,
  40. * as described in the Spout License Version 1.
  41. *
  42. * Spoutcraft Launcher is distributed in the hope that it will be useful,
  43. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  44. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  45. * GNU Lesser General Public License for more details.
  46. *
  47. * You should have received a copy of the GNU Lesser General Public License,
  48. * the MIT license and the Spout License Version 1 along with this program.
  49. * If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
  50. * License and see <http://spout.in/licensev1> for the full license,
  51. * including the MIT license.
  52. */
  53. package org.spoutcraft.launcher;
  54. import java.io.File;
  55. import java.io.IOException;
  56. import java.util.ArrayList;
  57. import java.util.Arrays;
  58. import java.util.Calendar;
  59. import java.util.HashSet;
  60. import java.util.List;
  61. import java.util.Map;
  62. import java.util.Map.Entry;
  63. import java.util.concurrent.atomic.AtomicBoolean;
  64. import java.util.concurrent.atomic.AtomicReference;
  65. import java.util.jar.JarFile;
  66. import java.util.logging.Level;
  67. import java.util.logging.Logger;
  68. import org.spoutcraft.launcher.api.Launcher;
  69. import org.spoutcraft.launcher.api.SpoutcraftDirectories;
  70. import org.spoutcraft.launcher.exceptions.RestfulAPIException;
  71. import org.spoutcraft.launcher.exceptions.UnsupportedOSException;
  72. import org.spoutcraft.launcher.launch.MinecraftClassLoader;
  73. import org.spoutcraft.launcher.launch.MinecraftLauncher;
  74. import org.spoutcraft.launcher.rest.Library;
  75. import org.spoutcraft.launcher.rest.Minecraft;
  76. import org.spoutcraft.launcher.rest.RestAPI;
  77. import org.spoutcraft.launcher.rest.Versions;
  78. import org.spoutcraft.launcher.util.Download;
  79. import org.spoutcraft.launcher.util.DownloadListener;
  80. import org.spoutcraft.launcher.util.DownloadUtils;
  81. import org.spoutcraft.launcher.util.FileUtils;
  82. import org.spoutcraft.launcher.util.MD5Utils;
  83. import org.spoutcraft.launcher.util.OperatingSystem;
  84. import org.spoutcraft.launcher.util.Utils;
  85. import org.spoutcraft.launcher.util.Download.Result;
  86. import org.spoutcraft.launcher.yml.Resources;
  87. import org.spoutcraft.launcher.yml.YAMLProcessor;
  88. public class UpdateThread extends Thread {
  89. /**
  90. * We only want to clean the old logs, temp folders once per startup
  91. */
  92. private static final AtomicBoolean cleaned = new AtomicBoolean(false);
  93. private static final int PRELOAD_CLASSES = 100;
  94. public static final String[] OLD_ASSETS = { "1.2.3", "1.2.5", "1.3.1", "1.3.2", "1.4.2", "1.4.4", "1.4.5", "1.4.6", "1.4.7", "1.5" };
  95. private final Logger logger = Logger.getLogger("launcher");
  96. private final AtomicBoolean waiting = new AtomicBoolean(false);
  97. private final AtomicBoolean valid = new AtomicBoolean(false);
  98. private final AtomicBoolean finished = new AtomicBoolean(false);
  99. private final StartupParameters params = Utils.getStartupParameters();
  100. private final DownloadListener listener = new DownloadListenerWrapper();
  101. private volatile SpoutcraftData build;
  102. private final Thread previous;
  103. public UpdateThread() {
  104. this(null);
  105. }
  106. public UpdateThread(Thread previous) {
  107. super("Update Thread");
  108. setDaemon(true);
  109. this.previous = previous;
  110. }
  111. public SpoutcraftData getBuild() {
  112. return build;
  113. }
  114. @Override
  115. public void run() {
  116. try {
  117. build = new SpoutcraftData();
  118. boolean interrupted = false;
  119. while(true) {
  120. try {
  121. if (previous != null) {
  122. previous.join();
  123. }
  124. break;
  125. } catch (InterruptedException e) {
  126. interrupted = true;
  127. }
  128. }
  129. if (!interrupted) {
  130. runTasks();
  131. }
  132. } catch (Exception e) {
  133. if (!this.isInterrupted()) {
  134. Launcher.getLoginFrame().handleException(e);
  135. }
  136. }
  137. }
  138. private void runTasks() throws IOException {
  139. while (!valid.get()) {
  140. boolean minecraftUpdate = isMinecraftUpdateAvailable(build);
  141. boolean spoutcraftUpdate = minecraftUpdate || isSpoutcraftUpdateAvailable(build);
  142. if (minecraftUpdate) {
  143. updateMinecraft(build);
  144. }
  145. if (spoutcraftUpdate) {
  146. updateSpoutcraft(build);
  147. }
  148. updateAssets();
  149. // Download assets
  150. if (cleaned.compareAndSet(false, true)) {
  151. Resources.VIP.getYAML();
  152. Resources.Special.getYAML();
  153. Versions.getMinecraftVersions();
  154. cleanLogs();
  155. cleanTemp();
  156. updateFiles();
  157. RestAPI.getCache().cleanup();
  158. }
  159. Validator validate = new Validator();
  160. if (!(params.isIgnoreMD5() || Settings.isIgnoreMD5())) {
  161. validate.run(build);
  162. valid.set(validate.isValid());
  163. } else {
  164. valid.set(true);
  165. }
  166. }
  167. MinecraftClassLoader loader;
  168. loader = MinecraftLauncher.getClassLoader(build.getLibraries());
  169. int loaded = 0;
  170. while (!waiting.get()) {
  171. int pass = loader.preloadClasses(PRELOAD_CLASSES);
  172. loaded += pass;
  173. // Less than the preload amount, so we are finished
  174. if (pass != PRELOAD_CLASSES) {
  175. break;
  176. }
  177. }
  178. logger.info("Preloaded " + loaded + " classes in advance");
  179. finished.set(true);
  180. }
  181. private void updateAssets() {
  182. YAMLProcessor assets = Resources.Assets.getYAML();
  183. if (assets != null) {
  184. updateAssets(assets.getMap(), Utils.getAssetsDirectory());
  185. }
  186. if(Settings.getUseLatestTexturepack()) {
  187. YAMLProcessor textures = Resources.Texturepacks.getYAML();
  188. if (textures != null) {
  189. updateAssets(textures.getMap(), Utils.getTexturePackDirectory());
  190. }
  191. }
  192. }
  193. @SuppressWarnings("unchecked")
  194. private void updateAssets(Map<String, Object> assets, File directory) {
  195. directory.mkdirs();
  196. for (Entry<String, Object> entry : assets.entrySet()) {
  197. String key = entry.getKey();
  198. Object value = entry.getValue();
  199. if (value instanceof Map<?, ?>) {
  200. updateAssets((Map<String, Object>)value, new File(directory, key));
  201. } else if (value instanceof String) {
  202. String url = (String)value;
  203. String name = getFileName(url);
  204. File asset = new File(directory, name);
  205. stateChanged("Verifying Asset: " + name, 0);
  206. boolean needDownload = true;
  207. if (asset.exists() && !(params.isIgnoreMD5() || Settings.isIgnoreMD5())) {
  208. String md5 = MD5Utils.getMD5(asset);
  209. Launcher.debug("Checking MD5 of " + asset.getName() + ". Expected MD5: " + key + " | Actual MD5: " + md5);
  210. needDownload = md5 == null || !md5.equals(key);
  211. } else if (asset.exists() && (params.isIgnoreMD5() || Settings.isIgnoreMD5())) {
  212. needDownload = false;
  213. }
  214. if (needDownload) {
  215. try {
  216. DownloadUtils.downloadFile(url, asset.getPath(), null, key, listener);
  217. } catch (IOException e) {
  218. logger.log(Level.SEVERE, "Failed to download asset [" + url + "]", e);
  219. }
  220. }
  221. stateChanged("Verified Asset: " + name, 100);
  222. } else {
  223. logger.warning("Unknown asset type for " + key + ". Type is " + value);
  224. }
  225. }
  226. }
  227. private String getFileName(String url) {
  228. String[] split = url.split("/");
  229. return split[split.length - 1];
  230. }
  231. private void updateFiles() {
  232. SpoutcraftDirectories dirs = new SpoutcraftDirectories();
  233. File oldConfig = new File(Utils.getWorkingDirectory(), "westeroscraft");
  234. if (oldConfig.exists() && oldConfig.isDirectory()) {
  235. moveDirectory(oldConfig, dirs.getSpoutcraftDir());
  236. FileUtils.deleteQuietly(oldConfig);
  237. }
  238. }
  239. private void moveDirectory(File dir, File newDir) {
  240. if (!dir.exists()) {
  241. dir.mkdirs();
  242. }
  243. for (File file : dir.listFiles()) {
  244. if (file.isDirectory()) {
  245. moveDirectory(file, new File(newDir, file.getName()));
  246. } else {
  247. file.renameTo(new File(newDir, file.getName()));
  248. }
  249. }
  250. }
  251. private void cleanTemp() {
  252. SpoutcraftDirectories dirs = new SpoutcraftDirectories();
  253. File binDir = dirs.getBinDir();
  254. for (File f : binDir.listFiles()) {
  255. if (f.isDirectory() && f.getName().startsWith("temp_")) {
  256. FileUtils.deleteQuietly(f);
  257. }
  258. }
  259. }
  260. private void cleanLogs() {
  261. File logDirectory = new File(Utils.getWorkingDirectory(), "logs");
  262. if (logDirectory.exists() && logDirectory.isDirectory()) {
  263. for (File log : logDirectory.listFiles()) {
  264. if (!log.getName().endsWith(".log")) {
  265. log.delete();
  266. continue;
  267. }
  268. if (!log.getName().startsWith("westeroscraft")) {
  269. log.delete();
  270. continue;
  271. }
  272. String[] split = log.getName().split("_");
  273. if (split.length != 2) {
  274. log.delete();
  275. continue;
  276. }
  277. String[] date = split[1].split("-");
  278. if (date.length != 3) {
  279. log.delete();
  280. continue;
  281. }
  282. date[2] = date[2].substring(0, date[2].length() - 4); // Trim .log extension
  283. try {
  284. int logYear = Integer.parseInt(date[0]);
  285. int logMonth = Integer.parseInt(date[1]);
  286. int logDay = Integer.parseInt(date[2]);
  287. Calendar logDate = Calendar.getInstance();
  288. // Add a month to the calendar (clear logs older than 1 month)
  289. if (logMonth < 12) {
  290. logMonth++;
  291. } else {
  292. logMonth = 1;
  293. logYear++;
  294. }
  295. logDate.set(logYear, logMonth, logDay);
  296. if (Calendar.getInstance().after(logDate)) {
  297. log.delete();
  298. }
  299. } catch (NumberFormatException ignore) {
  300. log.delete();
  301. continue;
  302. }
  303. }
  304. }
  305. }
  306. public void setWaiting(boolean waiting) {
  307. this.waiting.set(waiting);
  308. }
  309. public boolean isFinished() {
  310. return finished.get();
  311. }
  312. public boolean isValidInstall() {
  313. return valid.get();
  314. }
  315. public boolean isSpoutcraftUpdateAvailable(SpoutcraftData build) throws RestfulAPIException {
  316. if (!Utils.getWorkingDirectory().exists()) {
  317. return true;
  318. }
  319. if (!Launcher.getGameUpdater().getSpoutcraftDir().exists()) {
  320. return true;
  321. }
  322. List<Library> libraries = build.getLibraries();
  323. int steps = libraries.size() + 2;
  324. float progress = 100F;
  325. stateChanged("Checking for Westeroscraft update...", progress / steps);
  326. progress += 100F;
  327. File spoutcraft = new File(Launcher.getGameUpdater().getBinDir(), "westeroscraft.jar");
  328. if (!spoutcraft.exists()) {
  329. return true;
  330. }
  331. if (!Settings.isIgnoreMD5() && !build.getMD5().equalsIgnoreCase(MD5Utils.getMD5(spoutcraft))) {
  332. return true;
  333. }
  334. stateChanged("Checking for Westeroscraft update...", progress / steps);
  335. progress += 100F;
  336. File libDir = new File(Launcher.getGameUpdater().getBinDir(), "lib");
  337. libDir.mkdir();
  338. for (Library lib : libraries) {
  339. File libraryFile = new File(libDir, lib.name() + ".jar");
  340. if (!libraryFile.exists()) {
  341. return true;
  342. }
  343. stateChanged("Checking for Westeroscraft update...", progress / steps);
  344. progress += 100F;
  345. }
  346. return false;
  347. }
  348. public boolean isMinecraftUpdateAvailable(SpoutcraftData build) {
  349. int steps = 7;
  350. if (!Launcher.getGameUpdater().getBinDir().exists()) {
  351. return true;
  352. }
  353. stateChanged("Checking for Minecraft update...", 100F / steps);
  354. File nativesDir = new File(Launcher.getGameUpdater().getBinDir(), "natives");
  355. if (!nativesDir.exists()) {
  356. return true;
  357. }
  358. // Empty directory
  359. if (nativesDir.listFiles().length == 0) {
  360. return true;
  361. }
  362. stateChanged("Checking for Minecraft update...", 200F / steps);
  363. File minecraft = new File(Launcher.getGameUpdater().getBinDir(), "minecraft.jar");
  364. if (!minecraft.exists()) {
  365. return true;
  366. }
  367. stateChanged("Checking for Minecraft update...", 300F / steps);
  368. File lib = new File(Launcher.getGameUpdater().getBinDir(), "jinput.jar");
  369. if (!lib.exists()) {
  370. return true;
  371. }
  372. stateChanged("Checking for Minecraft update...", 400F / steps);
  373. lib = new File(Launcher.getGameUpdater().getBinDir(), "lwjgl.jar");
  374. if (!lib.exists()) {
  375. return true;
  376. }
  377. stateChanged("Checking for Minecraft update...", 500F / steps);
  378. lib = new File(Launcher.getGameUpdater().getBinDir(), "lwjgl_util.jar");
  379. if (!lib.exists()) {
  380. return true;
  381. }
  382. stateChanged("Checking for Minecraft update...", 600F / steps);
  383. String installed = Settings.getInstalledMC();
  384. stateChanged("Checking for Minecraft update...", 700F / steps);
  385. String required = build.getMinecraft().getVersion();
  386. return installed == null || !installed.equals(required);
  387. }
  388. // Searches the Minecraft libraries for the one matching the given artifact ID, returns the MD5
  389. protected static String findMd5(String artifactId, OperatingSystem platform, List<Library> libraries) {
  390. for (Library lib : libraries) {
  391. if (lib.getArtifactId().equalsIgnoreCase(artifactId)) {
  392. if (platform == null
  393. || platform.isWindows() && lib.getVersion().toLowerCase().endsWith("windows")
  394. || platform.isMac() && lib.getVersion().toLowerCase().endsWith("osx")
  395. || platform.isUnix() && lib.getVersion().toLowerCase().endsWith("linux")) {
  396. return lib.getMd5();
  397. }
  398. }
  399. }
  400. // Should never get here...
  401. throw new IllegalArgumentException("No valid library for " + artifactId + ", with platform " + platform + " was found");
  402. }
  403. public void updateMinecraft(SpoutcraftData build) throws IOException {
  404. Launcher.getGameUpdater().getBinDir().mkdir();
  405. Launcher.getGameUpdater().getBinCacheDir().mkdir();
  406. if (Launcher.getGameUpdater().getUpdateDir().exists()) {
  407. FileUtils.deleteDirectory(Launcher.getGameUpdater().getUpdateDir());
  408. }
  409. Launcher.getGameUpdater().getUpdateDir().mkdir();
  410. final Minecraft minecraft = build.getMinecraft();
  411. final String minecraftMD5 = minecraft.getMd5();
  412. final String jinputMD5 = findMd5("jinput", null, minecraft.getLibraries());
  413. final String lwjgl_utilMD5 = findMd5("lwjgl_util", null, minecraft.getLibraries());
  414. final String lwjglMD5 = findMd5("lwjgl", null, minecraft.getLibraries());
  415. // Process minecraft.jar
  416. logger.info("Minecraft Version: " + build.getMinecraft());
  417. File mcCache = new File(Launcher.getGameUpdater().getBinCacheDir(), "minecraft_" + minecraft.getVersion() + ".jar");
  418. if (!mcCache.exists() || (minecraftMD5 == null || !minecraftMD5.equals(MD5Utils.getMD5(mcCache)))) {
  419. if (Arrays.asList(OLD_ASSETS).contains(minecraft.getVersion())) {
  420. DownloadUtils.downloadFile("http://assets.minecraft.net/" + minecraft.getVersion().replaceAll("\\.", "_") + "/minecraft.jar", mcCache.getPath(), null, minecraftMD5, listener);
  421. } else {
  422. DownloadUtils.downloadFile("http://s3.amazonaws.com/Minecraft.Download/versions/" + minecraft.getVersion() + "/" + minecraft.getVersion() + ".jar", mcCache.getPath(), null, minecraftMD5, listener);
  423. }
  424. }
  425. Utils.copy(mcCache, new File(Launcher.getGameUpdater().getBinDir(), "minecraft.jar"));
  426. File nativesDir = new File(Launcher.getGameUpdater().getBinDir(), "natives");
  427. nativesDir.mkdir();
  428. stateChanged("Extracting Files...", 0);
  429. Settings.setInstalledMC(build.getMinecraft().getVersion());
  430. Settings.getYAML().save();
  431. }
  432. public void updateSpoutcraft(SpoutcraftData build) throws IOException {
  433. cleanupBinFoldersFor(build);
  434. Launcher.getGameUpdater().getUpdateDir().mkdirs();
  435. Launcher.getGameUpdater().getBinCacheDir().mkdirs();
  436. Launcher.getGameUpdater().getSpoutcraftDir().mkdirs();
  437. File cacheDir = new File(Launcher.getGameUpdater().getBinDir(), "cache");
  438. cacheDir.mkdir();
  439. // Process spoutcraft.jar
  440. logger.info("Westeroscraft Build: " + build.getBuild());
  441. File mcCache = new File(Launcher.getGameUpdater().getBinCacheDir(), "minecraft_" + build.getMinecraft().getVersion() + ".jar");
  442. File updateMC = new File(Launcher.getGameUpdater().getUpdateDir().getPath() + File.separator + "minecraft.jar");
  443. if (mcCache.exists()) {
  444. Utils.copy(mcCache, updateMC);
  445. }
  446. File spoutcraft = new File(Launcher.getGameUpdater().getBinDir(), "westeroscraft.jar");
  447. if (spoutcraft.exists()) {
  448. File spoutcraftCache;
  449. if (Integer.parseInt(build.getInstalledBuild()) > 0) {
  450. // Save our installed copy
  451. spoutcraftCache = new File(cacheDir, "westeroscraft_" + build.getInstalledBuild() + ".jar");
  452. if (!spoutcraftCache.exists()) {
  453. Utils.copy(spoutcraft, spoutcraftCache);
  454. }
  455. }
  456. spoutcraft.delete();
  457. // Check for an old copy of this build if it is already saved
  458. spoutcraftCache = new File(cacheDir, "westeroscraft_" + build.getBuild() + ".jar");
  459. if (spoutcraftCache.exists()) {
  460. Utils.copy(spoutcraftCache, spoutcraft);
  461. }
  462. }
  463. stateChanged("Looking Up Mirrors...", 0F);
  464. String url = build.getSpoutcraftURL();
  465. if (!spoutcraft.exists()) {
  466. Download download = DownloadUtils.downloadFile(url, Launcher.getGameUpdater().getUpdateDir() + File.separator + "westeroscraft.jar", null, build.getMD5(), listener);
  467. if (download.getResult() == Result.SUCCESS) {
  468. Utils.copy(download.getOutFile(), spoutcraft);
  469. }
  470. }
  471. File libDir = new File(Launcher.getGameUpdater().getBinDir(), "lib");
  472. libDir.mkdir();
  473. List<Library> allLibraries = new ArrayList<Library>();
  474. allLibraries.addAll(build.getLibraries());
  475. allLibraries.addAll(build.getMinecraft().getLibraries());
  476. for (Library lib : allLibraries) {
  477. File libraryFile = new File(libDir, lib.name() + ".jar");
  478. if (lib.getArtifactId().contains("lwjgl") || lib.getArtifactId().contains("jinput")) {
  479. if (lib.getVersion().contains("natives")) {
  480. File nativesFolder = new File(Launcher.getGameUpdater().getBinDir(), "natives");
  481. //This prevents downloading the wrong natives jar
  482. if (lib.getVersion().contains("osx") && !OperatingSystem.getOS().isMac()) {
  483. continue;
  484. } else if (lib.getVersion().contains("linux") && !OperatingSystem.getOS().isUnix()) {
  485. continue;
  486. } else if (lib.getVersion().contains("windows") && !OperatingSystem.getOS().isWindows()) {
  487. continue;
  488. }
  489. // Download natives
  490. File nativesJar = new File(Launcher.getGameUpdater().getUpdateDir(), "natives.jar");
  491. if (!nativesJar.exists() || !lib.valid(MD5Utils.getMD5(nativesJar))) {
  492. lib.download(nativesJar, listener);
  493. // Extract natives into the proper directory
  494. List<String> ignores = new ArrayList<String>();
  495. ignores.add("META-INF");
  496. File tempNatives = new File(Launcher.getGameUpdater().getUpdateDir(), "natives");
  497. Utils.extractJar(new JarFile(nativesJar), tempNatives, ignores);
  498. FileUtils.moveDirectory(tempNatives, nativesFolder);
  499. }
  500. continue;
  501. }
  502. libraryFile = new File(Launcher.getGameUpdater().getBinDir(), lib.getArtifactId() + ".jar");
  503. }
  504. if (libraryFile.exists()) {
  505. String computedMD5 = MD5Utils.getMD5(libraryFile);
  506. if (!lib.valid(computedMD5)) {
  507. logger.warning("MD5 check of " + libraryFile.getName() + " failed. Deleting and Redownloading.");
  508. libraryFile.delete();
  509. }
  510. }
  511. File cachedLibraryFile = new File(cacheDir, lib.name() + ".jar");
  512. if (cachedLibraryFile.exists()) {
  513. String computedMD5 = MD5Utils.getMD5(cachedLibraryFile);
  514. if (lib.valid(computedMD5)) {
  515. Utils.copy(cachedLibraryFile, libraryFile);
  516. }
  517. }
  518. if (!libraryFile.exists()) {
  519. lib.download(libraryFile, listener);
  520. }
  521. }
  522. }
  523. public void cleanupBinFoldersFor(SpoutcraftData build) {
  524. try {
  525. if (!Launcher.getGameUpdater().getBinDir().exists()) {
  526. return;
  527. }
  528. HashSet<String> neededBinFiles = new HashSet<String>(Arrays.asList(new String[]{"westeroscraft.jar", "minecraft.jar", "lwjgl.jar", "lwjgl_util.jar", "jinput.jar"}));
  529. for (File file : Launcher.getGameUpdater().getBinDir().listFiles()) {
  530. if (!file.isFile()) {
  531. continue;
  532. }
  533. if (neededBinFiles.contains(file.getName())) {
  534. continue;
  535. }
  536. file.delete();
  537. }
  538. } catch (Exception e) {
  539. System.err.println("Error while cleaning files: ");
  540. e.printStackTrace();
  541. }
  542. }
  543. public DownloadListener getDownloadListener() {
  544. return listener;
  545. }
  546. public void setDownloadListener(DownloadListener listener) {
  547. ((DownloadListenerWrapper)this.listener).setDownloadListener(listener);
  548. }
  549. public void stateChanged(String message, float progress) {
  550. if (listener != null) {
  551. listener.stateChanged(message, progress);
  552. }
  553. }
  554. private class DownloadListenerWrapper implements DownloadListener {
  555. private final AtomicReference<DownloadListener> wrapped = new AtomicReference<DownloadListener>(null);
  556. public void stateChanged(String fileName, float progress) {
  557. fileName = (new File(fileName)).getName();
  558. DownloadListener listener = wrapped.get();
  559. if (listener != null) {
  560. listener.stateChanged(fileName, progress);
  561. }
  562. }
  563. public void setDownloadListener(DownloadListener listener) {
  564. wrapped.set(listener);
  565. }
  566. }
  567. }