下面列出了怎么用net.minecraftforge.fml.common.ModContainer的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Check if another mod is loaded.
*
* @param modId The modid to check.
* @param version The version of the mod to match (optional).
*/
public boolean isModLoaded(String modId, String version) {
boolean isLoaded = Loader.isModLoaded(modId); // Check for the modid...
if (isLoaded && version != null) { // Check for the specific version...
for (ModContainer modContainer : Loader.instance().getModList()) {
if (modContainer.getModId().equals(modId) && modContainer.getVersion().equals(version)) {
return true;
}
}
return false;
}
return isLoaded;
}
public static void fixResourcePackLocation(ModContainer selfContainer) {
File sourceFile = selfContainer.getSource();
if (sourceFile.isDirectory()) {
AbstractResourcePack resourcePack = getModResourcePack(selfContainer.getModId());
File actualPackRoot = ObfuscationReflectionHelper.getPrivateValue(AbstractResourcePack.class, resourcePack, "field_110597_b");
File expectedPackRoot = getGTCEResourcePackRoot();
if (!expectedPackRoot.getAbsolutePath().equals(actualPackRoot.getAbsolutePath())) {
System.out.println("[GTCE] Found unexpected resource pack path in dev environment");
System.out.println("[GTCE] Expected path: " + expectedPackRoot.getAbsolutePath());
System.out.println("[GTCE] Actual path: " + actualPackRoot.getAbsolutePath());
System.out.println("[GTCE] Fixed resource pack patch automatically.");
ObfuscationReflectionHelper.setPrivateValue(AbstractResourcePack.class, resourcePack, expectedPackRoot, "field_110597_b");
setModResourcePack(selfContainer.getModId(), resourcePack);
}
}
}
public static Set<ModContainer> identifyFromStacktrace(Throwable e) {
Map<File, Set<ModContainer>> modMap = makeModMap();
// Get the set of classes
HashSet<String> classes = new LinkedHashSet<>();
while (e != null) {
for (StackTraceElement element : e.getStackTrace()) {
classes.add(element.getClassName());
}
e = e.getCause();
}
Set<ModContainer> mods = new LinkedHashSet<>();
for (String className : classes) {
Set<ModContainer> classMods = identifyFromClass(className, modMap);
if (classMods != null) mods.addAll(classMods);
}
return mods;
}
private static Map<File, Set<ModContainer>> makeModMap() {
Map<File, Set<ModContainer>> modMap = new HashMap<>();
for (ModContainer mod : Loader.instance().getModList()) {
Set<ModContainer> currentMods = modMap.getOrDefault(mod.getSource(), new HashSet<>());
currentMods.add(mod);
try {
modMap.put(mod.getSource().getCanonicalFile(), currentMods);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
try {
modMap.remove(Loader.instance().getMinecraftModContainer().getSource()); // Ignore minecraft jar (minecraft)
modMap.remove(Loader.instance().getIndexedModList().get("FML").getSource()); // Ignore forge jar (FML, forge)
} catch (NullPointerException ignored) {
// Workaround for https://github.com/MinecraftForge/MinecraftForge/issues/4919
}
return modMap;
}
protected String getModListString() {
if (modListString == null) {
final Set<ModContainer> suspectedMods = ((IPatchedCrashReport) report).getSuspectedMods();
if (suspectedMods == null) {
return modListString = I18n.format("vanillafix.crashscreen.identificationErrored");
}
List<String> modNames = new ArrayList<>();
for (ModContainer mod : suspectedMods) {
modNames.add(mod.getName());
}
if (modNames.isEmpty()) {
modListString = I18n.format("vanillafix.crashscreen.unknownCause");
} else {
modListString = StringUtils.join(modNames, ", ");
}
}
return modListString;
}
/** @reason Adds a list of mods which may have caused the crash to the report. */
@Inject(method = "populateEnvironment", at = @At("TAIL"))
private void afterPopulateEnvironment(CallbackInfo ci) {
systemDetailsCategory.addDetail("Suspected Mods", () -> {
try {
suspectedMods = ModIdentifier.identifyFromStacktrace(cause);
String modListString = "Unknown";
List<String> modNames = new ArrayList<>();
for (ModContainer mod : suspectedMods) {
modNames.add(mod.getName() + " (" + mod.getModId() + ")");
}
if (!modNames.isEmpty()) {
modListString = StringUtils.join(modNames, ", ");
}
return modListString;
} catch (Throwable e) {
return ExceptionUtils.getStackTrace(e).replace("\t", " ");
}
});
}
public void copyAllModules(File directory) {
Map<String, ModContainer> modList = Loader.instance().getIndexedModList();
for (Map.Entry<String, ModContainer> entry : modList.entrySet()) {
for (ModuleInstance module : modules) {
InputStream stream = LibrarianLib.PROXY.getResource(entry.getKey(), "wizmodules/" + module.getNBTKey() + ".json");
if (stream == null) {
Wizardry.LOGGER.error(" > SOMETHING WENT WRONG! Could not read module " + module.getNBTKey() + " from mod jar of '" + entry.getKey() + "'! Report this to the devs on Github!");
continue;
}
try {
FileUtils.copyInputStreamToFile(stream, new File(directory + "/wizmodules/", module.getNBTKey() + ".json"));
Wizardry.LOGGER.info(" > Module " + module.getNBTKey() + " copied successfully from mod jar.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void copyAllRecipes(File directory)
{
Map<String, ModContainer> modList = Loader.instance().getIndexedModList();
for (Map.Entry<String, ModContainer> entry : modList.entrySet() ) {
for (String recipeName : getResourceListing(entry.getKey(), "fire_recipes")) {
if (recipeName.isEmpty()) continue;
InputStream stream = LibrarianLib.PROXY.getResource(entry.getKey(), "fire_recipes/" + recipeName);
if (stream == null) {
Wizardry.LOGGER.fatal(" > SOMETHING WENT WRONG! Could not read recipe " + recipeName + " from mod jar of '" + entry.getKey() + "'! Report this to the devs on Github!");
continue;
}
try {
FileUtils.copyInputStreamToFile(stream, new File(directory, recipeName));
Wizardry.LOGGER.info(" > Fire recipe " + recipeName + " copied successfully from mod jar.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void copyAllRecipes(File directory) {
Map<String, ModContainer> modList = Loader.instance().getIndexedModList();
for (Map.Entry<String, ModContainer> entry : modList.entrySet() ) {
for (String recipeName : getResourceListing(entry.getKey(), "fluid_recipes")) {
if (recipeName.isEmpty()) continue;
InputStream stream = LibrarianLib.PROXY.getResource(entry.getKey(), "fluid_recipes/" + recipeName);
if (stream == null) {
Wizardry.LOGGER.fatal(" > SOMETHING WENT WRONG! Could not read recipe " + recipeName + " from mod jar of '" + entry.getKey() + "'! Report this to the devs on Github!");
continue;
}
try {
FileUtils.copyInputStreamToFile(stream, new File(directory, recipeName));
Wizardry.LOGGER.info(" > Mana recipe " + recipeName + " copied successfully from mod jar.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void parseModItems() {
HashMap<String, ItemStackSet> modSubsets = new HashMap<String, ItemStackSet>();
for (Item item : (Iterable<Item>) Item.itemRegistry) {
UniqueIdentifier ident = GameRegistry.findUniqueIdentifierFor(item);
if(ident == null) {
NEIClientConfig.logger.error("Failed to find identifier for: "+item);
continue;
}
String modId = GameRegistry.findUniqueIdentifierFor(item).modId;
itemOwners.put(item, modId);
ItemStackSet itemset = modSubsets.get(modId);
if(itemset == null)
modSubsets.put(modId, itemset = new ItemStackSet());
itemset.with(item);
}
API.addSubset("Mod.Minecraft", modSubsets.remove("minecraft"));
for(Entry<String, ItemStackSet> entry : modSubsets.entrySet()) {
ModContainer mc = FMLCommonHandler.instance().findContainerFor(entry.getKey());
if(mc == null)
NEIClientConfig.logger.error("Missing container for "+entry.getKey());
else
API.addSubset("Mod."+mc.getName(), entry.getValue());
}
}
@Override
public void perform(Object source, GuiCustom parent)
{
for (ModContainer mod : Loader.instance().getModList())
{
if (mod.getModId().equals(modid))
{
IModGuiFactory guiFactory = FMLClientHandler.instance().getGuiFactoryFor(mod);
if (guiFactory != null)
{
GuiScreen newScreen = guiFactory.createConfigGui(parent);
Minecraft.getMinecraft().displayGuiScreen(newScreen);
}
}
}
}
private void findClasspathMods() {
List<ModContainer> mods = Loader.instance().getActiveModList();
HashSet<String> searched = new HashSet<String>();
for (ModContainer mod : mods) {
File source = mod.getSource();
if(source == null || searched.contains(source.getAbsolutePath()))
continue;
searched.add(source.getAbsolutePath());
if (source.isFile()) {
CodeChickenCorePlugin.logger.debug("Found a mod container %s, examining for codechicken classes", source.getAbsolutePath());
try {
readFromZipFile(source);
} catch (Exception e) {
CodeChickenCorePlugin.logger.error("Failed to scan " + source.getAbsolutePath() + ", the zip file is invalid", e);
}
} else if (source.isDirectory()) {
CodeChickenCorePlugin.logger.debug("Found a minecraft related directory at %s, examining for codechicken classes", source.getAbsolutePath());
readFromDirectory(source, source);
}
}
}
public static String channelName(Object channelKey) {
if (channelKey instanceof String)
return (String) channelKey;
if (channelKey instanceof ModContainer) {
String s = ((ModContainer) channelKey).getModId();
if(s.length() > 20)
throw new IllegalArgumentException("Mod ID ("+s+") too long for use as channel (20 chars). Use a string identifier");
return s;
}
ModContainer mc = FMLCommonHandler.instance().findContainerFor(channelKey);
if (mc != null)
return mc.getModId();
throw new IllegalArgumentException("Invalid channel: " + channelKey);
}
/**
* Needs to be instantiated somewhere in your mod's loading stage.
*/
public IGWSupportNotifier(){
if(FMLCommonHandler.instance().getSide() == Side.CLIENT && !Loader.isModLoaded("IGWMod")) {
File dir = new File(".", "config");
Configuration config = new Configuration(new File(dir, "IGWMod.cfg"));
config.load();
if(config.get(Configuration.CATEGORY_GENERAL, "enable_missing_notification", true, "When enabled, this will notify players when IGW-Mod is not installed even though mods add support.").getBoolean()) {
ModContainer mc = Loader.instance().activeModContainer();
String modid = mc.getModId();
List<ModContainer> loadedMods = Loader.instance().getActiveModList();
for(ModContainer container : loadedMods) {
if(container.getModId().equals(modid)) {
supportingMod = container.getName();
MinecraftForge.EVENT_BUS.register(this);
ClientCommandHandler.instance.registerCommand(new CommandDownloadIGW());
break;
}
}
}
config.save();
}
}
public static String getModIdForEntity(Class<? extends Entity> entity){
if(reflectionFailed) return "minecraft";
if(entityNames == null) {
try {
entityNames = (HashMap<String, ModContainer>)ReflectionHelper.findField(EntityRegistry.class, "entityNames").get(EntityRegistry.instance());
} catch(Exception e) {
IGWLog.warning("IGW-Mod failed to perform reflection! A result of this is that wiki pages related to Entities will not be found. Report to MineMaarten please!");
e.printStackTrace();
reflectionFailed = true;
return "minecraft";
}
}
EntityRegistration entityReg = EntityRegistry.instance().lookupModSpawn(entity, true);
if(entityReg == null) return "minecraft";
ModContainer mod = entityNames.get(entityReg.getEntityName());
if(mod == null) {
IGWLog.info("Couldn't find the owning mod of the entity " + entityReg.getEntityName() + " even though it's registered through the EntityRegistry!");
return "minecraft";
} else {
return mod.getModId().toLowerCase();
}
}
public void unload() {
this.moduleManager.unload();
this.apiManager.unload();
this.commandManager.unload();
this.friendManager.unload();
this.waypointManager.unload();
this.macroManager.unload();
this.tickRateManager.unload();
this.chatManager.unload();
this.ignoredManager.unload();
this.capeManager.unload();
this.joinLeaveManager.unload();
this.hudManager.unload();
this.animationManager.unload();
this.notificationManager.unload();
this.seppukuMainMenu.unload();
this.cameraManager.unload();
this.getEventManager().dispatchEvent(new EventUnload());
ModContainer seppukuModContainer = null;
for (ModContainer modContainer : Loader.instance().getActiveModList()) {
if (modContainer.getModId().equals("seppukumod")) {
seppukuModContainer = modContainer;
}
}
if (seppukuModContainer != null) {
Loader.instance().getActiveModList().remove(seppukuModContainer);
}
Display.setTitle(this.prevTitle);
Minecraft.getMinecraft().ingameGUI.getChatGUI().clearChatMessages(true);
System.gc();
}
private Object getModCause() {
if (suspectedModString == null) {
Set<ModContainer> suspectedMods = ((IPatchedCrashReport) report).getSuspectedMods();
suspectedModString = suspectedMods.isEmpty() ? "" : suspectedMods.iterator().next().getName();
}
return suspectedModString;
}
private String getVanillaFixComment() {
try {
if (Math.random() < 0.01 && !suspectedMods.isEmpty()) {
ModContainer mod = suspectedMods.iterator().next();
String author = mod.getMetadata().authorList.get(0);
return "I blame " + author + ".";
}
} catch (Throwable ignored) {}
return getWittyComment();
}
private static ContentHelper createHelper(CS4Mod mod)
{
ModContainer container = FMLCommonHandler.instance().findContainerFor(mod);
File modDirectory = container.getSource();
return new ContentHelperImpl(container.getModId(), modDirectory);
}
public void loadNewInternalManifest(String... categories) {
Map<String, ModContainer> modList = Loader.instance().getIndexedModList();
for (Map.Entry<String, ModContainer> entry : modList.entrySet()) {
for (String category : categories) {
try {
for (String fileName : ManaRecipes.getResourceListing(entry.getKey(), category)) {
if (fileName.isEmpty()) continue;
InputStream stream = LibrarianLib.PROXY.getResource(entry.getKey(), category + "/" + fileName);
if (stream == null) {
Wizardry.LOGGER.error(" > SOMETHING WENT WRONG! Could not read " + fileName + " in " + category + " from mod jar! Report this to the devs on Github!");
continue;
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(stream, Charset.defaultCharset()))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append('\n');
}
addItemToManifest(category, entry.getKey(), Files.getNameWithoutExtension(fileName), sb.toString().hashCode() + "");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void loadModSubsets() {
ProgressBar bar = ProgressManager.push("Mod Subsets", ForgeRegistries.ITEMS.getKeys().size());
HashMap<String, ItemStackSet> modSubsets = new HashMap<>();
for (Item item : ForgeRegistries.ITEMS) {
try {
ResourceLocation ident = item.getRegistryName();
bar.step(ident.toString());
if (ident == null) {
LogHelper.error("Failed to find identifier for: " + item);
continue;
}
String modId = ident.getResourceDomain();
ItemInfo.itemOwners.put(item, modId);
ItemStackSet itemset = modSubsets.computeIfAbsent(modId, k -> new ItemStackSet());
itemset.with(item);
} catch (Throwable t) {
LogHelper.errorError("Failed to process mod subset item %s %s", t, String.valueOf(item), String.valueOf(item.getRegistryName()));
}
}
ProgressManager.pop(bar);
API.addSubset("Mod.Minecraft", modSubsets.remove("minecraft"));
for (Entry<String, ItemStackSet> entry : modSubsets.entrySet()) {
ModContainer mc = FMLCommonHandler.instance().findContainerFor(entry.getKey());
if (mc == null) {
LogHelper.error("Missing container for " + entry.getKey());
} else {
API.addSubset("Mod." + mc.getName(), entry.getValue());
}
}
}
/**
* Finds the mod container for the mod with the given mod id.
*
* @param modId The id of the mod of the container to search for.
* @return The container associated with the mod of the given id, or the empty optional.
*/
@Nonnull
public static Optional<ModContainer> resolveModContainer(@Nullable String modId) {
return Loader.instance()
.getActiveModList()
.stream()
.filter(c -> Objects.equals(modId, c.getModId()))
.findFirst();
}
/**
* Finds the mod instance for the mod with the given mod id.
*
* @param <T> The type of the mod instance.
* @param modId The id of the mod to find the instance of.
* @param modClass The type token of the mod class.
* @return The instance of the mod with the given mod id and given type, or the empty optional.
*/
@Nonnull
public static <T> Optional<T> resolveModInstance(@Nullable String modId, @Nonnull Class<T> modClass) {
Objects.requireNonNull(modClass);
return resolveModContainer(modId)
.map(ModContainer::getMod)
.filter(modClass::isInstance)
.map(modClass::cast);
}
/**
* Does not add the last 10 px space before the description normally starts
* Ignores empty child mods expecting a background draw overwrite
*/
private static int calcDescY(GuiModList gui, ModContainer mod) {
ModMetadata meta = mod.getMetadata();
int y = 35;
if(!!meta.logoFile.isEmpty() && ReflectionManager.getField(GuiModList.class, ResourceLocation.class, gui, "cachedLogo") != null)
y += 65;
y += 12; // title
y += 40; // necessary lines
if(!meta.credits.isEmpty())
y += 10;
if(!meta.childMods.isEmpty())
y += 10;
return y;
}
protected List<ResourceLocation> getPlatforms()
{
if (platforms.size() == 0)
{
for (ModContainer mc : Loader.instance().getModList())
{
File src = mc.getSource();
if (src == null)
continue;
InputStream is = getClass().getResourceAsStream("/assets/" + mc.getModId() + "/structures/sky_block_platforms.txt");
if (is == null)
continue;
try
{
for (String line : CharStreams.readLines(new InputStreamReader(is)))
{
if (getClass().getResourceAsStream("/assets/" + mc.getModId() + "/structures/" + line + ".nbt") != null)
platforms.add(new ResourceLocation(mc.getModId(), line));
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for (File f : YUNoMakeGoodMap.instance.getStructFolder().listFiles())
{
if (!f.isFile() || !f.getName().endsWith(".nbt"))
continue;
platforms.add(new ResourceLocation("/config/", f.getName().substring(0, f.getName().length() - 4)));
}
}
return platforms;
}
public static void notify(final ModContainer container, final ForgeVersion.Status status, final ComparableVersion target, final Map<ComparableVersion, String> changes, final String url) {
try {
final Map<ModContainer, ForgeVersion.CheckResult> versionMap = getVersionMap();
final ForgeVersion.CheckResult checkResult = getCheckResult(status, target, changes, url);
if (versionMap != null && checkResult != null) {
versionMap.put(container, checkResult);
}
} catch (final Throwable t) {
Reference.logger.error("Failed to notify Forge!", t);
}
}
@SuppressWarnings({ "unchecked" })
private static Map<ModContainer, ForgeVersion.CheckResult> getVersionMap() throws ReflectiveOperationException {
try {
final Field field = ForgeVersion.class.getDeclaredField("results");
field.setAccessible(true);
return (Map<ModContainer, ForgeVersion.CheckResult>) field.get(null);
} catch (final Throwable t) {
Reference.logger.error("Failed to get the version map!", t);
}
return null;
}
public static void registerMod(final ModContainer container, final String forgeVersion) {
REGISTERED_MODS.add(container);
final ModMetadata metadata = container.getMetadata();
if (metadata.description != null) {
metadata.description += "\n---\nCompiled against Forge " + forgeVersion;
}
}
public static ModContainer getModContainer(String modId)
{
for (ModContainer mod : Loader.instance().getActiveModList())
{
if (mod.getModId().equalsIgnoreCase(modId))
{
return mod;
}
}
return null;
}
public static void addModToCheck(ModContainer mod, String url)
{
if (mod == null || url == null || url.isEmpty() || modsToCheck.keySet().contains(mod))
return;
modsToCheck.put(mod, url);
}