PageRenderTime 51ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/BodyshotzVG/Essentials
Java | 545 lines | 504 code | 40 blank | 1 comment | 88 complexity | 42a8df5f7ca4410c9bf2279e56ca155d MD5 | raw file
  1. package com.earth2me.essentials;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileReader;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.net.MalformedURLException;
  9. import java.net.URL;
  10. import java.text.DecimalFormat;
  11. import java.text.DecimalFormatSymbols;
  12. import java.text.MessageFormat;
  13. import java.util.Calendar;
  14. import java.util.Enumeration;
  15. import java.util.GregorianCalendar;
  16. import java.util.HashSet;
  17. import java.util.List;
  18. import java.util.Locale;
  19. import java.util.MissingResourceException;
  20. import java.util.ResourceBundle;
  21. import java.util.Set;
  22. import java.util.logging.Level;
  23. import java.util.logging.Logger;
  24. import java.util.regex.Matcher;
  25. import java.util.regex.Pattern;
  26. import org.bukkit.Location;
  27. import org.bukkit.Material;
  28. import org.bukkit.World;
  29. import org.bukkit.block.Block;
  30. public class Util
  31. {
  32. private Util()
  33. {
  34. }
  35. private final static Logger logger = Logger.getLogger("Minecraft");
  36. public static String sanitizeFileName(String name)
  37. {
  38. return name.toLowerCase().replaceAll("[^a-z0-9]", "_");
  39. }
  40. public static String formatDateDiff(long date)
  41. {
  42. Calendar c = new GregorianCalendar();
  43. c.setTimeInMillis(date);
  44. Calendar now = new GregorianCalendar();
  45. return Util.formatDateDiff(now, c);
  46. }
  47. public static String formatDateDiff(Calendar fromDate, Calendar toDate)
  48. {
  49. boolean future = false;
  50. if (toDate.equals(fromDate))
  51. {
  52. return Util.i18n("now");
  53. }
  54. if (toDate.after(fromDate))
  55. {
  56. future = true;
  57. }
  58. StringBuilder sb = new StringBuilder();
  59. int[] types = new int[]
  60. {
  61. Calendar.YEAR,
  62. Calendar.MONTH,
  63. Calendar.DAY_OF_MONTH,
  64. Calendar.HOUR_OF_DAY,
  65. Calendar.MINUTE,
  66. Calendar.SECOND
  67. };
  68. String[] names = new String[]
  69. {
  70. Util.i18n("year"),
  71. Util.i18n("years"),
  72. Util.i18n("month"),
  73. Util.i18n("months"),
  74. Util.i18n("day"),
  75. Util.i18n("days"),
  76. Util.i18n("hour"),
  77. Util.i18n("hours"),
  78. Util.i18n("minute"),
  79. Util.i18n("minutes"),
  80. Util.i18n("second"),
  81. Util.i18n("seconds")
  82. };
  83. for (int i = 0; i < types.length; i++)
  84. {
  85. int diff = dateDiff(types[i], fromDate, toDate, future);
  86. if (diff > 0)
  87. {
  88. sb.append(" ").append(diff).append(" ").append(names[i * 2 + (diff > 1 ? 1 : 0)]);
  89. }
  90. }
  91. if (sb.length() == 0)
  92. {
  93. return "now";
  94. }
  95. return sb.toString();
  96. }
  97. private static int dateDiff(int type, Calendar fromDate, Calendar toDate, boolean future)
  98. {
  99. int diff = 0;
  100. long savedDate = fromDate.getTimeInMillis();
  101. while ((future && !fromDate.after(toDate)) || (!future && !fromDate.before(toDate)))
  102. {
  103. savedDate = fromDate.getTimeInMillis();
  104. fromDate.add(type, future ? 1 : -1);
  105. diff++;
  106. }
  107. diff--;
  108. fromDate.setTimeInMillis(savedDate);
  109. return diff;
  110. }
  111. public static long parseDateDiff(String time, boolean future) throws Exception
  112. {
  113. Pattern timePattern = Pattern.compile(
  114. "(?:([0-9]+)\\s*y[a-z]*[,\\s]*)?"
  115. + "(?:([0-9]+)\\s*mo[a-z]*[,\\s]*)?"
  116. + "(?:([0-9]+)\\s*w[a-z]*[,\\s]*)?"
  117. + "(?:([0-9]+)\\s*d[a-z]*[,\\s]*)?"
  118. + "(?:([0-9]+)\\s*h[a-z]*[,\\s]*)?"
  119. + "(?:([0-9]+)\\s*m[a-z]*[,\\s]*)?"
  120. + "(?:([0-9]+)\\s*(?:s[a-z]*)?)?", Pattern.CASE_INSENSITIVE);
  121. Matcher m = timePattern.matcher(time);
  122. int years = 0;
  123. int months = 0;
  124. int weeks = 0;
  125. int days = 0;
  126. int hours = 0;
  127. int minutes = 0;
  128. int seconds = 0;
  129. boolean found = false;
  130. while (m.find())
  131. {
  132. if (m.group() == null || m.group().isEmpty())
  133. {
  134. continue;
  135. }
  136. for (int i = 0; i < m.groupCount(); i++)
  137. {
  138. if (m.group(i) != null && !m.group(i).isEmpty())
  139. {
  140. found = true;
  141. break;
  142. }
  143. }
  144. if (found)
  145. {
  146. if (m.group(1) != null && !m.group(1).isEmpty())
  147. {
  148. years = Integer.parseInt(m.group(1));
  149. }
  150. if (m.group(2) != null && !m.group(2).isEmpty())
  151. {
  152. months = Integer.parseInt(m.group(2));
  153. }
  154. if (m.group(3) != null && !m.group(3).isEmpty())
  155. {
  156. weeks = Integer.parseInt(m.group(3));
  157. }
  158. if (m.group(4) != null && !m.group(4).isEmpty())
  159. {
  160. days = Integer.parseInt(m.group(4));
  161. }
  162. if (m.group(5) != null && !m.group(5).isEmpty())
  163. {
  164. hours = Integer.parseInt(m.group(5));
  165. }
  166. if (m.group(6) != null && !m.group(6).isEmpty())
  167. {
  168. minutes = Integer.parseInt(m.group(6));
  169. }
  170. if (m.group(7) != null && !m.group(7).isEmpty())
  171. {
  172. seconds = Integer.parseInt(m.group(7));
  173. }
  174. break;
  175. }
  176. }
  177. if (!found)
  178. {
  179. throw new Exception(Util.i18n("illegalDate"));
  180. }
  181. Calendar c = new GregorianCalendar();
  182. if (years > 0)
  183. {
  184. c.add(Calendar.YEAR, years * (future ? 1 : -1));
  185. }
  186. if (months > 0)
  187. {
  188. c.add(Calendar.MONTH, months * (future ? 1 : -1));
  189. }
  190. if (weeks > 0)
  191. {
  192. c.add(Calendar.WEEK_OF_YEAR, weeks * (future ? 1 : -1));
  193. }
  194. if (days > 0)
  195. {
  196. c.add(Calendar.DAY_OF_MONTH, days * (future ? 1 : -1));
  197. }
  198. if (hours > 0)
  199. {
  200. c.add(Calendar.HOUR_OF_DAY, hours * (future ? 1 : -1));
  201. }
  202. if (minutes > 0)
  203. {
  204. c.add(Calendar.MINUTE, minutes * (future ? 1 : -1));
  205. }
  206. if (seconds > 0)
  207. {
  208. c.add(Calendar.SECOND, seconds * (future ? 1 : -1));
  209. }
  210. return c.getTimeInMillis();
  211. }
  212. // The player can stand inside these materials
  213. private static final Set<Integer> AIR_MATERIALS = new HashSet<Integer>();
  214. static {
  215. AIR_MATERIALS.add(Material.AIR.getId());
  216. AIR_MATERIALS.add(Material.SAPLING.getId());
  217. AIR_MATERIALS.add(Material.POWERED_RAIL.getId());
  218. AIR_MATERIALS.add(Material.DETECTOR_RAIL.getId());
  219. AIR_MATERIALS.add(Material.DEAD_BUSH.getId());
  220. AIR_MATERIALS.add(Material.RAILS.getId());
  221. AIR_MATERIALS.add(Material.YELLOW_FLOWER.getId());
  222. AIR_MATERIALS.add(Material.RED_ROSE.getId());
  223. AIR_MATERIALS.add(Material.RED_MUSHROOM.getId());
  224. AIR_MATERIALS.add(Material.BROWN_MUSHROOM.getId());
  225. AIR_MATERIALS.add(Material.SEEDS.getId());
  226. AIR_MATERIALS.add(Material.SIGN_POST.getId());
  227. AIR_MATERIALS.add(Material.WALL_SIGN.getId());
  228. AIR_MATERIALS.add(Material.LADDER.getId());
  229. AIR_MATERIALS.add(Material.SUGAR_CANE_BLOCK.getId());
  230. AIR_MATERIALS.add(Material.REDSTONE_WIRE.getId());
  231. AIR_MATERIALS.add(Material.REDSTONE_TORCH_OFF.getId());
  232. AIR_MATERIALS.add(Material.REDSTONE_TORCH_ON.getId());
  233. AIR_MATERIALS.add(Material.TORCH.getId());
  234. AIR_MATERIALS.add(Material.SOIL.getId());
  235. AIR_MATERIALS.add(Material.DIODE_BLOCK_OFF.getId());
  236. AIR_MATERIALS.add(Material.DIODE_BLOCK_ON.getId());
  237. AIR_MATERIALS.add(Material.TRAP_DOOR.getId());
  238. AIR_MATERIALS.add(Material.STONE_BUTTON.getId());
  239. AIR_MATERIALS.add(Material.STONE_PLATE.getId());
  240. AIR_MATERIALS.add(Material.WOOD_PLATE.getId());
  241. AIR_MATERIALS.add(Material.IRON_DOOR_BLOCK.getId());
  242. AIR_MATERIALS.add(Material.WOODEN_DOOR.getId());
  243. }
  244. public static Location getSafeDestination(final Location loc) throws Exception
  245. {
  246. if (loc == null || loc.getWorld() == null)
  247. {
  248. throw new Exception(Util.i18n("destinationNotSet"));
  249. }
  250. final World world = loc.getWorld();
  251. int x = (int)Math.round(loc.getX());
  252. int y = (int)Math.round(loc.getY());
  253. int z = (int)Math.round(loc.getZ());
  254. while (isBlockAboveAir(world, x, y, z))
  255. {
  256. y -= 1;
  257. if (y < 0)
  258. {
  259. break;
  260. }
  261. }
  262. while (isBlockUnsafe(world, x, y, z))
  263. {
  264. y += 1;
  265. if (y >= 127)
  266. {
  267. x += 1;
  268. break;
  269. }
  270. }
  271. while (isBlockUnsafe(world, x, y, z))
  272. {
  273. y -= 1;
  274. if (y <= 1)
  275. {
  276. y = 127;
  277. x += 1;
  278. if (x - 32 > loc.getBlockX())
  279. {
  280. throw new Exception(Util.i18n("holeInFloor"));
  281. }
  282. }
  283. }
  284. return new Location(world, x + 0.5D, y, z + 0.5D, loc.getYaw(), loc.getPitch());
  285. }
  286. private static boolean isBlockAboveAir(final World world, final int x, final int y, final int z)
  287. {
  288. return AIR_MATERIALS.contains(world.getBlockAt(x, y - 1, z).getType().getId());
  289. }
  290. public static boolean isBlockUnsafe(final World world, final int x, final int y, final int z)
  291. {
  292. final Block below = world.getBlockAt(x, y - 1, z);
  293. if (below.getType() == Material.LAVA || below.getType() == Material.STATIONARY_LAVA)
  294. {
  295. return true;
  296. }
  297. if (below.getType() == Material.FIRE)
  298. {
  299. return true;
  300. }
  301. if ((!AIR_MATERIALS.contains(world.getBlockAt(x, y, z).getType().getId()))
  302. || (!AIR_MATERIALS.contains(world.getBlockAt(x, y + 1, z).getType().getId())))
  303. {
  304. return true;
  305. }
  306. return isBlockAboveAir(world, x, y, z);
  307. }
  308. private static DecimalFormat df = new DecimalFormat("#0.00", DecimalFormatSymbols.getInstance(Locale.US));
  309. public static String formatCurrency(final double value, final IEssentials ess)
  310. {
  311. String str = ess.getSettings().getCurrencySymbol() + df.format(value);
  312. if (str.endsWith(".00"))
  313. {
  314. str = str.substring(0, str.length() - 3);
  315. }
  316. return str;
  317. }
  318. public static double roundDouble(final double d)
  319. {
  320. return Math.round(d * 100.0) / 100.0;
  321. }
  322. public static Locale getCurrentLocale()
  323. {
  324. return currentLocale;
  325. }
  326. private static class ConfigClassLoader extends ClassLoader
  327. {
  328. private final transient File dataFolder;
  329. private final transient ClassLoader cl;
  330. private final transient IEssentials ess;
  331. public ConfigClassLoader(final ClassLoader cl, final IEssentials ess)
  332. {
  333. this.ess = ess;
  334. this.dataFolder = ess.getDataFolder();
  335. this.cl = cl;
  336. }
  337. @Override
  338. public URL getResource(final String string)
  339. {
  340. final File file = new File(dataFolder, string);
  341. if (file.exists())
  342. {
  343. try
  344. {
  345. return file.toURI().toURL();
  346. }
  347. catch (MalformedURLException ex)
  348. {
  349. return cl.getResource(string);
  350. }
  351. }
  352. return cl.getResource(string);
  353. }
  354. @Override
  355. public synchronized void clearAssertionStatus()
  356. {
  357. cl.clearAssertionStatus();
  358. }
  359. @Override
  360. public InputStream getResourceAsStream(final String string)
  361. {
  362. final File file = new File(dataFolder, string);
  363. if (file.exists())
  364. {
  365. BufferedReader br = null;
  366. try
  367. {
  368. br = new BufferedReader(new FileReader(file));
  369. final String version = br.readLine();
  370. if (version == null || !version.equals("#version: " + ess.getDescription().getVersion()))
  371. {
  372. logger.log(Level.WARNING, String.format("Translation file %s is not updated for Essentials version. Will use default.", file));
  373. return cl.getResourceAsStream(string);
  374. }
  375. return new FileInputStream(file);
  376. }
  377. catch (IOException ex)
  378. {
  379. return cl.getResourceAsStream(string);
  380. }
  381. finally
  382. {
  383. if (br != null)
  384. {
  385. try
  386. {
  387. br.close();
  388. }
  389. catch (IOException ex)
  390. {
  391. }
  392. }
  393. }
  394. }
  395. return cl.getResourceAsStream(string);
  396. }
  397. @Override
  398. public Enumeration<URL> getResources(final String string) throws IOException
  399. {
  400. return cl.getResources(string);
  401. }
  402. @Override
  403. public Class<?> loadClass(final String string) throws ClassNotFoundException
  404. {
  405. return cl.loadClass(string);
  406. }
  407. @Override
  408. public synchronized void setClassAssertionStatus(final String string, final boolean bln)
  409. {
  410. cl.setClassAssertionStatus(string, bln);
  411. }
  412. @Override
  413. public synchronized void setDefaultAssertionStatus(final boolean bln)
  414. {
  415. cl.setDefaultAssertionStatus(bln);
  416. }
  417. @Override
  418. public synchronized void setPackageAssertionStatus(final String string, final boolean bln)
  419. {
  420. cl.setPackageAssertionStatus(string, bln);
  421. }
  422. }
  423. private static final Locale defaultLocale = Locale.getDefault();
  424. private static Locale currentLocale = defaultLocale;
  425. private static ResourceBundle bundle = ResourceBundle.getBundle("messages", defaultLocale);
  426. private static ResourceBundle defaultBundle = ResourceBundle.getBundle("messages", Locale.US);
  427. public static String i18n(String string)
  428. {
  429. try
  430. {
  431. return bundle.getString(string);
  432. }
  433. catch (MissingResourceException ex)
  434. {
  435. logger.log(Level.WARNING, String.format("Missing translation key \"%s\" in translation file %s", ex.getKey(), bundle.getLocale().toString()), ex);
  436. return defaultBundle.getString(string);
  437. }
  438. }
  439. public static String format(String string, Object... objects)
  440. {
  441. MessageFormat mf = new MessageFormat(i18n(string));
  442. return mf.format(objects);
  443. }
  444. public static void updateLocale(String loc, IEssentials ess)
  445. {
  446. if (loc == null || loc.isEmpty())
  447. {
  448. return;
  449. }
  450. String[] parts = loc.split("[_\\.]");
  451. if (parts.length == 1)
  452. {
  453. currentLocale = new Locale(parts[0]);
  454. }
  455. if (parts.length == 2)
  456. {
  457. currentLocale = new Locale(parts[0], parts[1]);
  458. }
  459. if (parts.length == 3)
  460. {
  461. currentLocale = new Locale(parts[0], parts[1], parts[2]);
  462. }
  463. logger.log(Level.INFO, String.format("Using locale %s", currentLocale.toString()));
  464. bundle = ResourceBundle.getBundle("messages", currentLocale, new ConfigClassLoader(Util.class.getClassLoader(), ess));
  465. if (!bundle.keySet().containsAll(defaultBundle.keySet()))
  466. {
  467. logger.log(Level.WARNING, String.format("Translation file %s does not contain all translation keys.", currentLocale.toString()));
  468. }
  469. }
  470. public static String joinList(Object... list)
  471. {
  472. return joinList(", ", list);
  473. }
  474. public static String joinList(String seperator, Object... list)
  475. {
  476. StringBuilder buf = new StringBuilder();
  477. for (Object each : list)
  478. {
  479. if (buf.length() > 0)
  480. {
  481. buf.append(seperator);
  482. }
  483. if(each instanceof List)
  484. {
  485. buf.append(joinList(seperator, ((List)each).toArray()));
  486. }
  487. else
  488. {
  489. try
  490. {
  491. buf.append(each.toString());
  492. }
  493. catch (Exception e)
  494. {
  495. buf.append(each.toString());
  496. }
  497. }
  498. }
  499. return buf.toString();
  500. }
  501. public static String capitalCase(String s)
  502. {
  503. return s.toUpperCase().charAt(0) + s.toLowerCase().substring(1);
  504. }
  505. }