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:
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
|
||||
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{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
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;
|
||||
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.";
|
||||
}
|
||||
}
|
||||
|
@ -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]);
|
||||
}
|
||||
|
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.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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user