152 lines
5.5 KiB
Java
152 lines
5.5 KiB
Java
/*
|
|
* Forge Mod Loader
|
|
* Copyright (c) 2012-2013 cpw.
|
|
* All rights reserved. This program and the accompanying materials
|
|
* are made available under the terms of the GNU Lesser Public License v2.1
|
|
* which accompanies this distribution, and is available at
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
*
|
|
* Contributors:
|
|
* cpw - implementation
|
|
*/
|
|
|
|
package cpw.mods.fml.common.asm;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.File;
|
|
import java.io.InputStreamReader;
|
|
import java.io.ObjectInputStream.GetField;
|
|
import java.io.StringReader;
|
|
import java.net.JarURLConnection;
|
|
import java.nio.charset.Charset;
|
|
import java.security.CodeSource;
|
|
import java.security.cert.CertPath;
|
|
import java.security.cert.CertPathValidator;
|
|
import java.security.cert.Certificate;
|
|
import java.security.cert.CertificateFactory;
|
|
import java.security.cert.PKIXCertPathValidatorResult;
|
|
import java.security.cert.PKIXParameters;
|
|
import java.security.cert.TrustAnchor;
|
|
import java.security.cert.X509Certificate;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
|
|
import javax.swing.JOptionPane;
|
|
|
|
import org.objectweb.asm.ClassReader;
|
|
import org.objectweb.asm.ClassVisitor;
|
|
import org.objectweb.asm.FieldVisitor;
|
|
import org.objectweb.asm.Opcodes;
|
|
|
|
import cpw.mods.fml.common.CertificateHelper;
|
|
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
|
|
import cpw.mods.fml.common.patcher.ClassPatchManager;
|
|
import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
|
import cpw.mods.fml.relauncher.FMLRelauncher;
|
|
import cpw.mods.fml.relauncher.IFMLCallHook;
|
|
import cpw.mods.fml.relauncher.RelaunchClassLoader;
|
|
|
|
public class FMLSanityChecker implements IFMLCallHook
|
|
{
|
|
private static final String FMLFINGERPRINT = "AE:F6:54:79:96:E9:1B:D1:59:70:6C:B4:6B:F5:4A:89:C5:CE:08:1D".toLowerCase().replace(":","");
|
|
private static final String FORGEFINGERPRINT = "DE:4C:F8:A3:F3:BC:15:63:58:10:04:4C:39:24:0B:F9:68:04:EA:7D".toLowerCase().replace(":", "");
|
|
static class MLDetectorClassVisitor extends ClassVisitor
|
|
{
|
|
private boolean foundMarker = false;
|
|
private MLDetectorClassVisitor()
|
|
{
|
|
super(Opcodes.ASM4);
|
|
}
|
|
|
|
@Override
|
|
public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4)
|
|
{
|
|
if ("fmlMarker".equals(arg1))
|
|
{
|
|
foundMarker = true;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private RelaunchClassLoader cl;
|
|
|
|
@Override
|
|
public Void call() throws Exception
|
|
{
|
|
CodeSource codeSource = getClass().getProtectionDomain().getCodeSource();
|
|
boolean goodFML = false;
|
|
if (codeSource.getLocation().getProtocol().equals("jar"))
|
|
{
|
|
Certificate[] certificates = codeSource.getCertificates();
|
|
if (certificates!=null)
|
|
{
|
|
|
|
for (Certificate cert : certificates)
|
|
{
|
|
String fingerprint = CertificateHelper.getFingerprint(cert);
|
|
if (fingerprint.equals(FMLFINGERPRINT))
|
|
{
|
|
FMLRelaunchLog.info("Found valid fingerprint for FML. Certificate fingerprint %s", fingerprint);
|
|
goodFML = true;
|
|
}
|
|
else if (fingerprint.equals(FORGEFINGERPRINT))
|
|
{
|
|
FMLRelaunchLog.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint %s", fingerprint);
|
|
goodFML = true;
|
|
}
|
|
else
|
|
{
|
|
FMLRelaunchLog.severe("Found invalid fingerprint for FML: %s", fingerprint);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
goodFML = true;
|
|
}
|
|
if (!goodFML)
|
|
{
|
|
FMLRelaunchLog.severe("FML appears to be missing any signature data. This is not a good thing");
|
|
}
|
|
byte[] mlClass = cl.getClassBytes("ModLoader");
|
|
// Only care in obfuscated env
|
|
if (mlClass == null)
|
|
{
|
|
return null;
|
|
}
|
|
MLDetectorClassVisitor mlTester = new MLDetectorClassVisitor();
|
|
ClassReader cr = new ClassReader(mlClass);
|
|
cr.accept(mlTester, ClassReader.SKIP_CODE);
|
|
if (!mlTester.foundMarker)
|
|
{
|
|
JOptionPane.showMessageDialog(null, "<html>CRITICAL ERROR<br/>" +
|
|
"ModLoader was detected in this environment<br/>" +
|
|
"ForgeModLoader cannot be installed alongside ModLoader<br/>" +
|
|
"All mods should work without ModLoader being installed<br/>" +
|
|
"Because ForgeModLoader is 100% compatible with ModLoader<br/>" +
|
|
"Re-install Minecraft Forge or Forge ModLoader into a clean<br/>" +
|
|
"jar and try again.",
|
|
"ForgeModLoader critical error",
|
|
JOptionPane.ERROR_MESSAGE);
|
|
throw new RuntimeException("Invalid ModLoader class detected");
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void injectData(Map<String, Object> data)
|
|
{
|
|
cl = (RelaunchClassLoader) data.get("classLoader");
|
|
File mcDir = (File)data.get("mcLocation");
|
|
FMLDeobfuscatingRemapper.INSTANCE.setup(mcDir, cl, (String) data.get("deobfuscationFileName"));
|
|
File binpatches = new File(mcDir,"binpatch");
|
|
File side = new File(binpatches,FMLRelauncher.side().toLowerCase(Locale.ENGLISH));
|
|
ClassPatchManager.INSTANCE.setup(side);
|
|
}
|
|
|
|
}
|