> componentSlots) {
final NBTTagCompound nbt = new NBTTagCompound();
if (name != null) {
nbt.setString("name", name);
@@ -187,7 +189,7 @@ public final class IMC {
* @param disassemble callback used to apply a template and extract
* ingredients from an item.
*/
- public static void registerDisassemblerTemplate(String name, String select, String disassemble) {
+ public static void registerDisassemblerTemplate(final String name, final String select, final String disassemble) {
final NBTTagCompound nbt = new NBTTagCompound();
if (name != null) {
nbt.setString("name", name);
@@ -218,7 +220,7 @@ public final class IMC {
*
* @param callback the callback to register as a durability provider.
*/
- public static void registerToolDurabilityProvider(String callback) {
+ public static void registerToolDurabilityProvider(final String callback) {
FMLInterModComms.sendMessage(MOD_ID, "registerToolDurabilityProvider", callback);
}
@@ -234,7 +236,7 @@ public final class IMC {
*
* Signature of callbacks must be:
*
- * boolean callback(EntityPlayer player, int x, int y, int z, boolean changeDurability)
+ * boolean callback(EntityPlayer player, BlockPos pos, boolean changeDurability)
*
*
* Callbacks must be declared as packagePath.className.methodName.
@@ -242,7 +244,7 @@ public final class IMC {
*
* @param callback the callback to register as a wrench tool handler.
*/
- public static void registerWrenchTool(String callback) {
+ public static void registerWrenchTool(final String callback) {
FMLInterModComms.sendMessage(MOD_ID, "registerWrenchTool", callback);
}
@@ -265,7 +267,7 @@ public final class IMC {
*
* @param callback the callback to register as a wrench tool tester.
*/
- public static void registerWrenchToolCheck(String callback) {
+ public static void registerWrenchToolCheck(final String callback) {
FMLInterModComms.sendMessage(MOD_ID, "registerWrenchToolCheck", callback);
}
@@ -291,7 +293,7 @@ public final class IMC {
* @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) {
+ public static void registerItemCharge(final String name, final String canCharge, final String charge) {
final NBTTagCompound nbt = new NBTTagCompound();
nbt.setString("name", name);
nbt.setString("canCharge", canCharge);
@@ -319,7 +321,7 @@ public final class IMC {
*
* @param callback the callback to register as an ink provider.
*/
- public static void registerInkProvider(String callback) {
+ public static void registerInkProvider(final String callback) {
FMLInterModComms.sendMessage(MOD_ID, "registerInkProvider", callback);
}
@@ -332,7 +334,7 @@ public final class IMC {
*
* @param peripheral the class of the peripheral to blacklist.
*/
- public static void blacklistPeripheral(Class peripheral) {
+ public static void blacklistPeripheral(final Class peripheral) {
FMLInterModComms.sendMessage(MOD_ID, "blacklistPeripheral", peripheral.getName());
}
@@ -351,7 +353,7 @@ public final class IMC {
* @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) {
+ public static void blacklistHost(final String name, final Class host, final ItemStack stack) {
final NBTTagCompound nbt = new NBTTagCompound();
nbt.setString("name", name);
nbt.setString("host", host.getName());
@@ -372,6 +374,44 @@ public final class IMC {
FMLInterModComms.sendMessage(MOD_ID, "registerCustomPowerSystem", "true");
}
+ /**
+ * Register a mapping of program name to loot disk.
+ *
+ * The table of mappings is made available to machines to allow displaying
+ * a message to the user telling her on which floppy disk to find the program
+ * they were trying to run.
+ *
+ * For Lua programs, this should be the program name, i.e. the file
+ * name without the .lua
extension.
+ *
+ * The list of architectures is optional, if it is not specified this mapping
+ * will be made available to all architectures. It allows filtering since
+ * typically programs will be written for one specific architecture type, e.g.
+ * Lua programs will not (directly) work on a MIPS architecture. The name
+ * specified is the in the {@link li.cil.oc.api.machine.Architecture.Name}
+ * annotation of the architecture (also shown in the CPU tooltip).
+ *
+ * The architecture names for Lua are Lua 5.2
, Lua 5.3
+ * and LuaJ
for example.
+ *
+ * @param programName the name of the program.
+ * @param diskLabel the label of the disk the program is on.
+ * @param architectures the names of the architectures this entry applies to.
+ */
+ public static void registerProgramDiskLabel(final String programName, final String diskLabel, final String... architectures) {
+ final NBTTagCompound nbt = new NBTTagCompound();
+ nbt.setString("program", programName);
+ nbt.setString("label", diskLabel);
+ if (architectures != null && architectures.length > 0) {
+ final NBTTagList architecturesNbt = new NBTTagList();
+ for (final String architecture : architectures) {
+ architecturesNbt.appendTag(new NBTTagString(architecture));
+ }
+ nbt.setTag("architectures", architecturesNbt);
+ }
+ FMLInterModComms.sendMessage(MOD_ID, "registerProgramDiskLabel", nbt);
+ }
+
// ----------------------------------------------------------------------- //
private static final String MOD_ID = "OpenComputers";
diff --git a/src/main/resources/assets/opencomputers/lua/machine.lua b/src/main/resources/assets/opencomputers/lua/machine.lua
index 23b3e45b1..3a67047dd 100644
--- a/src/main/resources/assets/opencomputers/lua/machine.lua
+++ b/src/main/resources/assets/opencomputers/lua/machine.lua
@@ -1334,8 +1334,11 @@ local libcomputer = {
beep = function(...)
return libcomponent.invoke(computer.address(), "beep", ...)
end,
- getDeviceInfo = function(...)
- return libcomponent.invoke(computer.address(), "getDeviceInfo", ...)
+ getDeviceInfo = function()
+ return libcomponent.invoke(computer.address(), "getDeviceInfo")
+ end,
+ getProgramLocations = function()
+ return libcomponent.invoke(computer.address(), "getProgramLocations")
end,
getArchitectures = function(...)
diff --git a/src/main/scala/li/cil/oc/common/IMC.scala b/src/main/scala/li/cil/oc/common/IMC.scala
index 7cdd67891..27811148c 100644
--- a/src/main/scala/li/cil/oc/common/IMC.scala
+++ b/src/main/scala/li/cil/oc/common/IMC.scala
@@ -12,8 +12,11 @@ import li.cil.oc.common.template.DisassemblerTemplates
import li.cil.oc.integration.util.ItemCharge
import li.cil.oc.integration.util.Wrench
import li.cil.oc.server.driver.Registry
+import li.cil.oc.server.machine.ProgramLocations
+import li.cil.oc.util.ExtendedNBT._
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
+import net.minecraft.nbt.NBTTagString
import net.minecraftforge.common.util.Constants.NBT
import scala.collection.convert.WrapAsScala._
@@ -91,8 +94,13 @@ object IMC {
}
}
else if (message.key == "registerCustomPowerSystem" && message.isStringMessage) {
+ OpenComputers.log.info(s"Was told there is an unknown power system present by mod ${message.getSender}.")
Settings.get.is3rdPartyPowerSystemPresent = message.getStringValue == "true"
}
+ else if (message.key == "registerProgramDiskLabel" && message.isNBTMessage) {
+ OpenComputers.log.info(s"Registering new program location mapping for program '${message.getNBTValue.getString("program")}' being on disk '${message.getNBTValue.getString("label")}' from mod ${message.getSender}.")
+ ProgramLocations.addMapping(message.getNBTValue.getString("program"), message.getNBTValue.getString("label"), message.getNBTValue.getTagList("architectures", NBT.TAG_STRING).map((tag: NBTTagString) => tag.func_150285_a_()).toArray: _*)
+ }
else {
OpenComputers.log.warn(s"Got an unrecognized or invalid IMC message '${message.key}' from mod ${message.getSender}.")
}
diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala
index d415189a9..097e93f5d 100644
--- a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala
+++ b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala
@@ -67,9 +67,30 @@ object ModOpenComputers extends ModProxy {
"OpenComputers",
"li.cil.oc.integration.opencomputers.ModOpenComputers.canCharge",
"li.cil.oc.integration.opencomputers.ModOpenComputers.charge")
+
api.IMC.registerInkProvider("li.cil.oc.integration.opencomputers.ModOpenComputers.inkCartridgeInkProvider")
api.IMC.registerInkProvider("li.cil.oc.integration.opencomputers.ModOpenComputers.dyeInkProvider")
+ api.IMC.registerProgramDiskLabel("build", "builder", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("dig", "dig", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("base64", "data", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("deflate", "data", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("gpg", "data", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("inflate", "data", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("md5sum", "data", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("sha256sum", "data", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("refuel", "generator", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("pastebin", "internet", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("wget", "internet", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("irc", "irc", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("maze", "maze", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("arp", "network", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("ifconfig", "network", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("ping", "network", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("route", "network", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("opl-flash", "openloader", "Lua 5.2", "Lua 5.3", "LuaJ")
+ api.IMC.registerProgramDiskLabel("oppm", "oppm", "Lua 5.2", "Lua 5.3", "LuaJ")
+
ForgeChunkManager.setForcedChunkLoadingCallback(OpenComputers, ChunkloaderUpgradeHandler)
FMLCommonHandler.instance.bus.register(EventHandler)
diff --git a/src/main/scala/li/cil/oc/server/machine/Machine.scala b/src/main/scala/li/cil/oc/server/machine/Machine.scala
index 0a04b298e..8aaacc6ef 100644
--- a/src/main/scala/li/cil/oc/server/machine/Machine.scala
+++ b/src/main/scala/li/cil/oc/server/machine/Machine.scala
@@ -452,6 +452,10 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
}.collect { case Some(kvp) => kvp }.toMap)
}
+ @Callback(doc = """function():table -- Returns a map of program name to disk label for known programs.""")
+ def getProgramLocations(context: Context, args: Arguments): Array[AnyRef] =
+ result(ProgramLocations.getMappings(Machine.getArchitectureName(architecture.getClass)))
+
// ----------------------------------------------------------------------- //
def isExecuting = state.synchronized(state.contains(Machine.State.Running))
diff --git a/src/main/scala/li/cil/oc/server/machine/ProgramLocations.scala b/src/main/scala/li/cil/oc/server/machine/ProgramLocations.scala
new file mode 100644
index 000000000..d4578a61c
--- /dev/null
+++ b/src/main/scala/li/cil/oc/server/machine/ProgramLocations.scala
@@ -0,0 +1,19 @@
+package li.cil.oc.server.machine
+
+import scala.collection.mutable
+
+object ProgramLocations {
+ final val architectureLocations = mutable.Map.empty[String, mutable.Map[String, String]]
+ final val globalLocations = mutable.Map.empty[String, String]
+
+ def addMapping(program: String, label: String, architectures: String*): Unit = {
+ if (architectures == null || architectures.isEmpty) {
+ globalLocations += (program -> label)
+ }
+ else {
+ architectures.foreach(architectureLocations.getOrElseUpdate(_, mutable.Map.empty[String, String]) += (program -> label))
+ }
+ }
+
+ def getMappings(architecture: String) = architectureLocations.getOrElse(architecture, Iterable.empty) ++ globalLocations
+}