mirror of
https://github.com/chylex/Java-Checker.git
synced 2025-07-23 08:59:02 +02:00
Rewrite and update to 2.0 (fix headless env, add futureproofing, cleanup code)
This commit is contained in:
parent
507af0ea20
commit
36e0c3e456
build.gradle
src/main
java/chylex/javacheck
test/chylex/javacheck/test
@ -19,7 +19,7 @@ group = "chylex.javacheck"
|
|||||||
ext.buildnumber = 0
|
ext.buildnumber = 0
|
||||||
project.buildnumber = System.getenv('BUILD_NUMBER') == null ? "CUSTOM" : System.getenv('BUILD_NUMBER')
|
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"
|
String archiveSuffix = (project.hasProperty("mavendir") ? "-" : " ")+version+".jar"
|
||||||
|
|
||||||
minecraft{
|
minecraft{
|
||||||
|
@ -6,10 +6,10 @@ import net.minecraft.launchwrapper.LaunchClassLoader;
|
|||||||
import org.apache.commons.lang3.JavaVersion;
|
import org.apache.commons.lang3.JavaVersion;
|
||||||
import chylex.javacheck.report.JavaCheckerReporter;
|
import chylex.javacheck.report.JavaCheckerReporter;
|
||||||
|
|
||||||
public class Java7Checker implements ITweaker{
|
public final class Java7Checker implements ITweaker{
|
||||||
@Override
|
@Override
|
||||||
public void injectIntoClassLoader(LaunchClassLoader classLoader){
|
public void injectIntoClassLoader(LaunchClassLoader classLoader){
|
||||||
JavaCheckerReporter.run(JavaVersion.JAVA_1_7);
|
JavaVersionChecker.run(JavaVersion.JAVA_1_7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,10 +6,10 @@ import net.minecraft.launchwrapper.LaunchClassLoader;
|
|||||||
import org.apache.commons.lang3.JavaVersion;
|
import org.apache.commons.lang3.JavaVersion;
|
||||||
import chylex.javacheck.report.JavaCheckerReporter;
|
import chylex.javacheck.report.JavaCheckerReporter;
|
||||||
|
|
||||||
public class Java8Checker implements ITweaker{
|
public final class Java8Checker implements ITweaker{
|
||||||
@Override
|
@Override
|
||||||
public void injectIntoClassLoader(LaunchClassLoader classLoader){
|
public void injectIntoClassLoader(LaunchClassLoader classLoader){
|
||||||
JavaCheckerReporter.run(JavaVersion.JAVA_1_8);
|
JavaVersionChecker.run(JavaVersion.JAVA_1_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
48
src/main/java/chylex/javacheck/JavaVersionChecker.java
Normal file
48
src/main/java/chylex/javacheck/JavaVersionChecker.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package chylex.javacheck.report;
|
package chylex.javacheck.report;
|
||||||
import java.awt.Desktop;
|
import java.awt.Desktop;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.swing.JEditorPane;
|
import javax.swing.JEditorPane;
|
||||||
@ -10,106 +11,55 @@ import javax.swing.event.HyperlinkEvent.EventType;
|
|||||||
import javax.swing.event.HyperlinkListener;
|
import javax.swing.event.HyperlinkListener;
|
||||||
import org.apache.commons.lang3.JavaVersion;
|
import org.apache.commons.lang3.JavaVersion;
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
import chylex.javacheck.util.ForgeCompatibility;
|
||||||
|
|
||||||
public final class JavaCheckerReporter{
|
public final class JavaCheckerReporter{
|
||||||
public static void run(JavaVersion minVersion){
|
public static void reportOutdatedJava(JavaVersion minVersion){
|
||||||
if (minVersion == null || !SystemUtils.isJavaVersionAtLeast(minVersion)){
|
String consoleReport = getConsoleReport(minVersion);
|
||||||
if (minVersion == null)minVersion = JavaVersion.JAVA_1_8;
|
|
||||||
|
if (!ForgeCompatibility.tryLog(consoleReport)){
|
||||||
try{
|
System.out.println(consoleReport);
|
||||||
Class relaunchLog = findRelaunchLog();
|
}
|
||||||
if (relaunchLog != null)relaunchLog.getMethod("severe",String.class,Object[].class).invoke(null,getConsoleReport(minVersion),new Object[0]);
|
|
||||||
}catch(Throwable t){}
|
if (!GraphicsEnvironment.isHeadless() && ForgeCompatibility.isClientSide()){
|
||||||
|
displayErrorPopup("Outdated Java",getHtmlReport(minVersion));
|
||||||
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);
|
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.addHyperlinkListener(new HyperlinkListener(){
|
pane.setBackground(new JLabel().getBackground());
|
||||||
@Override
|
pane.setEditable(false);
|
||||||
public void hyperlinkUpdate(HyperlinkEvent e){
|
|
||||||
if (e.getEventType() == EventType.ACTIVATED){
|
pane.addHyperlinkListener(new HyperlinkListener(){
|
||||||
try{
|
@Override
|
||||||
if (Desktop.isDesktopSupported())Desktop.getDesktop().browse(e.getURL().toURI());
|
public void hyperlinkUpdate(HyperlinkEvent e){
|
||||||
}catch(Exception ex){
|
if (e.getEventType() == EventType.ACTIVATED){
|
||||||
ex.printStackTrace();
|
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){
|
private static String getConsoleReport(JavaVersion minVersion){
|
||||||
return new StringBuilder(242).append("\n")
|
return
|
||||||
.append("\n!! DO NOT REPORT !!\n\n")
|
"\n\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")
|
"One of the mods requires Java "+minVersion+" or newer, you are using "+SystemUtils.JAVA_VERSION+".\n"+
|
||||||
.append("Visit https://java.com/download/ for the latest version.\n")
|
"Visit https://java.com/download/ for the latest version.\n"+
|
||||||
.append("Please, uninstall the old version first to prevent further issues.")
|
"Please, uninstall the old version first to prevent further issues."+
|
||||||
.append("\n\n!! DO NOT REPORT !!\n")
|
"\n\n!! DO NOT REPORT !!\n";
|
||||||
.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getWindowReport(JavaVersion minVersion){
|
private static String getHtmlReport(JavaVersion minVersion){
|
||||||
return new StringBuilder(230)
|
return
|
||||||
.append("One of the mods requires Java "+minVersion.toString()+" or newer, you are using ").append(SystemUtils.JAVA_VERSION).append(".<br>")
|
"One of the mods requires Java "+minVersion+" or newer, you are using "+SystemUtils.JAVA_VERSION+".<br>"+
|
||||||
.append("Visit <a href=\"https://java.com/download/\"><span style=\"color:blue\">https://java.com/download/</span></a> for the latest version.<br>")
|
"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.")
|
"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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package chylex.javacheck.report;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
public class OutdatedJavaException extends RuntimeException{
|
public final class OutdatedJavaException extends RuntimeException{
|
||||||
public OutdatedJavaException(){
|
public OutdatedJavaException(){
|
||||||
setStackTrace(new StackTraceElement[0]);
|
setStackTrace(new StackTraceElement[0]);
|
||||||
}
|
}
|
||||||
|
100
src/main/java/chylex/javacheck/util/ForgeCompatibility.java
Normal file
100
src/main/java/chylex/javacheck/util/ForgeCompatibility.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@ -2,12 +2,14 @@ package chylex.javacheck.test;
|
|||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.Mod.EventHandler;
|
import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
|
import chylex.javacheck.JavaVersionChecker;
|
||||||
import chylex.javacheck.report.JavaCheckerReporter;
|
import chylex.javacheck.report.JavaCheckerReporter;
|
||||||
|
|
||||||
@Mod(modid = "JavaCheckerTestMod")
|
@Mod(modid = "JavaCheckerTestMod")
|
||||||
public class JavaCheckerTestMod{
|
public class JavaCheckerTestMod{
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPreInit(FMLPreInitializationEvent e){
|
public void onPreInit(FMLPreInitializationEvent e){
|
||||||
JavaCheckerReporter.run(null);
|
System.out.println(JavaCheckerReporter.class.getPackage().getName());
|
||||||
|
JavaVersionChecker.run(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user