package org.bukkit.craftbukkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import c.m;
public class FileCheck {
private static String minecraft_server = "./minecraft_server.jar";
private static String minecraft_servero = "./minecraft_servero.jar";
private static String temp_file = "deleteme.jar";
private static String temp2_file = "deleteme2.jar";
private static String temp3_file = "deleteme.log";
//Now in Jar.
//private static String jarjar = "./libs/jarjar.jar";
//private static String retroguard = "./libs/retroguard.jar";
private static String jarjar_rules = "./config/rules/latest.rules";
private static String retroguard_rules = "./config/rules/latest.rgs";
private static String jarjar_namespace_rules = "./config/rules/namespace.rules";
private static long crc_minecraft_server = 280458825L;
private static long crc_minecraft_servero = 2467234520L;
//private static long crc_jarjar = 519567578L;
//private static long crc_retroguard = 2728595211L;
private static long crc_jarjar_rules = 149905660L;
private static long crc_retroguard_rules = 3002032626L;
private static long crc_jarjar_namespace_rules = 4187131396L;
public static void checkAllFiles() throws IOException {
if(!fileExists(minecraft_servero)) {
if (!fileExists(jarjar_rules) || !fileExists(retroguard_rules) || !fileExists(jarjar_namespace_rules)) {
log("-----------------------------");
log("Some of the tools to make a normalized minecraft jar (aka minecraft_servero.jar) are missing!");
log("Without these files or a proper minecraft_servero.jar the server cannot run!");
log("-----------------------------");
System.exit(0);
}
//checkCRC32(jarjar, crc_jarjar);
//checkCRC32(retroguard, crc_retroguard);
checkCRC32(jarjar_rules, crc_jarjar_rules);
checkCRC32(retroguard_rules, crc_retroguard_rules);
checkCRC32(jarjar_namespace_rules, crc_jarjar_namespace_rules);
if (!fileExists(minecraft_server)) {
log("Missing minecraft_servero.jar, Downloading minecraft_server.jar...");
downloadFile("https://s3.amazonaws.com/MinecraftDownload/launcher/minecraft_server.jar", minecraft_server);
checkCRC32(minecraft_server, crc_minecraft_server);
log("Finished downloading minecraft_server.jar, start converting minecraft_server.jar to minecraft_servero.jar...");
} else
log("Missing minecraft_servero.jar, start converting minecraft_server.jar to minecraft_servero.jar...");
try {
com.tonicsystems.jarjar.Main.main(new String[] { "process", jarjar_rules, minecraft_server, temp_file });
} catch (Throwable t) {
t.printStackTrace();
}
log("Class files renamed, 30% done ..." );
try {
com.tonicsystems.jarjar.Main.main(new String[] { "process", jarjar_namespace_rules, temp_file, temp2_file });
} catch (Throwable t) {
t.printStackTrace();
}
log("Class files repacked, 70% done ..." );
try {
m.a(temp2_file, minecraft_servero, retroguard_rules, temp3_file);
} catch (Throwable t) {
t.printStackTrace();
}
log("Field names renamed, 99% done...");
(new File(temp_file)).delete();
(new File(temp2_file)).delete();
(new File(temp3_file)).delete();
checkCRC32(minecraft_servero, crc_minecraft_servero);
log("Finished converting minecraft_server.jar, Starting minecraft server...");
dynamicLoadJar(minecraft_servero);
} else {
checkCRC32(minecraft_servero,crc_minecraft_servero);
}
createMissingConfigFiles();
}
private static String jar_config_dir = "/org/buckit/config/";
private static String config_dir = "./config/";
private static String[] config_files = new String[]{
"Database.properties" ,
"Expert.properties" ,
"FlatFile.properties" ,
"General.properties" ,
"motd.txt" ,
"World.properties",
"Hell.properties"
};
private static void createMissingConfigFiles() throws IOException {
for(String file : config_files) {
if(!fileExists(config_dir + file)) {
InputStream input = FileCheck.class.getResourceAsStream(jar_config_dir + file);
//For Overwrite the file.
OutputStream output = new FileOutputStream(new File(config_dir + file));
byte[] buf = new byte[1024];
int len;
while ((len = input.read(buf)) > 0){
output.write(buf, 0, len);
}
input.close();
output.close();
log("Missing " + file + " restored.");
}
}
}
public static boolean fileExists(String filename) {
return new File(filename).exists();
}
public static void checkCRC32(String fileName, long[] crcs) throws IOException {
long checksum = getCRC32(fileName);
for (long i : crcs)
if (i == checksum)
return;
log("-----------------------------");
log(fileName + " does not match checksum!");
log("This means some of your files are either corrupted,outdated or to new(minecraft got updated?).");
log("Running the server with these files is NOT recommended and you will NEVER receive support for them!!");
log("-----------------------------");
//System.exit(0);
}
public static void checkCRC32(String fileName, long crc) throws IOException {
long checksum = getCRC32(fileName);
if (checksum != crc) {
log("-----------------------------");
log(fileName + " does not match checksum! Checksum found: " + checksum + ", required checksum: " + crc + ".");
log("This means some of your files are either corrupted,outdated or to new(minecraft got updated?).");
log("Running the server with these files is NOT recommended and you will NEVER receive support for them!!");
log("-----------------------------");
//System.exit(0);
}
}
public static long getCRC32(String fileName) throws IOException {
FileInputStream stream = new FileInputStream(fileName);
CheckedInputStream cis = new CheckedInputStream(stream, new CRC32());
byte[] buf = new byte[128];
while (cis.read(buf) >= 0) {
}
long rt = cis.getChecksum().getValue();
stream.close();
cis.close();
return rt;
}
public static void downloadFile(String website, String fileLocation) throws IOException {
URL url = new URL(website);
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
FileOutputStream fos = new FileOutputStream(fileLocation);
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
}
public static void log(String str) {
System.out.println(str);
}
public static void copyFile(File in, File out) throws IOException
{
FileChannel inChannel = new FileInputStream(in).getChannel();
FileChannel outChannel = new FileOutputStream(out).getChannel();
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} finally {
if (inChannel != null) inChannel.close();
if (outChannel != null) outChannel.close();
}
}
public static void dynamicLoadJar(String fileName) throws IOException {
URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<?> sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", new Class[] { URL.class });
method.setAccessible(true);
method.invoke(sysloader, new Object[] { (new File(fileName)).toURI().toURL() });
} catch (Throwable t) {
t.printStackTrace();
throw new IOException("Error, could not add URL to system classloader");
}
}
}