Added computer.getProgramLocations and IMC message to populate the returned table.

This commit is contained in:
Florian Nücke 2016-06-09 21:33:48 +02:00
parent 2874f4720a
commit cf43ca1d86
6 changed files with 108 additions and 13 deletions

View File

@ -4,6 +4,7 @@ import cpw.mods.fml.common.event.FMLInterModComms;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
/** /**
@ -20,6 +21,7 @@ import org.apache.commons.lang3.tuple.Pair;
* copy this class while keeping the package name, to avoid conflicts if this * copy this class while keeping the package name, to avoid conflicts if this
* class gets updated. * class gets updated.
*/ */
@SuppressWarnings("unused")
public final class IMC { public final class IMC {
/** /**
* Register a callback that is used as a filter for assembler templates. * Register a callback that is used as a filter for assembler templates.
@ -37,7 +39,7 @@ public final class IMC {
* *
* @param callback the callback to register as a filtering method. * @param callback the callback to register as a filtering method.
*/ */
public static void registerAssemblerFilter(String callback) { public static void registerAssemblerFilter(final String callback) {
FMLInterModComms.sendMessage(MOD_ID, "registerAssemblerFilter", callback); FMLInterModComms.sendMessage(MOD_ID, "registerAssemblerFilter", callback);
} }
@ -98,7 +100,7 @@ public final class IMC {
* with only two card slots will pass <tt>null</tt> * with only two card slots will pass <tt>null</tt>
* for the third component slot. Up to nine. * 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<Pair<String, Integer>> componentSlots) { public static void registerAssemblerTemplate(final String name, final String select, final String validate, final String assemble, final Class host, final int[] containerTiers, final int[] upgradeTiers, final Iterable<Pair<String, Integer>> componentSlots) {
final NBTTagCompound nbt = new NBTTagCompound(); final NBTTagCompound nbt = new NBTTagCompound();
if (name != null) { if (name != null) {
nbt.setString("name", name); nbt.setString("name", name);
@ -187,7 +189,7 @@ public final class IMC {
* @param disassemble callback used to apply a template and extract * @param disassemble callback used to apply a template and extract
* ingredients from an item. * 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(); final NBTTagCompound nbt = new NBTTagCompound();
if (name != null) { if (name != null) {
nbt.setString("name", name); nbt.setString("name", name);
@ -218,7 +220,7 @@ public final class IMC {
* *
* @param callback the callback to register as a durability provider. * @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); FMLInterModComms.sendMessage(MOD_ID, "registerToolDurabilityProvider", callback);
} }
@ -234,7 +236,7 @@ public final class IMC {
* <p/> * <p/>
* Signature of callbacks must be: * Signature of callbacks must be:
* <pre> * <pre>
* boolean callback(EntityPlayer player, int x, int y, int z, boolean changeDurability) * boolean callback(EntityPlayer player, BlockPos pos, boolean changeDurability)
* </pre> * </pre>
* <p/> * <p/>
* Callbacks must be declared as <tt>packagePath.className.methodName</tt>. * Callbacks must be declared as <tt>packagePath.className.methodName</tt>.
@ -242,7 +244,7 @@ public final class IMC {
* *
* @param callback the callback to register as a wrench tool handler. * @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); 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. * @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); FMLInterModComms.sendMessage(MOD_ID, "registerWrenchToolCheck", callback);
} }
@ -291,7 +293,7 @@ public final class IMC {
* @param canCharge the callback to register for checking chargeability. * @param canCharge the callback to register for checking chargeability.
* @param charge the callback to register for charging items. * @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(); final NBTTagCompound nbt = new NBTTagCompound();
nbt.setString("name", name); nbt.setString("name", name);
nbt.setString("canCharge", canCharge); nbt.setString("canCharge", canCharge);
@ -319,7 +321,7 @@ public final class IMC {
* *
* @param callback the callback to register as an ink provider. * @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); FMLInterModComms.sendMessage(MOD_ID, "registerInkProvider", callback);
} }
@ -332,7 +334,7 @@ public final class IMC {
* *
* @param peripheral the class of the peripheral to blacklist. * @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()); 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 host the class of the host to blacklist the component for.
* @param stack the item stack representing the blacklisted component. * @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(); final NBTTagCompound nbt = new NBTTagCompound();
nbt.setString("name", name); nbt.setString("name", name);
nbt.setString("host", host.getName()); nbt.setString("host", host.getName());
@ -372,6 +374,44 @@ public final class IMC {
FMLInterModComms.sendMessage(MOD_ID, "registerCustomPowerSystem", "true"); FMLInterModComms.sendMessage(MOD_ID, "registerCustomPowerSystem", "true");
} }
/**
* Register a mapping of program name to loot disk.
* <p/>
* 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.
* <p/>
* For Lua programs, this should be the program <em>name</em>, i.e. the file
* name without the <code>.lua</code> extension.
* <p/>
* 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).
* <p/>
* The architecture names for Lua are <code>Lua 5.2</code>, <code>Lua 5.3</code>
* and <code>LuaJ</code> 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"; private static final String MOD_ID = "OpenComputers";

View File

@ -1334,8 +1334,11 @@ local libcomputer = {
beep = function(...) beep = function(...)
return libcomponent.invoke(computer.address(), "beep", ...) return libcomponent.invoke(computer.address(), "beep", ...)
end, end,
getDeviceInfo = function(...) getDeviceInfo = function()
return libcomponent.invoke(computer.address(), "getDeviceInfo", ...) return libcomponent.invoke(computer.address(), "getDeviceInfo")
end,
getProgramLocations = function()
return libcomponent.invoke(computer.address(), "getProgramLocations")
end, end,
getArchitectures = function(...) getArchitectures = function(...)

View File

@ -12,8 +12,11 @@ import li.cil.oc.common.template.DisassemblerTemplates
import li.cil.oc.integration.util.ItemCharge import li.cil.oc.integration.util.ItemCharge
import li.cil.oc.integration.util.Wrench import li.cil.oc.integration.util.Wrench
import li.cil.oc.server.driver.Registry 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.entity.player.EntityPlayer
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagString
import net.minecraftforge.common.util.Constants.NBT import net.minecraftforge.common.util.Constants.NBT
import scala.collection.convert.WrapAsScala._ import scala.collection.convert.WrapAsScala._
@ -91,8 +94,13 @@ object IMC {
} }
} }
else if (message.key == "registerCustomPowerSystem" && message.isStringMessage) { 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" 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 { else {
OpenComputers.log.warn(s"Got an unrecognized or invalid IMC message '${message.key}' from mod ${message.getSender}.") OpenComputers.log.warn(s"Got an unrecognized or invalid IMC message '${message.key}' from mod ${message.getSender}.")
} }

View File

@ -67,9 +67,30 @@ object ModOpenComputers extends ModProxy {
"OpenComputers", "OpenComputers",
"li.cil.oc.integration.opencomputers.ModOpenComputers.canCharge", "li.cil.oc.integration.opencomputers.ModOpenComputers.canCharge",
"li.cil.oc.integration.opencomputers.ModOpenComputers.charge") "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.inkCartridgeInkProvider")
api.IMC.registerInkProvider("li.cil.oc.integration.opencomputers.ModOpenComputers.dyeInkProvider") 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) ForgeChunkManager.setForcedChunkLoadingCallback(OpenComputers, ChunkloaderUpgradeHandler)
FMLCommonHandler.instance.bus.register(EventHandler) FMLCommonHandler.instance.bus.register(EventHandler)

View File

@ -452,6 +452,10 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
}.collect { case Some(kvp) => kvp }.toMap) }.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)) def isExecuting = state.synchronized(state.contains(Machine.State.Running))

View File

@ -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
}