@Override public MinecraftCommandWrapper wrapCommand(ICommand command) { ModContainer activeContainer = Loader.instance().activeModContainer(); if (activeContainer == null) { activeContainer = Loader.instance().getMinecraftModContainer(); } return new ForgeMinecraftCommandWrapper((PluginContainer) activeContainer, command); }
void registerSubstitutionAlias(String nameToSubstitute, Type type, Object toReplace) throws ExistingSubstitutionException { type.getRegistry() .addSubstitutionAlias( Loader.instance().activeModContainer().getModId(), nameToSubstitute, toReplace); type.getRegistry().activateSubstitution(nameToSubstitute); }
@Nonnull @Override public Map<Object, Map<Class, Set<Method>>> findSubscribers() { SetMultimap<String, ASMData> allAnnotationsInContainer = asmTable.getAnnotationsFor(Loader.instance().activeModContainer()); if (!allAnnotationsInContainer.containsKey(ForgepathHandler.class.getCanonicalName())) return NO_SUBSCRIBERS; Set<ASMData> asmDataSet = allAnnotationsInContainer.get(ForgepathHandler.class.getName()); // Goddamnit Java and your stupidly long types ImmutableMap.Builder<Object, Map<Class, Set<Method>>> mapBuilder = new ImmutableMap.Builder<Object, Map<Class, Set<Method>>>(); for (ASMData asmData : asmDataSet) { String cname = asmData.getClassName(); Object obj; try { obj = Class.forName(cname).newInstance(); } catch (Exception ex) { continue; // SKIP! } Map<Class, Set<Method>> subscribers = innerLocator.findSubscribers(obj); mapBuilder.put(obj, subscribers); } return mapBuilder.build(); }
public TConstruct() { if (Loader.isModLoaded("Natura")) { log.info("Natura, what are we going to do tomorrow night?"); LogManager.getLogger("Natura").info("TConstruct, we're going to take over the world!"); } else { log.info("Preparing to take over the world"); } }
@Override public Integer getToken(String token, MixinEnvironment env) { if ("FORGE".equals(token)) { return Integer.valueOf(ForgeVersion.getBuildVersion()); } else if ("FML".equals(token)) { String fmlVersion = Loader.instance().getFMLVersionString(); int build = Integer.parseInt(fmlVersion.substring(fmlVersion.lastIndexOf('.') + 1)); return Integer.valueOf(build); } return null; }
public static void revertToFrozen() { if (frozen == null) { FMLLog.warning("Can't revert to frozen GameData state without freezing first."); } else { FMLLog.fine("Reverting to frozen data state."); getMain().set(frozen); } // the id mapping has reverted, fire remap events for those that care about id changes Loader.instance() .fireRemapEvent(ImmutableMap.<String, Integer[]>of(), ImmutableMap.<String, Integer[]>of()); // the id mapping has reverted, ensure we sync up the object holders ObjectHolderRegistry.INSTANCE.applyObjectHolders(); }
/** * Registers a ore item into the dictionary. Raises the registerOre function in all registered * handlers. * * @param name The name of the ore * @param ore The ore's ItemStack */ private static void registerOreImpl(String name, ItemStack ore) { if ("Unknown".equals(name)) return; // prevent bad IDs. if (ore == null || ore.getItem() == null) { FMLLog.bigWarning( "Invalid registration attempt for an Ore Dictionary item with name %s has occurred. The registration has been denied to prevent crashes. The mod responsible for the registration needs to correct this.", name); return; // prevent bad ItemStacks. } int oreID = getOreID(name); // HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to // a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not // aware of the item yet // IT should be noted that -1 will fail the gate further down, if an entry already exists with // value -1 for this name. This is what is broken and being warned about. // APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes // - you can't make them properly until you've registered with the game. ResourceLocation registryName = ore.getItem().delegate.name(); int hash; if (registryName == null) { FMLLog.bigWarning( "A broken ore dictionary registration with name %s has occurred. It adds an item (type: %s) which is currently unknown to the game registry. This dictionary item can only support a single value when" + " registered with ores like this, and NO I am not going to turn this spam off. Just register your ore dictionary entries after the GameRegistry.\n" + "TO USERS: YES this is a BUG in the mod " + Loader.instance().activeModContainer().getName() + " report it to them!", name, ore.getItem().getClass()); hash = -1; } else { hash = GameData.getItemRegistry().getId(registryName); } if (ore.getItemDamage() != WILDCARD_VALUE) { hash |= ((ore.getItemDamage() + 1) << 16); // +1 so 0 is significant } // Add things to the baked version, and prevent duplicates List<Integer> ids = stackToId.get(hash); if (ids != null && ids.contains(oreID)) return; if (ids == null) { ids = Lists.newArrayList(); stackToId.put(hash, ids); } ids.add(oreID); // Add to the unbaked version ore = ore.copy(); idToStack.get(oreID).add(ore); MinecraftForge.EVENT_BUS.post(new OreRegisterEvent(name, ore)); }
public static void register() { if (Loader.isModLoaded("VersionChecker")) { final NBTTagCompound nbt = new NBTTagCompound(); nbt.setString("curseProjectName", CURSE_PROJECT_NAME); nbt.setString("curseFilenameParser", MOD_NAME_TEMPLATE); FMLInterModComms.sendRuntimeMessage(Module.MOD_ID, "VersionChecker", "addVersionCheck", nbt); } if (ModOptions.getOnlineVersionChecking()) { final VersionCheck test = new VersionCheck(); MinecraftForge.EVENT_BUS.register(test); new Thread(test).start(); } }
/** * Prefix the supplied name with the current mod id. * * <p>If no mod id can be determined, minecraft will be assumed. The prefix is separated with a * colon. * * <p>If there's already a prefix, it'll be prefixed again if the new prefix doesn't match the old * prefix, as used by vanilla calls to addObject. * * @param name name to prefix. * @return prefixed name. */ private String addPrefix(String name) { int index = name.lastIndexOf(':'); String oldPrefix = index == -1 ? "" : name.substring(0, index); String prefix; ModContainer mc = Loader.instance().activeModContainer(); if (mc != null) { prefix = mc.getModId(); } else // no mod container, assume minecraft { prefix = "minecraft"; } if (!oldPrefix.equals(prefix)) { name = prefix + ":" + name; } return name; }
public static boolean IsAvailable() { return Loader.isModLoaded("customnpcs"); }
// Modeled after the BuildCraft version check system. public final class VersionCheck implements Runnable { private static final String REMOTE_VERSION_FILE = "https://raw.githubusercontent.com/OreCruncher/BetterRain/master/versions.txt"; private static final int VERSION_CHECK_RETRIES = 3; private static final int VERSION_CHECK_INTERVAL = 10000; public static enum UpdateStatus { UNKNOWN, CURRENT, OUTDATED, COMM_ERROR } public static final SoftwareVersion modVersion = new SoftwareVersion(Module.VERSION); public static SoftwareVersion currentVersion = new SoftwareVersion(); public static UpdateStatus status = UpdateStatus.UNKNOWN; private static final String mcVersion = Loader.instance().getMinecraftModContainer().getVersion(); public static class SoftwareVersion implements Comparable<SoftwareVersion> { public final int major; public final int minor; public final int revision; public final int patch; public final boolean isAlpha; public final boolean isBeta; public SoftwareVersion() { this.major = 0; this.minor = 0; this.revision = 0; this.patch = 0; this.isAlpha = false; this.isBeta = false; } public SoftwareVersion(String versionString) { // This can happen when running in debug if (versionString.charAt(0) == '@') { this.major = 0; this.minor = 0; this.revision = 0; this.patch = 0; this.isAlpha = false; this.isBeta = false; return; } assert versionString != null; assert versionString.length() > 0; isAlpha = StringUtils.containsIgnoreCase(versionString, "ALPHA"); if (isAlpha) versionString = StringUtils.remove(versionString, "ALPHA"); isBeta = StringUtils.containsIgnoreCase(versionString, "BETA"); if (isBeta) versionString = StringUtils.remove(versionString, "BETA"); final String[] parts = StringUtils.split(versionString, "."); final int numComponents = parts.length; assert numComponents >= 3; this.major = Integer.parseInt(parts[0]); this.minor = Integer.parseInt(parts[1]); this.revision = Integer.parseInt(parts[2]); if (numComponents == 4) { this.patch = Integer.parseInt(parts[3]); } else { this.patch = 0; } } @Override public String toString() { final StringBuilder builder = new StringBuilder(); builder.append(this.major).append('.').append(this.minor).append('.').append(this.revision); if (this.patch != 0) builder.append('.').append(this.patch); if (this.isAlpha) builder.append("ALPHA"); if (this.isBeta) builder.append("BETA"); return builder.toString(); } @Override public int compareTo(final SoftwareVersion obj) { if (this.major != obj.major) return this.major - obj.major; if (this.minor != obj.minor) return this.minor - obj.minor; if (this.revision != obj.revision) return this.revision - obj.revision; return this.patch - obj.patch; } } private VersionCheck() {} private static final String CURSE_PROJECT_NAME = "238891"; private static final String MOD_NAME_TEMPLATE = "DynamicSurroundings-1.8.9-[].jar"; public static void register() { if (Loader.isModLoaded("VersionChecker")) { final NBTTagCompound nbt = new NBTTagCompound(); nbt.setString("curseProjectName", CURSE_PROJECT_NAME); nbt.setString("curseFilenameParser", MOD_NAME_TEMPLATE); FMLInterModComms.sendRuntimeMessage(Module.MOD_ID, "VersionChecker", "addVersionCheck", nbt); } if (ModOptions.getOnlineVersionChecking()) { final VersionCheck test = new VersionCheck(); MinecraftForge.EVENT_BUS.register(test); new Thread(test).start(); } } @SubscribeEvent public void playerLogin(final PlayerLoggedInEvent event) { if (event.player instanceof EntityPlayer) { if (status == UpdateStatus.OUTDATED) { final String msg = StatCollector.translateToLocalFormatted( "msg.NewVersionAvailable.dsurround", Module.MOD_NAME, currentVersion, CURSE_PROJECT_NAME); final IChatComponent component = IChatComponent.Serializer.jsonToComponent(msg); event.player.addChatMessage(component); } } } private static void versionCheck() { try { String location = REMOTE_VERSION_FILE; HttpURLConnection conn = null; while (location != null && !location.isEmpty()) { URL url = new URL(location); if (conn != null) { conn.disconnect(); } conn = (HttpURLConnection) url.openConnection(); conn.setRequestProperty( "User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729)"); conn.connect(); location = conn.getHeaderField("Coordinates"); } if (conn == null) { throw new NullPointerException(); } BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = reader.readLine()) != null) { String[] tokens = line.split(":"); if (mcVersion.matches(tokens[0])) { currentVersion = new SoftwareVersion(tokens[1]); break; } } status = UpdateStatus.CURRENT; if (modVersion.compareTo(currentVersion) < 0) status = UpdateStatus.OUTDATED; conn.disconnect(); reader.close(); } catch (Exception e) { ModLog.warn("Unable to read remote version data", e); status = UpdateStatus.COMM_ERROR; } } @Override public void run() { int count = 0; ModLog.info("Checking for newer mod version"); try { do { if (count > 0) { ModLog.info("Awaiting attempt %d", count); Thread.sleep(VERSION_CHECK_INTERVAL); } versionCheck(); count++; } while (count < VERSION_CHECK_RETRIES && status == UpdateStatus.COMM_ERROR); } catch (InterruptedException e) { e.printStackTrace(); } switch (status) { case COMM_ERROR: ModLog.warn("Version check failed"); break; case CURRENT: ModLog.info( "Dynamic Surroundings version [%s] is the same or newer than the current version [%s]", modVersion, currentVersion); break; case OUTDATED: ModLog.warn( "Using outdated version [" + modVersion + "] for Minecraft " + mcVersion + ". Consider updating to " + currentVersion + "."); break; case UNKNOWN: ModLog.warn("Unknown version check status!"); break; default: break; } } }
public static List<String> injectSnapshot( GameDataSnapshot snapshot, boolean injectFrozenData, boolean isLocalWorld) { FMLLog.info( "Injecting existing block and item data into this %s instance", FMLCommonHandler.instance().getEffectiveSide().isServer() ? "server" : "client"); Map<String, Integer[]> remapBlocks = Maps.newHashMap(); Map<String, Integer[]> remapItems = Maps.newHashMap(); LinkedHashMap<String, Integer> missingBlocks = new LinkedHashMap<String, Integer>(); LinkedHashMap<String, Integer> missingItems = new LinkedHashMap<String, Integer>(); getMain().testConsistency(); getMain().iBlockRegistry.dump(); getMain().iItemRegistry.dump(); getMain().iItemRegistry.resetSubstitutionDelegates(); GameDataSnapshot.Entry blocks = snapshot.entries.get("fml:blocks"); GameDataSnapshot.Entry items = snapshot.entries.get("fml:items"); GameData newData = new GameData(); for (int id : blocks.blocked) { newData.block(id); } for (Map.Entry<String, String> entry : blocks.aliases.entrySet()) { newData.iBlockRegistry.addAlias(entry.getKey(), entry.getValue()); } for (Map.Entry<String, String> entry : items.aliases.entrySet()) { newData.iItemRegistry.addAlias(entry.getKey(), entry.getValue()); } for (String entry : blocks.substitutions) { newData.iBlockRegistry.activateSubstitution(entry); } for (String entry : items.substitutions) { newData.iItemRegistry.activateSubstitution(entry); } if (injectFrozenData) { for (String newBlockSubstitution : getMain().blockSubstitutions.keySet()) { if (!blocks.substitutions.contains(newBlockSubstitution)) { newData.iBlockRegistry.activateSubstitution(newBlockSubstitution); } } for (String newItemSubstitution : getMain().itemSubstitutions.keySet()) { if (!items.substitutions.contains(newItemSubstitution)) { newData.iItemRegistry.activateSubstitution(newItemSubstitution); } } } // Clear State map for it's ready for us to register below. GameData.BLOCKSTATE_TO_ID.clear(); // process blocks and items in the world, blocks in the first pass, items in the second // blocks need to be added first for proper ItemBlock handling for (int pass = 0; pass < 2; pass++) { boolean isBlock = (pass == 0); Map<String, Integer> ids = (isBlock ? blocks.ids : items.ids); for (Entry<String, Integer> entry : ids.entrySet()) { String itemName = entry.getKey(); int newId = entry.getValue(); int currId = isBlock ? getMain().iBlockRegistry.getId(itemName) : getMain().iItemRegistry.getId(itemName); if (currId == -1) { FMLLog.info("Found a missing id from the world %s", itemName); (isBlock ? missingBlocks : missingItems).put(entry.getKey(), newId); continue; // no block/item -> nothing to add } else if (currId != newId) { FMLLog.fine( "Fixed %s id mismatch %s: %d (init) -> %d (map).", isBlock ? "block" : "item", itemName, currId, newId); (isBlock ? remapBlocks : remapItems).put(itemName, new Integer[] {currId, newId}); } // register if (isBlock) { currId = newData.registerBlock(getMain().iBlockRegistry.getRaw(itemName), itemName, newId); } else { currId = newData.registerItem(getMain().iItemRegistry.getRaw(itemName), itemName, newId); } if (currId != newId) { throw new IllegalStateException( String.format( "Can't map %s %s to id %d (seen at: %d), already occupied by %s, blocked %b, ItemBlock %b", isBlock ? "block" : "item", itemName, newId, currId, isBlock ? newData.iBlockRegistry.getRaw(newId) : newData.iItemRegistry.getRaw(newId), newData.blockedIds.contains(newId), isBlock ? false : (getMain().iItemRegistry.getRaw(currId) instanceof ItemBlock))); } } } List<String> missedMappings = Loader.instance() .fireMissingMappingEvent( missingBlocks, missingItems, isLocalWorld, newData, remapBlocks, remapItems); if (!missedMappings.isEmpty()) return missedMappings; // If we got here - the load was accepted. We'll load generic repositories here. // Generic registries can fail by returning a missing mapping. missedMappings = newData.loadGenericRegistries(snapshot, getMain()); if (!missedMappings.isEmpty()) return missedMappings; if (injectFrozenData) // add blocks + items missing from the map { Map<String, Integer> newBlocks = frozen.iBlockRegistry.getEntriesNotIn(newData.iBlockRegistry); Map<String, Integer> newItems = frozen.iItemRegistry.getEntriesNotIn(newData.iItemRegistry); if (!newBlocks.isEmpty() || !newItems.isEmpty()) { FMLLog.info("Injecting new block and item data into this server instance."); for (int pass = 0; pass < 2; pass++) { boolean isBlock = pass == 0; Map<String, Integer> missing = (pass == 0) ? newBlocks : newItems; Map<String, Integer[]> remaps = (isBlock ? remapBlocks : remapItems); for (Entry<String, Integer> entry : missing.entrySet()) { String itemName = entry.getKey(); int currId = entry.getValue(); int newId; if (isBlock) { newId = newData.registerBlock(frozen.iBlockRegistry.getRaw(itemName), itemName, currId); } else { newId = newData.registerItem(frozen.iItemRegistry.getRaw(itemName), itemName, currId); } FMLLog.info( "Injected new block/item %s: %d (init) -> %d (map).", itemName, currId, newId); if (newId != currId) // a new id was assigned { remaps.put(itemName, new Integer[] {entry.getValue(), newId}); } } } } } newData.testConsistency(); getMain().set(newData); getMain().iBlockRegistry.dump(); getMain().iItemRegistry.dump(); Loader.instance().fireRemapEvent(remapBlocks, remapItems); // The id map changed, ensure we apply object holders ObjectHolderRegistry.INSTANCE.applyObjectHolders(); return ImmutableList.of(); }
/** * Fix IDs improperly allocated by early versions of the registry, best-effort. * * <p>Items sharing the same ID with a block, but not sharing the same registry name will be * mapped to an unused id. Losing items instead of blocks should minimize the damage. * * @param dataList List containing the IDs to fix */ public static void fixBrokenIds( GameDataSnapshot.Entry blocks, GameDataSnapshot.Entry items, Set<Integer> blockedIds) { BitSet availabilityMap = new BitSet(MAX_ITEM_ID + 1); // reserve all ids occupied by blocks for (Entry<String, Integer> entry : blocks.ids.entrySet()) { availabilityMap.set(entry.getValue()); } Set<Integer> newBlockedIds = new HashSet<Integer>(); Set<String> itemsToRemove = new HashSet<String>(); Map<String, Integer> itemsToRelocate = new HashMap<String, Integer>(); // check all ids occupied by items for (Entry<String, Integer> entry : items.ids.entrySet()) { int oldId = entry.getValue(); String name = entry.getKey(); Item item = getMain().iItemRegistry.getRaw(name); boolean blockThisId = false; // block oldId unless it's used by a block if (item == null) // item no longer available { // can't fix items without reliably checking if they are ItemBlocks FMLLog.warning( "Item %s (old id %d) is no longer available and thus can't be fixed.", name, oldId); itemsToRemove.add(name); blockThisId = true; } else if (item instanceof ItemBlock) { if (blocks.ids.containsKey(name)) // the item was an ItemBlock before { int blockId = blocks.ids.get(name); if (blockId != oldId) // mis-located ItemBlock { // relocate to the matching block FMLLog.warning( "ItemBlock %s (old id %d) doesn't have the same id as its block (%d).", name, oldId, blockId); itemsToRelocate.put(name, blockId); blockThisId = true; } else // intact ItemBlock { availabilityMap.set(oldId); // occupy id } } else // the item hasn't been an ItemBlock before, but it's now { // can't fix these, drop them FMLLog.warning( "Item %s (old id %d) has been migrated to an ItemBlock and can't be fixed.", name, oldId); itemsToRemove.add(name); blockThisId = true; } } else if (availabilityMap.get(oldId)) // normal item, id is already occupied { // remove the item mapping FMLLog.warning( "Item %s (old id %d) is conflicting with another block/item and can't be fixed.", name, oldId); itemsToRemove.add(name); } else // intact Item { availabilityMap.set(oldId); // occupy id } // handle blocking the id from future use if possible (i.e. not used by a conflicting block) // blockThisId requests don't modify availabilityMap, it could only be set by a block (or // another item, which isn't being handled) if (blockThisId && !availabilityMap.get(oldId)) { // there's no block occupying this id, thus block the id from future use // as there may still be ItemStacks in the world referencing it newBlockedIds.add(oldId); availabilityMap.set(oldId); } } if (itemsToRemove.isEmpty() && itemsToRelocate.isEmpty()) return; // nothing to do // confirm String text = "Forge Mod Loader detected that this save is damaged.\n\n" + "It's likely that an automatic repair can successfully restore\n" + "most of it, except some items which may get swapped with others.\n\n" + "A world backup will be created as a zip file in your saves\n" + "directory automatically.\n\n" + itemsToRemove.size() + " items need to be removed.\n" + itemsToRelocate.size() + " items need to be relocated."; boolean confirmed = StartupQuery.confirm(text); if (!confirmed) StartupQuery.abort(); // confirm missing mods causing item removal Set<String> modsMissing = new HashSet<String>(); for (String name : itemsToRemove) { modsMissing.add(name.substring(0, name.indexOf(':'))); } for (Iterator<String> it = modsMissing.iterator(); it.hasNext(); ) { String mod = it.next(); if (mod.equals("minecraft") || Loader.isModLoaded(mod)) it.remove(); } if (!modsMissing.isEmpty()) { text = "Forge Mod Loader detected that " + modsMissing.size() + " mods are missing.\n\n" + "If you continue items previously provided by those mods will be\n" + "removed while repairing this world save.\n\n" + "Missing mods:\n"; for (String mod : modsMissing) text += mod + "\n"; confirmed = StartupQuery.confirm(text); if (!confirmed) StartupQuery.abort(); } // backup try { String skip = System.getProperty("fml.doNotBackup"); if (skip == null || !"true".equals(skip)) { ZipperUtil.backupWorld(); } else { for (int x = 0; x < 10; x++) FMLLog.severe("!!!!!!!!!! UPDATING WORLD WITHOUT DOING BACKUP !!!!!!!!!!!!!!!!"); } } catch (IOException e) { StartupQuery.notify("The world backup couldn't be created.\n\n" + e); StartupQuery.abort(); } // apply fix for (String name : itemsToRemove) { FMLLog.warning("Removed Item %s, old id %d.", name, items.ids.remove(name)); } for (Map.Entry<String, Integer> entry : itemsToRelocate.entrySet()) { int newId = entry.getValue(); int oldId = items.ids.put(entry.getKey(), newId); FMLLog.warning("Remapped Item %s to id %d, old id %d.", entry.getKey(), newId, oldId); } blockedIds.addAll(newBlockedIds); }
@Override public File get() { return Loader.instance().getConfigDir(); }
/** @author canitzp */ public class Compat { public static boolean isTeslaLoaded = Loader.isModLoaded("tesla"); public static boolean isRailcraftLoaded = Loader.isModLoaded("railcraft"); }
@Mod.EventHandler public void onInit(FMLInitializationEvent event) { proxy.init(); isForestryInstalled = Loader.isModLoaded("Forestry"); }