1
0
mirror of https://github.com/chylex/Java-Checker.git synced 2025-06-10 10:34:03 +02:00

Rewrite and update to 2.0 (fix headless env, add futureproofing, cleanup code)

This commit is contained in:
chylex 2016-01-10 21:07:34 +01:00
parent 507af0ea20
commit 36e0c3e456
8 changed files with 198 additions and 98 deletions

View File

@ -19,7 +19,7 @@ group = "chylex.javacheck"
ext.buildnumber = 0
project.buildnumber = System.getenv('BUILD_NUMBER') == null ? "CUSTOM" : System.getenv('BUILD_NUMBER')
version = project.hasProperty("mavendir") ? "v1.3-b"+project.buildnumber : "MC-UNIVERSAL v1.3"
version = project.hasProperty("mavendir") ? "v2.0-b"+project.buildnumber : "MC-UNIVERSAL v2.0"
String archiveSuffix = (project.hasProperty("mavendir") ? "-" : " ")+version+".jar"
minecraft{

View File

@ -6,10 +6,10 @@ import net.minecraft.launchwrapper.LaunchClassLoader;
import org.apache.commons.lang3.JavaVersion;
import chylex.javacheck.report.JavaCheckerReporter;
public class Java7Checker implements ITweaker{
public final class Java7Checker implements ITweaker{
@Override
public void injectIntoClassLoader(LaunchClassLoader classLoader){
JavaCheckerReporter.run(JavaVersion.JAVA_1_7);
JavaVersionChecker.run(JavaVersion.JAVA_1_7);
}
@Override

View File

@ -6,10 +6,10 @@ import net.minecraft.launchwrapper.LaunchClassLoader;
import org.apache.commons.lang3.JavaVersion;
import chylex.javacheck.report.JavaCheckerReporter;
public class Java8Checker implements ITweaker{
public final class Java8Checker implements ITweaker{
@Override
public void injectIntoClassLoader(LaunchClassLoader classLoader){
JavaCheckerReporter.run(JavaVersion.JAVA_1_8);
JavaVersionChecker.run(JavaVersion.JAVA_1_8);
}
@Override

View File

@ -0,0 +1,48 @@
package chylex.javacheck;
import org.apache.commons.lang3.JavaVersion;
import org.apache.commons.lang3.SystemUtils;
import chylex.javacheck.report.JavaCheckerReporter;
import chylex.javacheck.report.OutdatedJavaException;
import chylex.javacheck.util.ForgeCompatibility;
public final class JavaVersionChecker{
public static final String issueReportSite = "https://github.com/chylex/Java-Checker/issues";
public static void run(JavaVersion minVersion){
try{
unsafeRun(minVersion);
}catch(OutdatedJavaException me){
throw me;
}catch(ShadingException up){
throw up;
}catch(Throwable t){
t.printStackTrace();
System.out.println("Detected an unexpected error in Java Version Checker, ignoring since trying to run the game is more important.");
System.out.println("If you crashed and happen to see this, please report the error above to: "+issueReportSite);
}
}
private static void unsafeRun(JavaVersion minVersion){
if (minVersion == null || !SystemUtils.isJavaVersionAtLeast(minVersion)){
if (minVersion == null)minVersion = JavaVersion.JAVA_1_8; // debugging purposes
JavaCheckerReporter.reportOutdatedJava(minVersion);
throw new OutdatedJavaException();
}
else{
if (isShaded() && !ForgeCompatibility.tryResetModState()){
throw new ShadingException();
}
}
}
private static boolean isShaded(){
return !JavaCheckerReporter.class.getPackage().getName().equals("chylex.javacheck.report");
}
public static class ShadingException extends RuntimeException{
public ShadingException(){
super("An exception happened when updating the coremod list, the mod you are shading Java Checker in will not run without it. Please, report the stack traces above to "+issueReportSite);
}
}
}

View File

@ -1,5 +1,6 @@
package chylex.javacheck.report;
import java.awt.Desktop;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.util.List;
import javax.swing.JEditorPane;
@ -10,106 +11,55 @@ import javax.swing.event.HyperlinkEvent.EventType;
import javax.swing.event.HyperlinkListener;
import org.apache.commons.lang3.JavaVersion;
import org.apache.commons.lang3.SystemUtils;
import chylex.javacheck.util.ForgeCompatibility;
public final class JavaCheckerReporter{
public static void run(JavaVersion minVersion){
if (minVersion == null || !SystemUtils.isJavaVersionAtLeast(minVersion)){
if (minVersion == null)minVersion = JavaVersion.JAVA_1_8;
try{
Class relaunchLog = findRelaunchLog();
if (relaunchLog != null)relaunchLog.getMethod("severe",String.class,Object[].class).invoke(null,getConsoleReport(minVersion),new Object[0]);
}catch(Throwable t){}
String style = "font-family:Dialog;font-size:12;font-weight:bold";
JEditorPane pane = new JEditorPane("text/html","<html><body style='"+style+"'>"+getWindowReport(minVersion)+"</body></html>");
pane.setBackground(new JLabel().getBackground());
pane.setEditable(false);
pane.addHyperlinkListener(new HyperlinkListener(){
@Override
public void hyperlinkUpdate(HyperlinkEvent e){
if (e.getEventType() == EventType.ACTIVATED){
try{
if (Desktop.isDesktopSupported())Desktop.getDesktop().browse(e.getURL().toURI());
}catch(Exception ex){
ex.printStackTrace();
}
public static void reportOutdatedJava(JavaVersion minVersion){
String consoleReport = getConsoleReport(minVersion);
if (!ForgeCompatibility.tryLog(consoleReport)){
System.out.println(consoleReport);
}
if (!GraphicsEnvironment.isHeadless() && ForgeCompatibility.isClientSide()){
displayErrorPopup("Outdated Java",getHtmlReport(minVersion));
}
}
private static void displayErrorPopup(String title, String contents){
JEditorPane pane = new JEditorPane("text/html","<html><body style='font-family:Dialog;font-size:12;font-weight:bold'>"+contents+"</body></html>");
pane.setBackground(new JLabel().getBackground());
pane.setEditable(false);
pane.addHyperlinkListener(new HyperlinkListener(){
@Override
public void hyperlinkUpdate(HyperlinkEvent e){
if (e.getEventType() == EventType.ACTIVATED){
try{
if (Desktop.isDesktopSupported())Desktop.getDesktop().browse(e.getURL().toURI());
}catch(Exception ex){
ex.printStackTrace();
}
}
});
JOptionPane.showMessageDialog(null,pane,"Outdated Java",JOptionPane.ERROR_MESSAGE);
throw new OutdatedJavaException();
}
else{
try{
Class cmm = findCoreModManager();
List coremods = getListOrNullSafe(cmm,"getLoadedCoremods");
if (coremods == null)coremods = getListOrNullSafe(cmm,"getIgnoredMods");
List reparsed = getListOrNullSafe(cmm,"getReparseableCoremods");
String myFile = new File(JavaCheckerReporter.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getName();
coremods.remove(myFile);
reparsed.add(myFile);
}catch(Throwable t){
t.printStackTrace();
}
}
});
JOptionPane.showMessageDialog(null,pane,title,JOptionPane.ERROR_MESSAGE);
}
private static String getConsoleReport(JavaVersion minVersion){
return new StringBuilder(242).append("\n")
.append("\n!! DO NOT REPORT !!\n\n")
.append("One of the mods requires Java "+minVersion.toString()+" or newer, you are using ").append(SystemUtils.JAVA_VERSION).append(".\n")
.append("Visit https://java.com/download/ for the latest version.\n")
.append("Please, uninstall the old version first to prevent further issues.")
.append("\n\n!! DO NOT REPORT !!\n")
.toString();
return
"\n\n!! DO NOT REPORT !!\n\n"+
"One of the mods requires Java "+minVersion+" or newer, you are using "+SystemUtils.JAVA_VERSION+".\n"+
"Visit https://java.com/download/ for the latest version.\n"+
"Please, uninstall the old version first to prevent further issues."+
"\n\n!! DO NOT REPORT !!\n";
}
private static String getWindowReport(JavaVersion minVersion){
return new StringBuilder(230)
.append("One of the mods requires Java "+minVersion.toString()+" or newer, you are using ").append(SystemUtils.JAVA_VERSION).append(".<br>")
.append("Visit <a href=\"https://java.com/download/\"><span style=\"color:blue\">https://java.com/download/</span></a> for the latest version.<br>")
.append("Please, uninstall the old version first to prevent further issues.")
.toString();
}
private static Class findRelaunchLog() throws Throwable{
try{
return Class.forName("cpw.mods.fml.relauncher.FMLRelaunchLog");
}catch(ClassNotFoundException e){}
try{
return Class.forName("net.minecraftforge.fml.relauncher.FMLRelaunchLog");
}catch(ClassNotFoundException e){}
return null;
}
private static Class findCoreModManager() throws Throwable{
try{
return Class.forName("cpw.mods.fml.relauncher.CoreModManager");
}catch(ClassNotFoundException e){}
try{
return Class.forName("net.minecraftforge.fml.relauncher.CoreModManager");
}catch(ClassNotFoundException e){}
return null;
}
private static List getListOrNullSafe(Class cls, String methodName){
try{
return (List)cls.getMethod(methodName).invoke(null);
}catch(NoSuchMethodException e){
}catch(Throwable t){
t.printStackTrace();
}
return null;
private static String getHtmlReport(JavaVersion minVersion){
return
"One of the mods requires Java "+minVersion+" or newer, you are using "+SystemUtils.JAVA_VERSION+".<br>"+
"Visit <a href=\"https://java.com/download/\"><span style=\"color:blue\">https://java.com/download/</span></a> for the latest version.<br>"+
"Please, uninstall the old version first to prevent further issues.";
}
}

View File

@ -2,7 +2,7 @@ package chylex.javacheck.report;
import java.io.PrintStream;
import java.io.PrintWriter;
public class OutdatedJavaException extends RuntimeException{
public final class OutdatedJavaException extends RuntimeException{
public OutdatedJavaException(){
setStackTrace(new StackTraceElement[0]);
}

View File

@ -0,0 +1,100 @@
package chylex.javacheck.util;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.List;
public final class ForgeCompatibility{
public static boolean tryLog(String data){
try{
org.apache.logging.log4j.LogManager.getLogger("JavaChecker").log(org.apache.logging.log4j.Level.ERROR,data);
return true;
}catch(Throwable t){ // apache logging is not available
t.printStackTrace();
}
try{
Class relaunchLog = findFMLClass("relaunch","FMLRelaunchLog");
Method logSevere = findMethod(relaunchLog,"severe",String.class,Object[].class);
if (logSevere != null){
logSevere.invoke(null,data,new Object[0]);
return true;
}
}catch(Throwable t){ // relaunch log not available
t.printStackTrace();
}
return false;
}
public static boolean tryResetModState(){
try{
Class cmm = findFMLClass("relauncher","CoreModManager");
Method getCoremods = findMethodAlt(cmm,new String[]{ "getLoadedCoremods", "getIgnoredMods" });
Method getReparsed = findMethodAlt(cmm,new String[]{ "getReparseableCoremods" });
if (getCoremods == null || getReparsed == null)return false;
String myFile = getModFileName();
((List)getCoremods.invoke(null)).remove(myFile);
((List)getReparsed.invoke(null)).add(myFile);
return true;
}catch(Throwable t){
t.printStackTrace();
return false;
}
}
public static boolean isClientSide(){
try{
return Class.forName("net.minecraft.client.Minecraft") != null;
}catch(ClassNotFoundException e){
return false;
}catch(Throwable t){
t.printStackTrace();
return false;
}
}
private static Class findFMLClass(String classPackage, String className){
String searchTarget = classPackage.isEmpty() ? className : classPackage+"."+className;
try{
return Class.forName("cpw.mods.fml."+searchTarget);
}catch(ClassNotFoundException e){}
try{
return Class.forName("net.minecraftforge.fml."+searchTarget);
}catch(ClassNotFoundException e){}
return null;
}
private static Method findMethod(Class cls, String methodName, Class...params){
if (cls == null)return null;
try{
return cls.getMethod(methodName,params);
}catch(NoSuchMethodException e){}
return null;
}
private static Method findMethodAlt(Class cls, String[] methodNames, Class...params){
if (cls == null)return null;
for(String methodName:methodNames){
try{
return cls.getMethod(methodName,params);
}catch(NoSuchMethodException e){}
}
return null;
}
private static String getModFileName() throws URISyntaxException{
return new File(ForgeCompatibility.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getName();
}
}

View File

@ -2,12 +2,14 @@ package chylex.javacheck.test;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import chylex.javacheck.JavaVersionChecker;
import chylex.javacheck.report.JavaCheckerReporter;
@Mod(modid = "JavaCheckerTestMod")
public class JavaCheckerTestMod{
@EventHandler
public void onPreInit(FMLPreInitializationEvent e){
JavaCheckerReporter.run(null);
System.out.println(JavaCheckerReporter.class.getPackage().getName());
JavaVersionChecker.run(null);
}
}