PageRenderTime 63ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/Essentials/src/com/earth2me/essentials/EssentialsUpgrade.java

https://github.com/YellowFellow/Essentials
Java | 669 lines | 641 code | 28 blank | 0 comment | 136 complexity | f8f7193b0cbe8ff33e2bfea053621013 MD5 | raw file
  1. package com.earth2me.essentials;
  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedReader;
  4. import java.io.BufferedWriter;
  5. import java.io.File;
  6. import java.io.FileInputStream;
  7. import java.io.FileReader;
  8. import java.io.FileWriter;
  9. import java.io.IOException;
  10. import java.math.BigInteger;
  11. import java.security.DigestInputStream;
  12. import java.security.MessageDigest;
  13. import java.util.ArrayList;
  14. import java.util.HashSet;
  15. import java.util.List;
  16. import java.util.Map;
  17. import java.util.Set;
  18. import java.util.logging.Level;
  19. import java.util.logging.Logger;
  20. import org.bukkit.Bukkit;
  21. import org.bukkit.Location;
  22. import org.bukkit.Material;
  23. import org.bukkit.World;
  24. import org.bukkit.inventory.ItemStack;
  25. public class EssentialsUpgrade
  26. {
  27. private final static Logger LOGGER = Logger.getLogger("Minecraft");
  28. private final transient IEssentials ess;
  29. private final transient EssentialsConf doneFile;
  30. EssentialsUpgrade(final IEssentials essentials)
  31. {
  32. ess = essentials;
  33. if (!ess.getDataFolder().exists())
  34. {
  35. ess.getDataFolder().mkdirs();
  36. }
  37. doneFile = new EssentialsConf(new File(ess.getDataFolder(), "upgrades-done.yml"));
  38. doneFile.load();
  39. }
  40. private void moveWorthValuesToWorthYml()
  41. {
  42. if (doneFile.getBoolean("moveWorthValuesToWorthYml", false))
  43. {
  44. return;
  45. }
  46. try
  47. {
  48. final File configFile = new File(ess.getDataFolder(), "config.yml");
  49. if (!configFile.exists())
  50. {
  51. return;
  52. }
  53. final EssentialsConf conf = new EssentialsConf(configFile);
  54. conf.load();
  55. final Worth worth = new Worth(ess.getDataFolder());
  56. boolean found = false;
  57. for (Material mat : Material.values())
  58. {
  59. final int id = mat.getId();
  60. final double value = conf.getDouble("worth-" + id, Double.NaN);
  61. if (!Double.isNaN(value))
  62. {
  63. found = true;
  64. worth.setPrice(new ItemStack(mat, 1, (short)0, (byte)0), value);
  65. }
  66. }
  67. if (found)
  68. {
  69. removeLinesFromConfig(configFile, "\\s*#?\\s*worth-[0-9]+.*", "# Worth values have been moved to worth.yml");
  70. }
  71. doneFile.setProperty("moveWorthValuesToWorthYml", true);
  72. doneFile.save();
  73. }
  74. catch (Throwable e)
  75. {
  76. LOGGER.log(Level.SEVERE, Util.i18n("upgradingFilesError"), e);
  77. }
  78. }
  79. private void removeLinesFromConfig(File file, String regex, String info) throws Exception
  80. {
  81. boolean needUpdate = false;
  82. final BufferedReader bReader = new BufferedReader(new FileReader(file));
  83. final File tempFile = File.createTempFile("essentialsupgrade", ".tmp.yml", ess.getDataFolder());
  84. final BufferedWriter bWriter = new BufferedWriter(new FileWriter(tempFile));
  85. do
  86. {
  87. final String line = bReader.readLine();
  88. if (line == null)
  89. {
  90. break;
  91. }
  92. if (line.matches(regex))
  93. {
  94. if (!needUpdate && info != null)
  95. {
  96. bWriter.write(info, 0, info.length());
  97. bWriter.newLine();
  98. }
  99. needUpdate = true;
  100. }
  101. else
  102. {
  103. if (line.endsWith("\r\n"))
  104. {
  105. bWriter.write(line, 0, line.length() - 2);
  106. }
  107. else if (line.endsWith("\r") || line.endsWith("\n"))
  108. {
  109. bWriter.write(line, 0, line.length() - 1);
  110. }
  111. else
  112. {
  113. bWriter.write(line, 0, line.length());
  114. }
  115. bWriter.newLine();
  116. }
  117. }
  118. while (true);
  119. bReader.close();
  120. bWriter.close();
  121. if (needUpdate)
  122. {
  123. if (!file.renameTo(new File(file.getParentFile(), file.getName().concat("." + System.currentTimeMillis() + ".upgradebackup"))))
  124. {
  125. throw new Exception(Util.i18n("configFileMoveError"));
  126. }
  127. if (!tempFile.renameTo(file))
  128. {
  129. throw new Exception(Util.i18n("configFileRenameError"));
  130. }
  131. }
  132. else
  133. {
  134. tempFile.delete();
  135. }
  136. }
  137. private void updateUsersToNewDefaultHome()
  138. {
  139. if (doneFile.getBoolean("updateUsersToNewDefaultHome", false))
  140. {
  141. return;
  142. }
  143. final File userdataFolder = new File(ess.getDataFolder(), "userdata");
  144. if (!userdataFolder.exists() || !userdataFolder.isDirectory())
  145. {
  146. return;
  147. }
  148. final File[] userFiles = userdataFolder.listFiles();
  149. for (File file : userFiles)
  150. {
  151. if (!file.isFile() || !file.getName().endsWith(".yml"))
  152. {
  153. continue;
  154. }
  155. final EssentialsConf config = new EssentialsConf(file);
  156. try
  157. {
  158. config.load();
  159. if (config.hasProperty("home") && !config.hasProperty("home.default"))
  160. {
  161. @SuppressWarnings("unchecked")
  162. final List<Object> vals = (List<Object>)config.getProperty("home");
  163. if (vals == null)
  164. {
  165. continue;
  166. }
  167. World world = ess.getServer().getWorlds().get(0);
  168. if (vals.size() > 5)
  169. {
  170. world = ess.getServer().getWorld((String)vals.get(5));
  171. }
  172. if (world != null)
  173. {
  174. final Location loc = new Location(
  175. world,
  176. ((Number)vals.get(0)).doubleValue(),
  177. ((Number)vals.get(1)).doubleValue(),
  178. ((Number)vals.get(2)).doubleValue(),
  179. ((Number)vals.get(3)).floatValue(),
  180. ((Number)vals.get(4)).floatValue());
  181. final String worldName = world.getName().toLowerCase();
  182. if (worldName != null && !worldName.isEmpty())
  183. {
  184. config.removeProperty("home");
  185. config.setProperty("home.default", worldName);
  186. config.setProperty("home.worlds." + worldName, loc);
  187. config.save();
  188. }
  189. }
  190. }
  191. }
  192. catch (RuntimeException ex)
  193. {
  194. LOGGER.log(Level.INFO, "File: " + file.toString());
  195. throw ex;
  196. }
  197. }
  198. doneFile.setProperty("updateUsersToNewDefaultHome", true);
  199. doneFile.save();
  200. }
  201. private void updateUsersPowerToolsFormat()
  202. {
  203. if (doneFile.getBoolean("updateUsersPowerToolsFormat", false))
  204. {
  205. return;
  206. }
  207. final File userdataFolder = new File(ess.getDataFolder(), "userdata");
  208. if (!userdataFolder.exists() || !userdataFolder.isDirectory())
  209. {
  210. return;
  211. }
  212. final File[] userFiles = userdataFolder.listFiles();
  213. for (File file : userFiles)
  214. {
  215. if (!file.isFile() || !file.getName().endsWith(".yml"))
  216. {
  217. continue;
  218. }
  219. final EssentialsConf config = new EssentialsConf(file);
  220. try
  221. {
  222. config.load();
  223. if (config.hasProperty("powertools"))
  224. {
  225. @SuppressWarnings("unchecked")
  226. final Map<Integer, Object> powertools = (Map<Integer, Object>)config.getProperty("powertools");
  227. if (powertools == null)
  228. {
  229. continue;
  230. }
  231. for (Map.Entry<Integer, Object> entry : powertools.entrySet())
  232. {
  233. if (entry.getValue() instanceof String)
  234. {
  235. List<String> temp = new ArrayList<String>();
  236. temp.add((String)entry.getValue());
  237. ((Map<Integer, Object>)powertools).put(entry.getKey(), temp);
  238. }
  239. }
  240. config.save();
  241. }
  242. }
  243. catch (RuntimeException ex)
  244. {
  245. LOGGER.log(Level.INFO, "File: " + file.toString());
  246. throw ex;
  247. }
  248. }
  249. doneFile.setProperty("updateUsersPowerToolsFormat", true);
  250. doneFile.save();
  251. }
  252. private void updateUsersHomesFormat()
  253. {
  254. if (doneFile.getBoolean("updateUsersHomesFormat", false))
  255. {
  256. return;
  257. }
  258. final File userdataFolder = new File(ess.getDataFolder(), "userdata");
  259. if (!userdataFolder.exists() || !userdataFolder.isDirectory())
  260. {
  261. return;
  262. }
  263. final File[] userFiles = userdataFolder.listFiles();
  264. for (File file : userFiles)
  265. {
  266. if (!file.isFile() || !file.getName().endsWith(".yml"))
  267. {
  268. continue;
  269. }
  270. final EssentialsConf config = new EssentialsConf(file);
  271. try
  272. {
  273. config.load();
  274. if (config.hasProperty("home") && config.hasProperty("home.default"))
  275. {
  276. @SuppressWarnings("unchecked")
  277. final String defworld = (String)config.getProperty("home.default");
  278. final Location defloc = getFakeLocation(config, "home.worlds." + defworld);
  279. if (defloc != null)
  280. {
  281. config.setProperty("homes.home", defloc);
  282. }
  283. List<String> worlds = config.getKeys("home.worlds");
  284. Location loc;
  285. String worldName;
  286. if (worlds == null)
  287. {
  288. continue;
  289. }
  290. for (String world : worlds)
  291. {
  292. if (defworld.equalsIgnoreCase(world))
  293. {
  294. continue;
  295. }
  296. loc = getFakeLocation(config, "home.worlds." + world);
  297. if (loc == null)
  298. {
  299. continue;
  300. }
  301. worldName = loc.getWorld().getName().toLowerCase();
  302. if (worldName != null && !worldName.isEmpty())
  303. {
  304. config.setProperty("homes." + worldName, loc);
  305. }
  306. }
  307. config.removeProperty("home");
  308. config.save();
  309. }
  310. }
  311. catch (RuntimeException ex)
  312. {
  313. LOGGER.log(Level.INFO, "File: " + file.toString());
  314. throw ex;
  315. }
  316. }
  317. doneFile.setProperty("updateUsersHomesFormat", true);
  318. doneFile.save();
  319. }
  320. private void moveUsersDataToUserdataFolder()
  321. {
  322. final File usersFile = new File(ess.getDataFolder(), "users.yml");
  323. if (!usersFile.exists())
  324. {
  325. return;
  326. }
  327. final EssentialsConf usersConfig = new EssentialsConf(usersFile);
  328. usersConfig.load();
  329. for (String username : usersConfig.getKeys(null))
  330. {
  331. final User user = new User(new OfflinePlayer(username, ess), ess);
  332. final String nickname = usersConfig.getString(username + ".nickname");
  333. if (nickname != null && !nickname.isEmpty() && !nickname.equals(username))
  334. {
  335. user.setNickname(nickname);
  336. }
  337. final List<String> mails = usersConfig.getStringList(username + ".mail", null);
  338. if (mails != null && !mails.isEmpty())
  339. {
  340. user.setMails(mails);
  341. }
  342. if (!user.hasHome())
  343. {
  344. @SuppressWarnings("unchecked")
  345. final List<Object> vals = (List<Object>)usersConfig.getProperty(username + ".home");
  346. if (vals != null)
  347. {
  348. World world = ess.getServer().getWorlds().get(0);
  349. if (vals.size() > 5)
  350. {
  351. world = getFakeWorld((String)vals.get(5));
  352. }
  353. if (world != null)
  354. {
  355. user.setHome("home", new Location(world,
  356. ((Number)vals.get(0)).doubleValue(),
  357. ((Number)vals.get(1)).doubleValue(),
  358. ((Number)vals.get(2)).doubleValue(),
  359. ((Number)vals.get(3)).floatValue(),
  360. ((Number)vals.get(4)).floatValue()));
  361. }
  362. }
  363. }
  364. }
  365. usersFile.renameTo(new File(usersFile.getAbsolutePath() + ".old"));
  366. }
  367. private void convertWarps()
  368. {
  369. final File warpsFolder = new File(ess.getDataFolder(), "warps");
  370. if (!warpsFolder.exists())
  371. {
  372. warpsFolder.mkdirs();
  373. }
  374. final File[] listOfFiles = warpsFolder.listFiles();
  375. if (listOfFiles.length >= 1)
  376. {
  377. for (int i = 0; i < listOfFiles.length; i++)
  378. {
  379. final String filename = listOfFiles[i].getName();
  380. if (listOfFiles[i].isFile() && filename.endsWith(".dat"))
  381. {
  382. try
  383. {
  384. final BufferedReader rx = new BufferedReader(new FileReader(listOfFiles[i]));
  385. double x, y, z;
  386. float yaw, pitch;
  387. String worldName;
  388. try
  389. {
  390. if (!rx.ready())
  391. {
  392. continue;
  393. }
  394. x = Double.parseDouble(rx.readLine().trim());
  395. if (!rx.ready())
  396. {
  397. continue;
  398. }
  399. y = Double.parseDouble(rx.readLine().trim());
  400. if (!rx.ready())
  401. {
  402. continue;
  403. }
  404. z = Double.parseDouble(rx.readLine().trim());
  405. if (!rx.ready())
  406. {
  407. continue;
  408. }
  409. yaw = Float.parseFloat(rx.readLine().trim());
  410. if (!rx.ready())
  411. {
  412. continue;
  413. }
  414. pitch = Float.parseFloat(rx.readLine().trim());
  415. worldName = rx.readLine();
  416. }
  417. finally
  418. {
  419. rx.close();
  420. }
  421. World w = null;
  422. for (World world : ess.getServer().getWorlds())
  423. {
  424. if (world.getEnvironment() != World.Environment.NETHER)
  425. {
  426. w = world;
  427. break;
  428. }
  429. }
  430. if (worldName != null)
  431. {
  432. worldName = worldName.trim();
  433. World w1 = null;
  434. w1 = getFakeWorld(worldName);
  435. if (w1 != null)
  436. {
  437. w = w1;
  438. }
  439. }
  440. final Location loc = new Location(w, x, y, z, yaw, pitch);
  441. ess.getWarps().setWarp(filename.substring(0, filename.length() - 4), loc);
  442. if (!listOfFiles[i].renameTo(new File(warpsFolder, filename + ".old")))
  443. {
  444. throw new Exception(Util.format("fileRenameError", filename));
  445. }
  446. }
  447. catch (Exception ex)
  448. {
  449. LOGGER.log(Level.SEVERE, null, ex);
  450. }
  451. }
  452. }
  453. }
  454. final File warpFile = new File(ess.getDataFolder(), "warps.txt");
  455. if (warpFile.exists())
  456. {
  457. try
  458. {
  459. final BufferedReader rx = new BufferedReader(new FileReader(warpFile));
  460. try
  461. {
  462. for (String[] parts = new String[0]; rx.ready(); parts = rx.readLine().split(":"))
  463. {
  464. if (parts.length < 6)
  465. {
  466. continue;
  467. }
  468. final String name = parts[0];
  469. final double x = Double.parseDouble(parts[1].trim());
  470. final double y = Double.parseDouble(parts[2].trim());
  471. final double z = Double.parseDouble(parts[3].trim());
  472. final float yaw = Float.parseFloat(parts[4].trim());
  473. final float pitch = Float.parseFloat(parts[5].trim());
  474. if (name.isEmpty())
  475. {
  476. continue;
  477. }
  478. World w = null;
  479. for (World world : ess.getServer().getWorlds())
  480. {
  481. if (world.getEnvironment() != World.Environment.NETHER)
  482. {
  483. w = world;
  484. break;
  485. }
  486. }
  487. final Location loc = new Location(w, x, y, z, yaw, pitch);
  488. ess.getWarps().setWarp(name, loc);
  489. if (!warpFile.renameTo(new File(ess.getDataFolder(), "warps.txt.old")))
  490. {
  491. throw new Exception(Util.format("fileRenameError", "warps.txt"));
  492. }
  493. }
  494. }
  495. finally
  496. {
  497. rx.close();
  498. }
  499. }
  500. catch (Exception ex)
  501. {
  502. LOGGER.log(Level.SEVERE, null, ex);
  503. }
  504. }
  505. }
  506. private void sanitizeAllUserFilenames()
  507. {
  508. if (doneFile.getBoolean("sanitizeAllUserFilenames", false))
  509. {
  510. return;
  511. }
  512. final File usersFolder = new File(ess.getDataFolder(), "userdata");
  513. if (!usersFolder.exists())
  514. {
  515. return;
  516. }
  517. final File[] listOfFiles = usersFolder.listFiles();
  518. for (int i = 0; i < listOfFiles.length; i++)
  519. {
  520. final String filename = listOfFiles[i].getName();
  521. if (!listOfFiles[i].isFile() || !filename.endsWith(".yml"))
  522. {
  523. continue;
  524. }
  525. final String sanitizedFilename = Util.sanitizeFileName(filename.substring(0, filename.length() - 4)) + ".yml";
  526. if (sanitizedFilename.equals(filename))
  527. {
  528. continue;
  529. }
  530. final File tmpFile = new File(listOfFiles[i].getParentFile(), sanitizedFilename + ".tmp");
  531. final File newFile = new File(listOfFiles[i].getParentFile(), sanitizedFilename);
  532. if (!listOfFiles[i].renameTo(tmpFile))
  533. {
  534. LOGGER.log(Level.WARNING, Util.format("userdataMoveError", filename, sanitizedFilename));
  535. continue;
  536. }
  537. if (newFile.exists())
  538. {
  539. LOGGER.log(Level.WARNING, Util.format("duplicatedUserdata", filename, sanitizedFilename));
  540. continue;
  541. }
  542. if (!tmpFile.renameTo(newFile))
  543. {
  544. LOGGER.log(Level.WARNING, Util.format("userdataMoveBackError", sanitizedFilename, sanitizedFilename));
  545. }
  546. }
  547. doneFile.setProperty("sanitizeAllUserFilenames", true);
  548. doneFile.save();
  549. }
  550. private World getFakeWorld(final String name)
  551. {
  552. final File bukkitDirectory = ess.getDataFolder().getParentFile().getParentFile();
  553. final File worldDirectory = new File(bukkitDirectory, name);
  554. if (worldDirectory.exists() && worldDirectory.isDirectory())
  555. {
  556. return new FakeWorld(worldDirectory.getName(), World.Environment.NORMAL);
  557. }
  558. return null;
  559. }
  560. public Location getFakeLocation(EssentialsConf config, String path)
  561. {
  562. String worldName = config.getString((path != null ? path + "." : "") + "world");
  563. if (worldName == null || worldName.isEmpty())
  564. {
  565. return null;
  566. }
  567. World world = getFakeWorld(worldName);
  568. if (world == null)
  569. {
  570. return null;
  571. }
  572. return new Location(world,
  573. config.getDouble((path != null ? path + "." : "") + "x", 0),
  574. config.getDouble((path != null ? path + "." : "") + "y", 0),
  575. config.getDouble((path != null ? path + "." : "") + "z", 0),
  576. (float)config.getDouble((path != null ? path + "." : "") + "yaw", 0),
  577. (float)config.getDouble((path != null ? path + "." : "") + "pitch", 0));
  578. }
  579. private void deleteOldItemsCsv()
  580. {
  581. if (doneFile.getBoolean("deleteOldItemsCsv", false))
  582. {
  583. return;
  584. }
  585. final File file = new File(ess.getDataFolder(), "items.csv");
  586. if (file.exists())
  587. {
  588. try
  589. {
  590. final Set<BigInteger> oldconfigs = new HashSet<BigInteger>();
  591. oldconfigs.add(new BigInteger("66ec40b09ac167079f558d1099e39f10", 16)); // sep 1
  592. oldconfigs.add(new BigInteger("34284de1ead43b0bee2aae85e75c041d", 16)); // crlf
  593. oldconfigs.add(new BigInteger("c33bc9b8ee003861611bbc2f48eb6f4f", 16)); // jul 24
  594. oldconfigs.add(new BigInteger("6ff17925430735129fc2a02f830c1daa", 16)); // crlf
  595. MessageDigest digest = ManagedFile.getDigest();
  596. final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
  597. final DigestInputStream dis = new DigestInputStream(bis, digest);
  598. final byte[] buffer = new byte[1024];
  599. try
  600. {
  601. while (dis.read(buffer) != -1)
  602. {
  603. }
  604. }
  605. finally
  606. {
  607. dis.close();
  608. }
  609. BigInteger hash = new BigInteger(1, digest.digest());
  610. if (oldconfigs.contains(hash) && !file.delete())
  611. {
  612. throw new IOException("Could not delete file " + file.toString());
  613. }
  614. doneFile.setProperty("deleteOldItemsCsv", true);
  615. doneFile.save();
  616. }
  617. catch (IOException ex)
  618. {
  619. Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
  620. }
  621. }
  622. }
  623. public void beforeSettings()
  624. {
  625. if (!ess.getDataFolder().exists())
  626. {
  627. ess.getDataFolder().mkdirs();
  628. }
  629. moveWorthValuesToWorthYml();
  630. }
  631. public void afterSettings()
  632. {
  633. sanitizeAllUserFilenames();
  634. updateUsersToNewDefaultHome();
  635. moveUsersDataToUserdataFolder();
  636. convertWarps();
  637. updateUsersPowerToolsFormat();
  638. updateUsersHomesFormat();
  639. deleteOldItemsCsv();
  640. }
  641. }