More work
This commit is contained in:
parent
289ce3339a
commit
47dfd99d4f
4 changed files with 103 additions and 10 deletions
|
@ -0,0 +1,24 @@
|
||||||
|
package cpw.mods.fml.common;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.event.FMLEvent;
|
||||||
|
|
||||||
|
public class FMLFingerprintViolationEvent extends FMLEvent {
|
||||||
|
|
||||||
|
public final boolean isDirectory;
|
||||||
|
public final Set<String> fingerprints;
|
||||||
|
public final File source;
|
||||||
|
|
||||||
|
public FMLFingerprintViolationEvent(boolean isDirectory, File source, ImmutableSet<String> fingerprints)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.isDirectory = isDirectory;
|
||||||
|
this.source = source;
|
||||||
|
this.fingerprints = fingerprints;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -34,6 +35,8 @@ import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.BiMap;
|
import com.google.common.collect.BiMap;
|
||||||
import com.google.common.collect.ImmutableBiMap;
|
import com.google.common.collect.ImmutableBiMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.SetMultimap;
|
import com.google.common.collect.SetMultimap;
|
||||||
|
@ -86,10 +89,13 @@ public class FMLModContainer implements ModContainer
|
||||||
.put(FMLServerStartedEvent.class, Mod.ServerStarted.class)
|
.put(FMLServerStartedEvent.class, Mod.ServerStarted.class)
|
||||||
.put(FMLServerStoppingEvent.class, Mod.ServerStopping.class)
|
.put(FMLServerStoppingEvent.class, Mod.ServerStopping.class)
|
||||||
.put(IMCEvent.class,Mod.IMCCallback.class)
|
.put(IMCEvent.class,Mod.IMCCallback.class)
|
||||||
|
.put(FMLFingerprintViolationEvent.class, Mod.FingerprintWarning.class)
|
||||||
.build();
|
.build();
|
||||||
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
||||||
private String annotationDependencies;
|
private String annotationDependencies;
|
||||||
private VersionRange minecraftAccepted;
|
private VersionRange minecraftAccepted;
|
||||||
|
private boolean fingerprintNotPresent;
|
||||||
|
private Set<String> sourceFingerprints;
|
||||||
|
|
||||||
|
|
||||||
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
|
public FMLModContainer(String className, File modSource, Map<String,Object> modDescriptor)
|
||||||
|
@ -335,13 +341,6 @@ public class FMLModContainer implements ModContainer
|
||||||
return mc.getMetadata();
|
return mc.getMetadata();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//TODO
|
|
||||||
// for (Object o : annotations.get(Block.class))
|
|
||||||
// {
|
|
||||||
// Field f = (Field) o;
|
|
||||||
// f.set(modInstance, GameRegistry.buildBlock(this, f.getType(), f.getAnnotation(Block.class)));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseSimpleFieldAnnotation(SetMultimap<String, ASMData> annotations, String annotationClassName, Function<ModContainer, Object> retreiver) throws IllegalAccessException
|
private void parseSimpleFieldAnnotation(SetMultimap<String, ASMData> annotations, String annotationClassName, Function<ModContainer, Object> retreiver) throws IllegalAccessException
|
||||||
|
@ -408,12 +407,39 @@ public class FMLModContainer implements ModContainer
|
||||||
ModClassLoader modClassLoader = event.getModClassLoader();
|
ModClassLoader modClassLoader = event.getModClassLoader();
|
||||||
modClassLoader.addFile(source);
|
modClassLoader.addFile(source);
|
||||||
Class<?> clazz = Class.forName(className, true, modClassLoader);
|
Class<?> clazz = Class.forName(className, true, modClassLoader);
|
||||||
ASMDataTable asmHarvestedAnnotations = event.getASMHarvestedData();
|
|
||||||
// TODO
|
Certificate[] certificates = clazz.getProtectionDomain().getCodeSource().getCertificates();
|
||||||
asmHarvestedAnnotations.getAnnotationsFor(this);
|
int len = 0;
|
||||||
|
if (certificates != null)
|
||||||
|
{
|
||||||
|
len = certificates.length;
|
||||||
|
}
|
||||||
|
Builder<String> certBuilder = ImmutableSet.<String>builder();
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
certBuilder.add(CertificateHelper.getFingerprint(certificates[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceFingerprints = certBuilder.build();
|
||||||
|
|
||||||
|
String expectedFingerprint = (String) descriptor.get("certificateFingerprint");
|
||||||
|
|
||||||
|
if (expectedFingerprint != "" && !sourceFingerprints.contains(expectedFingerprint))
|
||||||
|
{
|
||||||
|
Level warnLevel = Level.SEVERE;
|
||||||
|
if (source.isDirectory())
|
||||||
|
{
|
||||||
|
warnLevel = Level.FINER;
|
||||||
|
}
|
||||||
|
FMLLog.log(warnLevel, "The mod %s is expecting signature %s for source %s, however there is no signature matching that description", getModId(), expectedFingerprint, source.getName());
|
||||||
|
}
|
||||||
annotations = gatherAnnotations(clazz);
|
annotations = gatherAnnotations(clazz);
|
||||||
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData());
|
isNetworkMod = FMLNetworkHandler.instance().registerNetworkMod(this, clazz, event.getASMHarvestedData());
|
||||||
modInstance = clazz.newInstance();
|
modInstance = clazz.newInstance();
|
||||||
|
if (fingerprintNotPresent)
|
||||||
|
{
|
||||||
|
handleModStateEvent(new FMLFingerprintViolationEvent(source.isDirectory(), source, ImmutableSet.copyOf(this.sourceFingerprints)));
|
||||||
|
}
|
||||||
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
|
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
|
||||||
processFieldAnnotations(event.getASMHarvestedData());
|
processFieldAnnotations(event.getASMHarvestedData());
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,26 @@ public @interface Mod
|
||||||
* @return A string listing modids to exclude from loading with this mod.
|
* @return A string listing modids to exclude from loading with this mod.
|
||||||
*/
|
*/
|
||||||
String modExclusionList() default "";
|
String modExclusionList() default "";
|
||||||
|
/**
|
||||||
|
* Specifying this field allows for a mod to expect a signed jar with a fingerprint matching this value.
|
||||||
|
* The fingerprint should be SHA-1 encoded, lowercase with ':' removed. An empty value indicates that
|
||||||
|
* the mod is not expecting to be signed.
|
||||||
|
*
|
||||||
|
* Any incorrectness of the fingerprint, be it missing or wrong, will result in the {@link FingerprintWarning}
|
||||||
|
* method firing <i>prior to any other event on the mod</i>.
|
||||||
|
*
|
||||||
|
* @return A certificate fingerprint that is expected for this mod.
|
||||||
|
*/
|
||||||
|
String certificateFingerprint() default "";
|
||||||
|
/**
|
||||||
|
* Mark the designated method as to be called at if there is something wrong with the certificate fingerprint of
|
||||||
|
* the mod's jar, or it is missing, or otherwise a problem.
|
||||||
|
* @author cpw
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface FingerprintWarning {}
|
||||||
/**
|
/**
|
||||||
* Mark the designated method as being called at the "pre-initialization" phase
|
* Mark the designated method as being called at the "pre-initialization" phase
|
||||||
* @author cpw
|
* @author cpw
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package cpw.mods.fml.common.event;
|
package cpw.mods.fml.common.event;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.security.CodeSource;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -88,4 +90,25 @@ public class FMLPreInitializationEvent extends FMLStateEvent
|
||||||
log.setParent(FMLLog.getLogger());
|
log.setParent(FMLLog.getLogger());
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the FML signing certificates, if any. Validate these against the
|
||||||
|
* published FML certificates in your mod, if you wish.
|
||||||
|
*
|
||||||
|
* @return Certificates used to sign FML and Forge
|
||||||
|
*/
|
||||||
|
public Certificate[] getFMLSigningCertificates()
|
||||||
|
{
|
||||||
|
CodeSource codeSource = getClass().getClassLoader().getParent().getClass().getProtectionDomain().getCodeSource();
|
||||||
|
Certificate[] certs = codeSource.getCertificates();
|
||||||
|
if (certs == null)
|
||||||
|
{
|
||||||
|
return new Certificate[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return certs;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue