diff --git a/Essentials/src/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/com/earth2me/essentials/EssentialsUpgrade.java index ffe4f5375..409250a00 100644 --- a/Essentials/src/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/com/earth2me/essentials/EssentialsUpgrade.java @@ -1,15 +1,24 @@ package com.earth2me.essentials; +import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; +import java.io.FileInputStream; import java.io.FileReader; import java.io.FileWriter; +import java.io.IOException; +import java.math.BigInteger; +import java.security.DigestInputStream; +import java.security.MessageDigest; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -280,11 +289,11 @@ public class EssentialsUpgrade { @SuppressWarnings("unchecked") final String defworld = (String)config.getProperty("home.default"); - final Location defloc = getFakeLocation(config,"home.worlds." + defworld); + final Location defloc = getFakeLocation(config, "home.worlds." + defworld); if (defloc != null) { config.setProperty("homes.home", defloc); - } + } List worlds = config.getKeys("home.worlds"); Location loc; @@ -570,6 +579,7 @@ public class EssentialsUpgrade } return null; } + public Location getFakeLocation(EssentialsConf config, String path) { String worldName = config.getString((path != null ? path + "." : "") + "world"); @@ -590,6 +600,53 @@ public class EssentialsUpgrade (float)config.getDouble((path != null ? path + "." : "") + "pitch", 0)); } + private void deleteOldItemsCsv() + { + if (doneFile.getBoolean("deleteOldItemsCsv", false)) + { + return; + } + final File file = new File(ess.getDataFolder(), "items.csv"); + if (file.exists()) + { + try + { + final Set oldconfigs = new HashSet(); + oldconfigs.add(new BigInteger("66ec40b09ac167079f558d1099e39f10", 16)); // sep 1 + oldconfigs.add(new BigInteger("34284de1ead43b0bee2aae85e75c041d", 16)); // crlf + oldconfigs.add(new BigInteger("c33bc9b8ee003861611bbc2f48eb6f4f", 16)); // jul 24 + oldconfigs.add(new BigInteger("6ff17925430735129fc2a02f830c1daa", 16)); // crlf + + MessageDigest digest = ManagedFile.getDigest(); + final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); + final DigestInputStream dis = new DigestInputStream(bis, digest); + final byte[] buffer = new byte[1024]; + try + { + while (dis.read(buffer) != -1) + { + } + } + finally + { + dis.close(); + } + + BigInteger hash = new BigInteger(1, digest.digest()); + if (oldconfigs.contains(hash) && !file.delete()) + { + throw new IOException("Could not delete file " + file.toString()); + } + doneFile.setProperty("deleteOldItemsCsv", true); + doneFile.save(); + } + catch (IOException ex) + { + Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); + } + } + } + public void beforeSettings() { if (!ess.getDataFolder().exists()) @@ -607,5 +664,6 @@ public class EssentialsUpgrade convertWarps(); updateUsersPowerToolsFormat(); updateUsersHomesFormat(); + deleteOldItemsCsv(); } } diff --git a/Essentials/src/com/earth2me/essentials/ItemDb.java b/Essentials/src/com/earth2me/essentials/ItemDb.java index 8e05b17fb..e978a312d 100644 --- a/Essentials/src/com/earth2me/essentials/ItemDb.java +++ b/Essentials/src/com/earth2me/essentials/ItemDb.java @@ -1,14 +1,8 @@ package com.earth2me.essentials; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.util.*; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; @@ -17,108 +11,45 @@ public class ItemDb implements IConf { private final transient IEssentials ess; - public ItemDb(IEssentials ess) + public ItemDb(final IEssentials ess) { this.ess = ess; + file = new ManagedFile("items.csv", ess); } - private final static Logger LOGGER = Logger.getLogger("Minecraft"); private final transient Map items = new HashMap(); private final transient Map durabilities = new HashMap(); + private final transient ManagedFile file; + @Override public void reloadConfig() { - final File file = new File(ess.getDataFolder(), "items.csv"); - - if (!file.exists()) - { - final InputStream res = ItemDb.class.getResourceAsStream("/items.csv"); - FileWriter tx = null; - try - { - tx = new FileWriter(file); - for (int i = 0; (i = res.read()) > 0;) - { - tx.write(i); - } - tx.flush(); - } - catch (IOException ex) - { - LOGGER.log(Level.SEVERE, Util.i18n("itemsCsvNotLoaded"), ex); - return; - } - finally - { - try - { - res.close(); - } - catch (Exception ex) - { - } - try - { - if (tx != null) - { - tx.close(); - } - } - catch (Exception ex) - { - } - } + final List lines = file.getLines(); + + if (lines.isEmpty()) { + return; } - BufferedReader rx = null; - try - { - rx = new BufferedReader(new FileReader(file)); - durabilities.clear(); - items.clear(); + durabilities.clear(); + items.clear(); - for (int i = 0; rx.ready(); i++) + for (String line : lines) + { + line = line.trim().toLowerCase(); + if (line.length() > 0 && line.charAt(0) == '#') { - try - { - final String line = rx.readLine().trim().toLowerCase(); - if (line.startsWith("#")) - { - continue; - } - - final String[] parts = line.split("[^a-z0-9]"); - if (parts.length < 2) - { - continue; - } - - final int numeric = Integer.parseInt(parts[1]); - - durabilities.put(parts[0].toLowerCase(), parts.length > 2 && !parts[2].equals("0") ? Short.parseShort(parts[2]) : 0); - items.put(parts[0].toLowerCase(), numeric); - } - catch (Exception ex) - { - LOGGER.warning(Util.format("parseError", "items.csv", i)); - } + continue; } - } - catch (IOException ex) - { - LOGGER.log(Level.SEVERE, Util.i18n("itemsCsvNotLoaded"), ex); - } - finally - { - if (rx != null) { - try - { - rx.close(); - } - catch (IOException ex) - { - LOGGER.log(Level.SEVERE, ex.getMessage(), ex); - } + + final String[] parts = line.split("[^a-z0-9]"); + if (parts.length < 2) + { + continue; } + + final int numeric = Integer.parseInt(parts[1]); + + durabilities.put(parts[0].toLowerCase(), parts.length > 2 && !parts[2].equals("0") ? Short.parseShort(parts[2]) : 0); + items.put(parts[0].toLowerCase(), numeric); } } @@ -163,7 +94,7 @@ public class ItemDb implements IConf metaData = durabilities.get(itemname); } } - else if(Material.getMaterial(itemname) != null) + else if (Material.getMaterial(itemname) != null) { itemid = Material.getMaterial(itemname).getId(); metaData = 0; diff --git a/Essentials/src/com/earth2me/essentials/ManagedFile.java b/Essentials/src/com/earth2me/essentials/ManagedFile.java new file mode 100644 index 000000000..759261e02 --- /dev/null +++ b/Essentials/src/com/earth2me/essentials/ManagedFile.java @@ -0,0 +1,235 @@ +package com.earth2me.essentials; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.math.BigInteger; +import java.security.DigestInputStream; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import org.bukkit.Bukkit; + + +public class ManagedFile +{ + private final static int BUFFERSIZE = 1024 * 8; + private final transient File file; + + public ManagedFile(final String filename, final IEssentials ess) + { + file = new File(ess.getDataFolder(), filename); + + if (file.exists()) + { + try + { + if (checkForVersion(file, ess.getDescription().getVersion()) && !file.delete()) + { + throw new IOException("Could not delete file " + file.toString()); + } + } + catch (IOException ex) + { + Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); + } + } + + if (!file.exists()) + { + try + { + copyResourceAscii("/" + filename, file); + } + catch (IOException ex) + { + Bukkit.getLogger().log(Level.SEVERE, Util.i18n("itemsCsvNotLoaded"), ex); + } + } + } + + public static void copyResourceAscii(final String resourceName, final File file) throws IOException + { + final InputStreamReader reader = new InputStreamReader(ManagedFile.class.getResourceAsStream(resourceName)); + try + { + final MessageDigest digest = getDigest(); + final DigestOutputStream digestStream = new DigestOutputStream(new FileOutputStream(file), digest); + try + { + final OutputStreamWriter writer = new OutputStreamWriter(digestStream); + try + { + final char[] buffer = new char[BUFFERSIZE]; + do + { + final int length = reader.read(buffer); + if (length >= 0) + { + writer.write(buffer, 0, length); + } + else + { + break; + } + } + while (true); + writer.write("\n"); + writer.flush(); + final BigInteger hashInt = new BigInteger(1, digest.digest()); + digestStream.on(false); + digestStream.write('#'); + digestStream.write(hashInt.toString(16).getBytes()); + } + finally + { + writer.close(); + } + } + finally + { + digestStream.close(); + } + } + finally + { + reader.close(); + } + } + + public static boolean checkForVersion(final File file, final String version) throws IOException + { + if (file.length() < 33) + { + return false; + } + final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); + try + { + final byte[] buffer = new byte[(int)file.length()]; + int position = 0; + do + { + final int length = bis.read(buffer, position, Math.min((int)file.length() - position, BUFFERSIZE)); + if (length < 0) + { + break; + } + position += length; + } + while (position < file.length()); + final ByteArrayInputStream bais = new ByteArrayInputStream(buffer); + if (bais.skip(file.length() - 33) != file.length() - 33) + { + return false; + } + final BufferedReader reader = new BufferedReader(new InputStreamReader(bais)); + try + { + String hash = reader.readLine(); + if (hash.matches("#[a-f0-9]{32}")) + { + hash = hash.substring(1); + bais.reset(); + final String versionline = reader.readLine(); + if (versionline.matches("#version: .+")) + { + final String versioncheck = versionline.substring(10); + if (!versioncheck.equalsIgnoreCase(version)) + { + bais.reset(); + final MessageDigest digest = getDigest(); + final DigestInputStream digestStream = new DigestInputStream(bais, digest); + try + { + final byte[] bytes = new byte[(int)file.length() - 33]; + digestStream.read(bytes); + final BigInteger correct = new BigInteger(hash, 16); + final BigInteger test = new BigInteger(1, digest.digest()); + if (correct.equals(test)) + { + return true; + } + else + { + Bukkit.getLogger().warning("File " + file.toString() + " has been modified by user and file version differs, please update the file manually."); + } + } + finally + { + digestStream.close(); + } + } + } + } + } + finally + { + reader.close(); + } + } + finally + { + bis.close(); + } + return false; + } + + public static MessageDigest getDigest() throws IOException + { + try + { + return MessageDigest.getInstance("MD5"); + } + catch (NoSuchAlgorithmException ex) + { + throw new IOException(ex); + } + } + + public List getLines() + { + try + { + final BufferedReader reader = new BufferedReader(new FileReader(file)); + try + { + final List lines = new ArrayList(); + do + { + final String line = reader.readLine(); + if (line == null) + { + break; + } + else + { + lines.add(line); + } + } + while (true); + return lines; + } + finally + { + reader.close(); + } + } + catch (IOException ex) + { + Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); + return Collections.emptyList(); + } + } +} diff --git a/Essentials/src/items.csv b/Essentials/src/items.csv index c9899dbb1..53fe31d6c 100644 --- a/Essentials/src/items.csv +++ b/Essentials/src/items.csv @@ -1,4 +1,5 @@ -#Last updated on 14/9/2011 21:30 (gmt -5) for minecraft version 1.8.1 +#version: TeamCity +# If you change this file, it will not be automatically updated after the next release. #item,id,metadata stone,1,0 sstone,1,0