diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitMain.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitMain.java index bfcd3d92..438d7a74 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitMain.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitMain.java @@ -1,12 +1,10 @@ package com.boydti.fawe.bukkit; import com.boydti.fawe.Fawe; +import com.boydti.fawe.util.Jars; import java.io.File; import java.io.FileOutputStream; import java.lang.reflect.Field; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -57,11 +55,9 @@ public class BukkitMain extends JavaPlugin { if (Bukkit.getPluginManager().getPlugin("WorldEdit") == null) { try { File output = new File(this.getDataFolder().getParentFile(), "WorldEdit.jar"); - URL worldEditUrl = new URL("https://addons.cursecdn.com/files/2431/372/worldedit-bukkit-6.1.7.2.jar"); - try (ReadableByteChannel rbc = Channels.newChannel(worldEditUrl.openStream())) { - try (FileOutputStream fos = new FileOutputStream(output)) { - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - } + byte[] weJar = Jars.WE_B_6_1_7_2.download(); + try (FileOutputStream fos = new FileOutputStream(output)) { + fos.write(weJar); } Bukkit.getPluginManager().loadPlugin(output); } catch (Throwable e) { diff --git a/core/src/main/java/com/boydti/fawe/util/Jars.java b/core/src/main/java/com/boydti/fawe/util/Jars.java new file mode 100644 index 00000000..7bfdd54d --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/util/Jars.java @@ -0,0 +1,67 @@ +package com.boydti.fawe.util; + +import java.io.DataInputStream; +import java.io.IOException; +import java.net.URL; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +import com.boydti.fawe.Fawe; +import com.google.common.io.BaseEncoding; + +public enum Jars { + WE_B_6_1_7_2("https://addons.cursecdn.com/files/2431/372/worldedit-bukkit-6.1.7.2.jar", + "711be37301a327aba4e347131875d0564dbfdc2f41053a12db97f0234661778b", 1726340), + + VS_B_5_171_0("https://addons-origin.cursecdn.com/files/912/511/VoxelSniper-5.171.0-SNAPSHOT.jar", + "292c3b38238e0d8e5f036381d28bccfeb15df67cae53d28b52d066bc6238208f", 3632776); + + public final String url; + public final int filesize; + public final String digest; + + /** + * @param url + * Where this jar can be found and downloaded + * @param digest + * The SHA-256 hexadecimal digest + * @param filesize + * Size of this jar in bytes + */ + private Jars(String url, String digest, int filesize) { + this.url = url; + this.digest = digest; + this.filesize = filesize; + } + + /** download a jar, verify hash, return byte[] containing the jar */ + public byte[] download() throws IOException { + byte[] jarBytes = new byte[this.filesize]; + URL url = new URL(this.url); + try (DataInputStream dis = new DataInputStream(url.openConnection().getInputStream());) { + dis.readFully(jarBytes); + if (dis.read() != -1) { // assert that we've read everything + throw new IllegalStateException("downloaded jar is longer than expected"); + } + + MessageDigest md; + md = MessageDigest.getInstance("SHA-256"); + byte[] thisDigest = md.digest(jarBytes); + byte[] realDigest = BaseEncoding.base16().decode(this.digest.toUpperCase()); + + if (Arrays.equals(thisDigest, realDigest)) { + Fawe.debug("++++ HASH CHECK ++++"); + Fawe.debug(this.url); + Fawe.debug(BaseEncoding.base16().encode(thisDigest)); + return jarBytes; + } else { + throw new IllegalStateException("downloaded jar does not match the hash"); + } + } catch (NoSuchAlgorithmException e) { + // Shouldn't ever happen, Minecraft won't even run on such a JRE + throw new IllegalStateException("Your JRE does not support SHA-256"); + } + + } +} diff --git a/favs/src/main/java/com/boydti/fawe/bukkit/favs/Favs.java b/favs/src/main/java/com/boydti/fawe/bukkit/favs/Favs.java index afcbbfd5..9002a274 100644 --- a/favs/src/main/java/com/boydti/fawe/bukkit/favs/Favs.java +++ b/favs/src/main/java/com/boydti/fawe/bukkit/favs/Favs.java @@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.bukkit.BukkitCommand; import com.boydti.fawe.object.FaweCommand; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.util.Jars; import com.boydti.fawe.util.MainUtil; import com.thevoxelbox.voxelsniper.RangeBlockHelper; import com.thevoxelbox.voxelsniper.SnipeData; @@ -12,9 +13,6 @@ import com.thevoxelbox.voxelsniper.brush.perform.PerformBrush; import com.thevoxelbox.voxelsniper.command.VoxelVoxelCommand; import java.io.File; import java.io.FileOutputStream; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -40,11 +38,9 @@ public class Favs extends JavaPlugin { } if (output == null) { output = new File(this.getDataFolder().getParentFile(), "VoxelSniper.jar"); - URL worldEditUrl = new URL("https://addons-origin.cursecdn.com/files/912/511/VoxelSniper-5.171.0-SNAPSHOT.jar"); - try (ReadableByteChannel rbc = Channels.newChannel(worldEditUrl.openStream())) { - try (FileOutputStream fos = new FileOutputStream(output)) { - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); - } + byte[] vsJar = Jars.VS_B_5_171_0.download(); + try (FileOutputStream fos = new FileOutputStream(output)) { + fos.write(vsJar); } } Bukkit.getPluginManager().loadPlugin(output);