diff --git a/src/main/java/li/cil/oc/api/API.java b/src/main/java/li/cil/oc/api/API.java index 50189f915..5e277005b 100644 --- a/src/main/java/li/cil/oc/api/API.java +++ b/src/main/java/li/cil/oc/api/API.java @@ -1,11 +1,7 @@ package li.cil.oc.api; -import li.cil.oc.api.detail.DriverAPI; -import li.cil.oc.api.detail.FileSystemAPI; -import li.cil.oc.api.detail.ItemAPI; -import li.cil.oc.api.detail.MachineAPI; -import li.cil.oc.api.detail.ManualAPI; -import li.cil.oc.api.detail.NetworkAPI; +import com.typesafe.config.Config; +import li.cil.oc.api.detail.*; /** * Central reference for the API. @@ -16,7 +12,7 @@ import li.cil.oc.api.detail.NetworkAPI; */ public class API { public static final String ID_OWNER = "OpenComputers|Core"; - public static final String VERSION = "5.2.3"; + public static final String VERSION = "5.4.0"; public static DriverAPI driver = null; public static FileSystemAPI fileSystem = null; @@ -24,4 +20,6 @@ public class API { public static MachineAPI machine = null; public static ManualAPI manual = null; public static NetworkAPI network = null; + + public static Config config = null; } diff --git a/src/main/java/li/cil/oc/api/IMC.java b/src/main/java/li/cil/oc/api/IMC.java new file mode 100644 index 000000000..39beb10e3 --- /dev/null +++ b/src/main/java/li/cil/oc/api/IMC.java @@ -0,0 +1,339 @@ +package li.cil.oc.api; + +import cpw.mods.fml.common.event.FMLInterModComms; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import org.apache.commons.lang3.tuple.Pair; + +/** + * This is a pure utility class to more comfortably register things that can + * only be registered using IMC. + *
+ * Use this if you have some kind of abstraction layer in place anyway, and can + * safely use the API without class not found exceptions and such, and don't + * want to put together the IMC messages manually. + * + * This also servers to document of all IMC messages OpenComputers handles. + * + * Feel free to copy these functions into your own code, just please don't + * copy this class while keeping the package name, to avoid conflicts if this + * class gets updated. + */ +public final class IMC { + /** + * Register a callback that is used as a filter for assembler templates. + * Any templates that require a base item that is rejected by any + * registered filter will be disabled. For example, if a filter rejects the + * computer case item stacks, robots can not be assembled. + * + * Signature of callbacks must be: + *+ * boolean callback(ItemStack stack) + *+ * + * Callbacks must be declared as packagePath.className.methodName. + * For example: com.example.Integration.callbackMethod. + * + * @param callback the callback to register as a filtering method. + */ + public static void registerAssemblerFilter(String callback) { + FMLInterModComms.sendMessage(MOD_ID, "registerAssemblerFilter", callback); + } + + /** + * Register a new template for the assembler. + * + * Signature of callbacks must be: + *
+ * boolean select(ItemStack stack) + * Object[] validate(IInventory inventory) + * Object[] assemble(IInventory inventory) + *+ * Values in the array returned by validate must be one of the following: + *
+ * // Valid or not. + * new Object[]{Boolean} + * // Valid or not, text for progess bar. + * new Object[]{Boolean, IChatComponent} + * // Valid or not, text for progess bar, warnings for start button tooltip (one per line). + * new Object[]{Boolean, IChatComponent, IChatComponent[]} + *+ * Values in the array returned by assemble must be one of the following: + *
+ * // The assembled device. + * new Object[]{ItemStack} + * // The assembled device and energy cost (which also determines assembly duration). + * new Object[]{ItemStack, Number} + *+ * + * Callbacks must be declared as packagePath.className.methodName. + * For example: com.example.Integration.callbackMethod. + * + * @param name the name of the device created using the + * template. Optional, only used in logging. + * @param select callback used to determine if the template + * applies to a base item. For example, the robot + * template returns true from this if the passed + * item stack is a computer case. + * @param validate callback used to determine if the template + * configuration is valid. Once a template is + * valid assembly can be started, but not before. + * @param assemble callback used to apply a template and create a + * device from it. + * @param host the class of the device being assembled, i.e. + * the host class for the components being + * installed in the device. Used for filtering + * eligible components. See {@link #blacklistHost}. + * @param containerTiers the tiers of the container slots provided by the + * template. The length determines the number of + * containers. Maximum number is three. + * @param upgradeTiers the tiers of the upgrade slots provided by the + * template. The length determines the number of + * upgrades. Maximum number is nine. + * @param componentSlots the types and tiers of component slots provided by + * this template. May contain null entries + * to skip slots (slots are ordered top-to-bottom, + * left-to-right). For example, a robot template + * with only two card slots will pass null + * for the third component slot. Up to nine. + */ + public static void registerAssemblerTemplate(String name, String select, String validate, String assemble, Class host, int[] containerTiers, int[] upgradeTiers, Iterable
+ * boolean select(ItemStack stack) + * ItemStack[] disassemble(ItemStack stack, ItemStack[] ingredients) + *+ * + * Callbacks must be declared as packagePath.className.methodName. + * For example: com.example.Integration.callbackMethod. + * + * @param name the name of the handler (e.g. name of the item + * being handled). Optional, only used in logging. + * @param select callback used to determine if the template + * applies to an item. + * @param disassemble callback used to apply a template and extract + * ingredients from an item. + */ + public static void registerDisassemblerTemplate(String name, String select, String disassemble) { + final NBTTagCompound nbt = new NBTTagCompound(); + if (name != null) { + nbt.setString("name", name); + } + nbt.setString("select", select); + nbt.setString("disassemble", disassemble); + + FMLInterModComms.sendMessage(MOD_ID, "registerDisassemblerTemplate", nbt); + } + + /** + * Register a callback for providing tool durability information. + * + * If your provider does not handle a tool/item, return Double.NaN + * to indicate that another provider should be queried. The first value + * that isn't NaN will be used as the durability. + * + * The returned value must be the relative durability of the tool, + * in a range of [0,1], with 0 being broken, 1 being new/fully repaired. + * + * Signature of callbacks must be: + *
+ * double callback(ItemStack stack) + *+ * + * Callbacks must be declared as packagePath.className.methodName. + * For example: com.example.Integration.callbackMethod. + * + * @param callback the callback to register as a durability provider. + */ + public static void registerToolDurabilityProvider(String callback) { + FMLInterModComms.sendMessage(MOD_ID, "registerToolDurabilityProvider", callback); + } + + /** + * Register a callback handling a wrench tool. + * + * These are used when determining whether an item is a wrench tool, when + * interacting with certain blocks while the player is holding such an item, + * for example to avoid rotating blocks when opening their GUI. + * + * The returned value must be true if the wrench was used/usable, + * false otherwise. + * + * Signature of callbacks must be: + *
+ * boolean callback(EntityPlayer player, int x, int y, int z, boolean changeDurability) + *+ * + * Callbacks must be declared as packagePath.className.methodName. + * For example: com.example.Integration.callbackMethod. + * + * @param callback the callback to register as a wrench tool handler. + */ + public static void registerWrenchTool(String callback) { + FMLInterModComms.sendMessage(MOD_ID, "registerWrenchTool", callback); + } + + /** + * Register a handler for items that can be charged. + * + * This is used by the charger to determine whether items can be charged + * by it (canCharge) and to actually charge them (charge). + * + * Note that OpenComputers comes with a few built-in handlers for third- + * party charged items, such as Redstone Flux and IndustrialCraft 2. + * + * Signature of callbacks must be: + *
+ * boolean canCharge(ItemStack stack) + * double charge(ItemStack stack, double amount, boolean simulate) + *+ * + * Callbacks must be declared as packagePath.className.methodName. + * For example: com.example.Integration.callbackMethod. + * + * @param name the name of the energy system/item type handled. + * @param canCharge the callback to register for checking chargeability. + * @param charge the callback to register for charging items. + */ + public static void registerItemCharge(String name, String canCharge, String charge) { + final NBTTagCompound nbt = new NBTTagCompound(); + nbt.setString("name", name); + nbt.setString("canCharge", canCharge); + nbt.setString("charge", charge); + FMLInterModComms.sendMessage(MOD_ID, "registerItemCharge", nbt); + } + + /** + * Register a provider for ink usable in the 3D printer. + * + * Default providers in OpenComputers are one for the ink cartridges as + * well as one for arbitrary dyes (via the OreDictionary). + * + * Use this to make other items usable as ink in the 3D printer. Return a + * value larger than zero to indicate you handled the provided item stack, + * with the value being the amount of ink provided by the stack. + * + * Signature of callbacks must be: + *
+ * int callback(ItemStack stack) + *+ * + * Callbacks must be declared as packagePath.className.methodName. + * For example: com.example.Integration.callbackMethod. + * + * @param callback the callback to register as an ink provider. + */ + public static void registerInkProvider(String callback) { + FMLInterModComms.sendMessage(MOD_ID, "registerInkProvider", callback); + } + + /** + * Blacklist a ComputerCraft peripheral from being wrapped by OpenComputers' + * built-in driver for ComputerCraft peripherals. + * + * Use this if you provide a driver for something that is a peripheral and + * wish to avoid conflicts in the registered callbacks, for example. + * + * @param peripheral the class of the peripheral to blacklist. + */ + public static void blacklistPeripheral(Class peripheral) { + FMLInterModComms.sendMessage(MOD_ID, "blacklistPeripheral", peripheral.getName()); + } + + /** + * Blacklist an item for a specified host. + * + * This can be used to prevent certain components to be installed in select + * devices, via the devices class. For example, this is used to prevent + * components that would not be functional in certain devices to be + * installed in those devices, such as graphics cards in micro-controllers. + * + * The host class is the class of the environment the component would be + * installed in, e.g. {@link li.cil.oc.api.internal.Tablet}. + * + * @param name the name of the component being blacklisted. + * @param host the class of the host to blacklist the component for. + * @param stack the item stack representing the blacklisted component. + */ + public static void blacklistHost(String name, Class host, ItemStack stack) { + final NBTTagCompound nbt = new NBTTagCompound(); + nbt.setString("name", name); + nbt.setString("host", host.getName()); + final NBTTagCompound stackNbt = new NBTTagCompound(); + stack.writeToNBT(stackNbt); + nbt.setTag("item", stackNbt); + FMLInterModComms.sendMessage(MOD_ID, "blacklistHost", nbt); + } + + // ----------------------------------------------------------------------- // + + private static final String MOD_ID = "OpenComputers"; + + private IMC() { + } +} diff --git a/src/main/scala/li/cil/oc/common/IMC.scala b/src/main/scala/li/cil/oc/common/IMC.scala index 14bb196f0..9a0703129 100644 --- a/src/main/scala/li/cil/oc/common/IMC.scala +++ b/src/main/scala/li/cil/oc/common/IMC.scala @@ -4,6 +4,7 @@ import java.lang.reflect.Method import java.lang.reflect.Modifier import com.typesafe.config.Config +import cpw.mods.fml.common.FMLLog import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent import li.cil.oc.OpenComputers import li.cil.oc.Settings @@ -47,7 +48,9 @@ object IMC { } } else if (message.key == "requestSettings" && message.isStringMessage) { + // TODO Remove in OC 1.6 OpenComputers.log.info(s"Got a request for our configuration from mod ${message.getSender}.") + FMLLog.bigWarning("The IMC message `requestSettings` is deprecated. Use `li.cil.oc.api.API.config` instead.") try tryInvokeStaticVoid(getStaticMethod(message.getStringValue, classOf[Config]), Settings.get.config) catch { case t: Throwable => OpenComputers.log.warn("Failed sending config.", t) } diff --git a/src/main/scala/li/cil/oc/common/Proxy.scala b/src/main/scala/li/cil/oc/common/Proxy.scala index f8bc531b6..1f2d0e71e 100644 --- a/src/main/scala/li/cil/oc/common/Proxy.scala +++ b/src/main/scala/li/cil/oc/common/Proxy.scala @@ -64,6 +64,8 @@ class Proxy { api.API.machine = machine.Machine api.API.network = network.Network + api.API.config = Settings.get.config + api.Machine.LuaArchitecture = if (LuaStateFactory.isAvailable && !Settings.get.forceLuaJ) classOf[NativeLuaArchitecture] else classOf[LuaJLuaArchitecture]