private Set<ASMData> unpackInterfaces(Set<ASMData> packedInterfaces) { Set<ASMData> result = Sets.newHashSet(); for (ASMData data : packedInterfaces) { @SuppressWarnings("unchecked") List<Map<String,Object>> packedList = (List<Map<String,Object>>) data.getAnnotationInfo().get("value"); for (Map<String,Object> packed : packedList) { ASMData newData = data.copy(packed); result.add(newData); } } return result; }
public void addRoot(ASMData asmData) { Map<String, Object> annotationInfo = asmData.getAnnotationInfo(); String packageName = asmData.getClassName(); int pkgIndex = packageName.lastIndexOf('.'); if (pkgIndex > -1) packageName = packageName.substring(0, pkgIndex); packageName = packageName.replace(".", "/"); if (!containerMap.containsKey(packageName)) { DPLogger.info("Discovered config controller inside: " + packageName); File defaultConfig = getConfigForPackage(annotationInfo); DPLogger.info("Setting config: " + defaultConfig); containerMap.put(packageName, new ConfigContainer(defaultConfig)); } else { DPLogger.warning("Config controller discovered in the same root: " + packageName); DPLogger.warning("THIS IS AN ERROR! Ignoring " + asmData.getClassName()); } }
public void processAllClasses(ASMDataTable dataTable, Map<Class<? extends Annotation>, Class<? extends ConfigEntry<? extends Annotation, ?>>> staticMap) { for (Map.Entry<Class<? extends Annotation>, Class<? extends ConfigEntry<? extends Annotation, ?>>> entry : staticMap.entrySet()) { try { annotationMap.put(entry.getKey(), entry.getValue().newInstance().setConfig(config)); } catch (InstantiationException | IllegalAccessException e) { DPLogger.severe("Failed to create instance of the registered ConfigEntry!", e); } } ArrayList<String> processedClasses = new ArrayList<>(); for (Class<? extends Annotation> clazz : annotationMap.keySet()) { for (ASMData asmData : dataTable.getAll(clazz.getName())) { String className = asmData.getClassName(); if (childClasses.contains(className) && !processedClasses.contains(className)) { processedClasses.add(className); processClass(className); } } } }
public void addRoot(ASMData asmData) { Map<String, Object> annotationInfo = asmData.getAnnotationInfo(); String packageName = asmData.getClassName(); int pkgIndex = packageName.lastIndexOf('.'); if (pkgIndex > -1) packageName = packageName.substring(0, pkgIndex); packageName = packageName.replace(".", "/"); if (!containerMap.containsKey(packageName)) { CoreProperties.logger.info("Discovered config controller inside: {}", packageName); File defaultConfig = getConfigForPackage(annotationInfo); CoreProperties.logger.info("Setting config: {}", defaultConfig); containerMap.put(packageName, new ConfigContainer(defaultConfig)); } else { CoreProperties.logger.warn("Config controller discovered in the same root: {}. ", packageName); CoreProperties.logger.warn("THIS IS AN ERROR! Ignoring {}", asmData.getClassName()); } }
public void processAllClasses(ASMDataTable dataTable, Map<Class<? extends Annotation>, Class<? extends ConfigEntry<? extends Annotation, ?>>> staticMap) { for (Map.Entry<Class<? extends Annotation>, Class<? extends ConfigEntry<? extends Annotation, ?>>> entry : staticMap.entrySet()) { try { annotationMap.put(entry.getKey(), entry.getValue().newInstance().setConfig(config)); } catch (InstantiationException | IllegalAccessException e) { CoreProperties.logger.fatal("Failed to create instance of the registered ConfigEntry!", e); } } ArrayList<String> processedClasses = new ArrayList<>(); for (Class<? extends Annotation> clazz : annotationMap.keySet()) { for (ASMData asmData : dataTable.getAll(clazz.getName())) { String className = asmData.getClassName(); if (childClasses.contains(className) && !processedClasses.contains(className)) { processedClasses.add(className); processClass(className); } } } }
public void initTable(ASMDataTable dataTable) { optionals = ArrayListMultimap.create(); Set<ASMData> interfaceLists = dataTable.getAll("cpw.mods.fml.common.Optional$InterfaceList"); addData(unpackInterfaces(interfaceLists)); Set<ASMData> interfaces = dataTable.getAll("cpw.mods.fml.common.Optional$Interface"); addData(interfaces); Set<ASMData> methods = dataTable.getAll("cpw.mods.fml.common.Optional$Method"); addData(methods); }
private void addData(Set<ASMData> interfaces) { for (ASMData data : interfaces) { optionals.put(data.getClassName(),data); } }
@Subscribe public void constructMod(FMLConstructionEvent event) { log.info("LambdaLib|Core is loading."); // Get annotation information from forge asm data table. // This must be done before PreInit stage. ASMDataTable data = event.getASMHarvestedData(); Set<String> removedClasses = Sets.newHashSet(); { // Get removed classes String startupSide = FMLCommonHandler.instance().getSide().toString(); Set<ASMData> sideData = data.getAll("cpw.mods.fml.relauncher.SideOnly"); for (ASMData ad : sideData) if (ad.getClassName().equals(ad.getObjectName())) { // If is a class EnumHolder enumHolder = (EnumHolder) ad.getAnnotationInfo().get("value"); try { String value = (String) ehFieldValue.get(enumHolder); if (!value.equals(startupSide)) { removedClasses.add(ad.getClassName()); } } catch (IllegalAccessException ex) { throw Throwables.propagate(ex); } } } LLModContainer.removedClasses.addAll(removedClasses); Set<String> registrants = mapToClass(data.getAll("cn.lambdalib.annoreg.core.Registrant")); registrants.removeAll(removedClasses); RegistrationManager.INSTANCE.annotationList(registrants); Set<String> registryTypes = mapToClass(data.getAll("cn.lambdalib.annoreg.core.RegistryTypeDecl")); registryTypes.removeAll(removedClasses); RegistrationManager.INSTANCE.addRegistryTypes(registryTypes); Set<String> registryMods = mapToClass(data.getAll("cn.lambdalib.annoreg.core.RegistrationMod")); registryMods.removeAll(removedClasses); RegistrationManager.INSTANCE.addAnnotationMod(registryMods); }
public void parseControllers(FMLPreInitializationEvent event) { if (init) return; init = true; ASMDataTable asmDataTable = event.getAsmData(); Set<ASMData> asmDataSet = asmDataTable.getAll(Controller.class.getName()); // Filters out all controller annotations and places them with their associated mod. for (ASMData data : asmDataSet) { ModCandidate candidate = data.getCandidate(); for (ModContainer modContainer : candidate.getContainedMods()) { String modId = modContainer.getModId(); if (!configMap.containsKey(modId)) configMap.put(modId, new ConfigData(modContainer, candidate.getClassList())); configMap.get(modId).addRoot(data); } } // Process all potential registrars first. for (ConfigData configValue : configMap.values()) if (configValue.isRegistrar) configValue.processIConfigRegistrar(this); processed = true; for (ConfigData configData : configMap.values()) { // Organise all sub-packages. configData.processRoots(); // Process all current classes associated with the ConfigContainer. configData.processConfigContainers(asmDataTable, annotationMap); } postProcessed = true; }
public NetworkModHandler(ModContainer container, Class<?> networkModClass, ASMDataTable table) { this(container, networkModClass.getAnnotation(NetworkMod.class)); if (this.mod == null) { return; } Set<ASMData> versionCheckHandlers = table.getAnnotationsFor(container).get(NetworkMod.VersionCheckHandler.class.getName()); String versionCheckHandlerMethod = null; for (ASMData vch : versionCheckHandlers) { if (vch.getClassName().equals(networkModClass.getName())) { versionCheckHandlerMethod = vch.getObjectName(); versionCheckHandlerMethod = versionCheckHandlerMethod.substring(0,versionCheckHandlerMethod.indexOf('(')); break; } } if (versionCheckHandlerMethod != null) { try { Method checkHandlerMethod = networkModClass.getDeclaredMethod(versionCheckHandlerMethod, String.class); if (checkHandlerMethod.isAnnotationPresent(NetworkMod.VersionCheckHandler.class)) { this.checkHandler = checkHandlerMethod; } } catch (Exception e) { FMLLog.log(Level.WARNING, e, "The declared version check handler method %s on network mod id %s is not accessible", versionCheckHandlerMethod, container.getModId()); } } configureNetworkMod(container); }
private Set<ASMData> unpackInterfaces(Set<ASMData> packedInterfaces) { Set<ASMData> result = Sets.newHashSet(); for (ASMData data : packedInterfaces) { List<Map<String,Object>> packedList = (List<Map<String,Object>>) data.getAnnotationInfo().get("value"); for (Map<String,Object> packed : packedList) { ASMData newData = data.copy(packed); result.add(newData); } } return result; }
public void loadFeatureGroupsFromAnnotations(ASMDataTable asmData) { for (ASMData fgAnnotation : asmData.getAll(FeatureGroup.class.getName())) { @SuppressWarnings("unchecked") final List<String> featureGroups = (List<String>)fgAnnotation.getAnnotationInfo().get("value"); for (String featureGroup : featureGroups) ensureExists(featureGroup); } }
public static void inject(ModContainer mod, ASMDataTable data, Side side, ILanguageAdapter languageAdapter) { FMLLog.fine("Attempting to inject @SidedProxy classes into %s", mod.getModId()); Set<ASMData> targets = data.getAnnotationsFor(mod).get(SidedProxy.class.getName()); ClassLoader mcl = Loader.instance().getModClassLoader(); for (ASMData targ : targets) { try { Class<?> proxyTarget = Class.forName(targ.getClassName(), true, mcl); Field target = proxyTarget.getDeclaredField(targ.getObjectName()); if (target == null) { // Impossible? FMLLog.severe("Attempted to load a proxy type into %s.%s but the field was not found", targ.getClassName(), targ.getObjectName()); throw new LoaderException(String.format("Attempted to load a proxy type into %s.%s but the field was not found", targ.getClassName(), targ.getObjectName())); } target.setAccessible(true); SidedProxy annotation = target.getAnnotation(SidedProxy.class); if (!Strings.isNullOrEmpty(annotation.modId()) && !annotation.modId().equals(mod.getModId())) { FMLLog.fine("Skipping proxy injection for %s.%s since it is not for mod %s", targ.getClassName(), targ.getObjectName(), mod.getModId()); continue; } String targetType = side.isClient() ? annotation.clientSide() : annotation.serverSide(); Object proxy=Class.forName(targetType, true, mcl).newInstance(); if (languageAdapter.supportsStatics() && (target.getModifiers() & Modifier.STATIC) == 0 ) { FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the field is not static", targetType, targ.getClassName(), targ.getObjectName()); throw new LoaderException(String.format("Attempted to load a proxy type %s into %s.%s, but the field is not static", targetType, targ.getClassName(), targ.getObjectName())); } if (!target.getType().isAssignableFrom(proxy.getClass())) { FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, targ.getClassName(), targ.getObjectName()); throw new LoaderException(String.format("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, targ.getClassName(), targ.getObjectName())); } languageAdapter.setProxy(target, proxyTarget, proxy); } catch (Exception e) { FMLLog.log(Level.ERROR, e, "An error occured trying to load a proxy into %s.%s", targ.getAnnotationInfo(), targ.getClassName(), targ.getObjectName()); throw new LoaderException(e); } } // Allow language specific proxy injection. languageAdapter.setInternalProxies(mod, side, mcl); }
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) { String lookupName = name; if(name.endsWith("$class")) { lookupName = name.substring(0, name.length() - 6); } if (optionals == null || !optionals.containsKey(lookupName)) { return basicClass; } ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); classReader.accept(classNode, 0); if (logDebugInfo) FMLRelaunchLog.finer("Optional removal - found optionals for class %s - processing", name); for (ASMData optional : optionals.get(lookupName)) { String modId = (String) optional.getAnnotationInfo().get("modid"); if (Loader.isModLoaded(modId) || ModAPIManager.INSTANCE.hasAPI(modId)) { if (logDebugInfo) FMLRelaunchLog.finer("Optional removal skipped - mod present %s", modId); continue; } if (logDebugInfo) FMLRelaunchLog.finer("Optional on %s triggered - mod missing %s", name, modId); if (optional.getAnnotationInfo().containsKey("iface")) { Boolean stripRefs = (Boolean)optional.getAnnotationInfo().get("striprefs"); if (stripRefs == null) stripRefs = Boolean.FALSE; stripInterface(classNode,(String)optional.getAnnotationInfo().get("iface"), stripRefs); } else { stripMethod(classNode, (String)optional.getObjectName()); } } if (logDebugInfo) FMLRelaunchLog.finer("Optional removal - class %s processed", name); ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); }
private void parseSimpleFieldAnnotation(SetMultimap<String, ASMData> annotations, String annotationClassName, Function<ModContainer, Object> retreiver) throws IllegalAccessException { String[] annName = annotationClassName.split("\\."); String annotationName = annName[annName.length - 1]; for (ASMData targets : annotations.get(annotationClassName)) { String targetMod = (String) targets.getAnnotationInfo().get("value"); Field f = null; Object injectedMod = null; ModContainer mc = this; boolean isStatic = false; Class<?> clz = modInstance.getClass(); if (!Strings.isNullOrEmpty(targetMod)) { if (Loader.isModLoaded(targetMod)) { mc = Loader.instance().getIndexedModList().get(targetMod); } else { mc = null; } } if (mc != null) { try { clz = Class.forName(targets.getClassName(), true, Loader.instance().getModClassLoader()); f = clz.getDeclaredField(targets.getObjectName()); f.setAccessible(true); isStatic = Modifier.isStatic(f.getModifiers()); injectedMod = retreiver.apply(mc); } catch (Exception e) { Throwables.propagateIfPossible(e); FMLLog.log(getModId(), Level.WARN, e, "Attempting to load @%s in class %s for %s and failing", annotationName, targets.getClassName(), mc.getModId()); } } if (f != null) { Object target = null; if (!isStatic) { target = modInstance; if (!modInstance.getClass().equals(clz)) { FMLLog.log(getModId(), Level.WARN, "Unable to inject @%s in non-static field %s.%s for %s as it is NOT the primary mod instance", annotationName, targets.getClassName(), targets.getObjectName(), mc.getModId()); continue; } } f.set(target, injectedMod); } } }
private Set<String> mapToClass(Set<ASMData> adset) { return adset.stream().map(ASMData::getClassName).collect(Collectors.toSet()); }
public static void inject(ModContainer mod, ASMDataTable data, Side side, ILanguageAdapter languageAdapter) { FMLLog.fine("Attempting to inject @SidedProxy classes into %s", mod.getModId()); Set<ASMData> targets = data.getAnnotationsFor(mod).get(SidedProxy.class.getName()); ClassLoader mcl = Loader.instance().getModClassLoader(); for (ASMData targ : targets) { try { Class<?> proxyTarget = Class.forName(targ.getClassName(), true, mcl); Field target = proxyTarget.getDeclaredField(targ.getObjectName()); if (target == null) { // Impossible? FMLLog.severe("Attempted to load a proxy type into %s.%s but the field was not found", targ.getClassName(), targ.getObjectName()); throw new LoaderException(); } target.setAccessible(true); SidedProxy annotation = target.getAnnotation(SidedProxy.class); if (!Strings.isNullOrEmpty(annotation.modId()) && !annotation.modId().equals(mod.getModId())) { FMLLog.fine("Skipping proxy injection for %s.%s since it is not for mod %s", targ.getClassName(), targ.getObjectName(), mod.getModId()); continue; } String targetType = side.isClient() ? annotation.clientSide() : annotation.serverSide(); Object proxy=Class.forName(targetType, true, mcl).newInstance(); if (languageAdapter.supportsStatics() && (target.getModifiers() & Modifier.STATIC) == 0 ) { FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the field is not static", targetType, targ.getClassName(), targ.getObjectName()); throw new LoaderException(); } if (!target.getType().isAssignableFrom(proxy.getClass())) { FMLLog.severe("Attempted to load a proxy type %s into %s.%s, but the types don't match", targetType, targ.getClassName(), targ.getObjectName()); throw new LoaderException(); } languageAdapter.setProxy(target, proxyTarget, proxy); } catch (Exception e) { FMLLog.log(Level.ERROR, e, "An error occured trying to load a proxy into %s.%s", targ.getAnnotationInfo(), targ.getClassName(), targ.getObjectName()); throw new LoaderException(e); } } // Allow language specific proxy injection. languageAdapter.setInternalProxies(mod, side, mcl); }