Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8

Conflicts:
	src/main/scala/li/cil/oc/client/Textures.scala
	src/main/scala/li/cil/oc/common/init/Blocks.scala
	src/main/scala/li/cil/oc/common/tileentity/Switch.scala
This commit is contained in:
Florian Nücke 2015-08-23 22:02:17 +02:00
commit f4491f5fc6
42 changed files with 630 additions and 52 deletions

View File

@ -45,12 +45,13 @@ def getGitRef() {
if (System.getenv("BUILD_NUMBER") != null)
version += ".${System.getenv("BUILD_NUMBER")}"
else
version += "-" + getGitRef()
if (config.oc.subversion != null && config.oc.subversion != "")
version += "-${config.oc.subversion}"
if (System.getenv("BUILD_NUMBER") == null)
version += "+" + getGitRef()
ext.simpleVersion = version
version = "MC${config.minecraft.version}-${project.version}"

View File

@ -2,6 +2,8 @@
![AAA](oredict:oc:accessPoint)
*This block is deprecated and will be removed in a future version.* Craft it into a [relay](relay.md) to avoid losing it.
The access point is the wireless version of the [switch](switch.md). It can be used to separate subnetworks so that machines in them will not see [components](../general/computer.md) in other networks, while still allowing to send network messages to the machines in other networks.
In addition to that, this block can act as a repeater: it can re-send wired messages as wired messages to other devices; or wireless messages as wired or wireless messages.

View File

@ -36,10 +36,9 @@ Keep in mind that some of these may not be available, depending on the recipe se
* [Disassembler](disassembler.md)
## Networking
* [Access Point](accessPoint.md)
* [Cable](cable.md)
* [Net Splitter](netSplitter.md)
* [Switch](switch.md)
* [Relay](relay.md)
## Power management
* [Capacitor](capacitor.md)

View File

@ -2,6 +2,6 @@
![*.net *.split](oredict:oc:netSplitter)
The net splitter is a device that allows controlling connectivity between subnetworks. Unlike the [switch](switch.md) or [power converter](powerConverter.md) it directly connects adjacent subnetworks, i.e. components can be accessed. Each side's connectivity can be toggled using a wrench (e.g. the [scrench](../item/wrench.md)). When a redstone signal is applied to the net splitter, all sides' connectivity is inverted.
The net splitter is a device that allows controlling connectivity between subnetworks. Unlike the [relay](relay.md) or [power converter](powerConverter.md) it directly connects adjacent subnetworks, i.e. components can be accessed. Each side's connectivity can be toggled using a wrench (e.g. the [scrench](../item/wrench.md)). When a redstone signal is applied to the net splitter, all sides' connectivity is inverted.
This block can therefore be used to toggle connectivity to certain parts of a component network. Use a [redstone I/O block](redstone.md) or [redstone cards](../item/redstoneCard1.md) to automate the net splitter.

View File

@ -0,0 +1,13 @@
# Relay
![Building bridges.](oredict:oc:relay)
The relay can be used to allow different subnetworks to send network messages to each other, without exposing components to [computers](../general/computer.md) in other networks. Keeping components local is usually a good idea, to avoid [computers](../general/computer.md) using the wrong [screen](screen1.md) or to avoid component overflows to happen (causing [computers](../general/computer.md) to crash and refuse to boot up).
The relay can be upgraded by inserting a [wireless network card](../item/wlanCard.md) to also relay messages wirelessly. Wireless messages can be received and relayed by other relays with a wireless network card, or by [computers](../general/computer.md) with a wireless network card.
Alternatively the relay can be upgraded using [linked cards](../item/linkedCard.md). In this case it will forward messages through the tunnel provided by the linked card, too; at the usual cost, so make sure the relay is sufficiently powered.
Relays do *not* keep track of which packets they forwarded recently, so avoid cycles in your network or you may receive the same packet multiple times. Due to the limited buffer size of relays, sending messages too frequently will result in packet loss. You can upgrade your relays to increase the speed with which they relay messages, as well as their internal message queue size.
Packets are only re-sent a certain number of times, so chaining an arbitrary number of relays is not possible. By default, a packet will be re-sent up to five times.

View File

@ -6,4 +6,4 @@ A server rack houses up to four [servers](../item/server1.md). A [server](../ite
Each [server](../item/server1.md) in a server rack can only communicate with one "face" of the server rack at a time - or none at all. Which side each [server](../item/server1.md) is connected to can be configured in the server rack's GUI. Beware that the sides are from the point of view of the server rack, i.e. if you are looking at the front of the server rack, `sides.right` will be to your left and vice versa.
Server racks act as [switch](switch.md) and [power distributor](powerDistributor.md) in one. The switch mode of the server rack can be configured in its GUI, with the two options being internal and external. In external mode the server rack will behave like a normal [switch](switch.md). In internal mode, messages are only passed to the [servers](../item/server1.md) in the rack, and will not be automatically relayed to the other faces of the rack. [Servers](../item/server1.md) will still be able to send messages to each other. This allows using server racks as advanced [switches](switch.md) that can perform filter and mapping operations, for example.
Server racks act as [relay](relay.md) and [power distributor](powerDistributor.md) in one. The switch mode of the server rack can be configured in its GUI, with the two options being internal and external. In external mode the server rack will behave like a normal [relay](relay.md). In internal mode, messages are only passed to the [servers](../item/server1.md) in the rack, and will not be automatically relayed to the other faces of the rack. [Servers](../item/server1.md) will still be able to send messages to each other. This allows using server racks as advanced [relays](relay.md) that can perform filter and mapping operations, for example.

View File

@ -2,6 +2,8 @@
![Building bridges.](oredict:oc:switch)
*This block is deprecated and will be removed in a future version.* Craft it into a [relay](relay.md) to avoid losing it.
The switch can be used to allow different subnetworks to send network messages to each other, without exposing components to [computers](../general/computer.md) in other networks. Keeping components local is usually a good idea, to avoid [computers](../general/computer.md) using the wrong [screen](screen1.md) or to avoid component overflows to happen (causing [computers](../general/computer.md) to crash and refuse to boot up).
There is also a wireless variation of this block, called the [access point](accessPoint.md), which will also relay messages wirelessly. Wireless messages can be received and relayed by other [access points](accessPoint.md), or by [computers](../general/computer.md) with a [wireless network card](../item/wlanCard.md).

View File

@ -2,4 +2,4 @@
![Enter the network.](oredict:oc:lanCard)
The network card allows [computers](../general/computer.md) to send and receive network messages. Messages (or packets) can be broadcasted to all receiving nodes in a subnetwork, or sent to a specific node with a specified address. [Switches](../block/switch.md) and [access points](../block/accessPoint.md) can be used to bridge multiple subnetworks by relaying messages between the subnetworks they are connected to. It is also possible to send a targeted message if the receiver is in another subnetwork, if the networks are connected via one or more [switches](../block/switch.md).
The network card allows [computers](../general/computer.md) to send and receive network messages. Messages (or packets) can be broadcasted to all receiving nodes in a subnetwork, or sent to a specific node with a specified address. [Relays](../block/relay.md) can be used to bridge multiple subnetworks by relaying messages between the subnetworks they are connected to. It is also possible to send a targeted message if the receiver is in another subnetwork, if the networks are connected via one or more [relays](../block/relay.md).

View File

@ -3,7 +3,7 @@
# Use [nl] to for a line break.
# Blocks
tile.oc.accessPoint.name=Access Point
tile.oc.accessPoint.name=§cAccess Point§7
tile.oc.adapter.name=Adapter
tile.oc.assembler.name=Electronics Assembler
tile.oc.cable.name=Cable
@ -29,13 +29,14 @@ tile.oc.print.name=3D Print
tile.oc.printer.name=3D Printer
tile.oc.raid.name=Raid
tile.oc.redstone.name=Redstone I/O
tile.oc.relay.name=Relay
tile.oc.robot.name=Robot
tile.oc.robotAfterimage.name=Robot
tile.oc.screen1.name=Screen (Tier 1)
tile.oc.screen2.name=Screen (Tier 2)
tile.oc.screen3.name=Screen (Tier 3)
tile.oc.serverRack.name=Server Rack
tile.oc.switch.name=Switch
tile.oc.switch.name=§cSwitch§7
tile.oc.netSplitter.name=Net Splitter
tile.oc.waypoint.name=Waypoint
@ -235,6 +236,7 @@ oc:container.Disassembler=Disassembler
oc:container.DiskDrive=Disk Drive
oc:container.Printer=Printer
oc:container.Raid=Raid
oc:container.Relay=Relay
oc:container.Server=Server
oc:container.ServerRack=Server Rack
oc:container.Switch=Switch
@ -328,6 +330,7 @@ oc:tooltip.RedstoneCard.RedNet=§fRedNet§7 is §asupported§7.
oc:tooltip.RedstoneCard.WirelessCBE=§fWireless Redstone (ChickenBones)§7 is §asupported§7.
oc:tooltip.RedstoneCard.WirelessSV=§fWireless Redstone (SlimeVoid)§7 is §asupported§7.
oc:tooltip.RedstoneCard=Allows reading and emitting redstone signals around the computer or robot.
oc:tooltip.Relay=Allows connecting different networks to each other. Only network messages will be passed along, components will not be visible through this. Use this to separate networks while still allowing communication using Network Cards, for example.
oc:tooltip.Robot=Unlike computers, robots can move around and interact with the world much like a player can.[nl] §cCan not connect to external components.§7
# The underscore makes sure this isn't hidden with the rest of the tooltip.
oc:tooltip.Robot_Level=§fLevel§7: §a%s§7

View File

@ -0,0 +1,8 @@
{
"parent": "block/cube_bottom_top",
"textures": {
"top": "opencomputers:blocks/switch_top",
"bottom": "opencomputers:blocks/generic_top",
"side": "opencomputers:blocks/switch_side"
}
}

View File

@ -0,0 +1,10 @@
{
"parent": "opencomputers:block/relay",
"display": {
"thirdperson": {
"rotation": [ 10, -45, 170 ],
"translation": [ 0, 1.5, -2.75 ],
"scale": [ 0.375, 0.375, 0.375 ]
}
}
}

View File

@ -504,11 +504,6 @@ interweb {
[string, string, string]]
}
accessPoint {
input: [[ingotIron, "oc:wlanCard", ingotIron]
["oc:cable", "oc:lanCard", "oc:cable"]
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]
}
adapter {
input: [[ingotIron, "oc:cable", ingotIron]
["oc:cable", "oc:circuitChip1", "oc:cable"]
@ -607,7 +602,7 @@ powerDistributor {
serverRack {
input: [["oc:circuitChip2", "oc:wlanCard", "oc:circuitChip2"]
[fenceIron, chest, fenceIron]
["oc:switch", "oc:materialCircuitBoardPrinted", "oc:powerDistributor"]]
["oc:relay", "oc:materialCircuitBoardPrinted", "oc:powerDistributor"]]
}
raid {
input: [[nuggetIron, "oc:cpu3", nuggetIron]
@ -619,7 +614,7 @@ redstone {
[blockRedstone, "oc:redstoneCard1", blockRedstone]
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]
}
switch {
relay {
input: [[ingotIron, "oc:cable", ingotIron]
["oc:cable", "oc:lanCard", "oc:cable"]
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]

View File

@ -318,7 +318,7 @@ powerDistributor {
serverRack {
input: [[craftingToolScrewdriver, "oc:wlanCard", craftingToolWrench]
["ic2.reactorVentDiamond", chest, "ic2.reactorVentDiamond"]
["oc:switch", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]]
["oc:relay", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]]
}
redstone {
# 32731 = Activity Detector
@ -326,7 +326,7 @@ redstone {
[{item="gt.metaitem.01", subID=32731}, {block="gt.blockcasings", subID=2}, "oc:redstoneCard1"]
["oc:circuitChip2", "oc:materialCircuitBoardPrinted", "oc:circuitChip2"]]
}
switch {
relay {
input: [["", "oc:lanCard", ""]
["oc:cable", {block="gt.blockcasings", subID=2}, "oc:cable"]
["oc:materialCircuitBoardPrinted", craftingToolWrench, "oc:materialCircuitBoardPrinted"]]

View File

@ -363,14 +363,14 @@ powerDistributor {
serverRack {
input: [["oc:circuitChip3", "oc:wlanCard", "oc:circuitChip3"]
[fenceIron, chest, fenceIron]
["oc:switch", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]]
["oc:relay", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]]
}
redstone {
input: [[ingotIron, "oc:circuitChip3", ingotIron]
[blockRedstone, "oc:redstoneCard1", blockRedstone]
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]
}
switch {
relay {
input: [[ingotIron, "oc:cable", ingotIron]
["oc:cable", "oc:lanCard", "oc:cable"]
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

View File

@ -31,6 +31,7 @@ object Constants {
final val Printer = "printer"
final val Raid = "raid"
final val Redstone = "redstone"
final val Relay = "relay"
final val Robot = "robot"
final val RobotAfterimage = "robotAfterimage"
final val ScreenTier1 = "screen1"

View File

@ -36,12 +36,14 @@ object GuiHandler extends CommonGuiHandler {
new gui.DiskDrive(player.inventory, t)
case t: tileentity.Printer if id == GuiType.Printer.id =>
new gui.Printer(player.inventory, t)
case t: tileentity.Raid if id == GuiType.Raid.id =>
new gui.Raid(player.inventory, t)
case t: tileentity.RobotProxy if id == GuiType.Robot.id =>
new gui.Robot(player.inventory, t.robot)
case t: tileentity.ServerRack if id == GuiType.Rack.id =>
new gui.ServerRack(player.inventory, t)
case t: tileentity.Raid if id == GuiType.Raid.id =>
new gui.Raid(player.inventory, t)
case t: tileentity.Relay if id == GuiType.Relay.id =>
new gui.Relay(player.inventory, t)
case t: tileentity.RobotProxy if id == GuiType.Robot.id =>
new gui.Robot(player.inventory, t.robot)
case t: tileentity.Screen if id == GuiType.Screen.id =>
new gui.Screen(t.origin.buffer, t.tier > 0, () => t.origin.hasKeyboard, () => t.origin.buffer.isRenderingEnabled)
case t: tileentity.Switch if id == GuiType.Switch.id =>

View File

@ -420,7 +420,7 @@ object PacketHandler extends CommonPacketHandler {
}
def onSwitchActivity(p: PacketParser) =
p.readTileEntity[Switch]() match {
p.readTileEntity[traits.SwitchLike]() match {
case Some(t) => t.lastMessage = System.currentTimeMillis()
case _ => // Invalid packet.
}

View File

@ -69,6 +69,7 @@ private[oc] class Proxy extends CommonProxy {
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.ServerRack], ServerRackRenderer)
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Switch], SwitchRenderer)
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.AccessPoint], SwitchRenderer)
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Relay], SwitchRenderer)
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.RobotProxy], RobotRenderer)
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Screen], ScreenRenderer)
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.NetSplitter], NetSplitterRenderer)

View File

@ -59,6 +59,7 @@ object Textures {
val RobotSelection = L("robot_selection")
val Server = L("server")
val Slot = L("slot")
val UpgradeTab = L("upgrade_tab")
val Waypoint = L("waypoint")
override protected def basePath = "textures/gui/%s.png"

View File

@ -0,0 +1,123 @@
package li.cil.oc.client.gui
import java.lang.Iterable
import java.text.DecimalFormat
import java.util
import codechicken.nei.VisiblityData
import codechicken.nei.api.INEIGuiHandler
import codechicken.nei.api.TaggedInventoryArea
import li.cil.oc.Localization
import li.cil.oc.client.Textures
import li.cil.oc.common.container
import li.cil.oc.common.tileentity
import li.cil.oc.integration.Mods
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.client.renderer.Tessellator
import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.Optional
import org.lwjgl.opengl.GL11
import org.lwjgl.util.Rectangle
@Optional.Interface(iface = "codechicken.nei.api.INEIGuiHandler", modid = Mods.IDs.NotEnoughItems)
class Relay(playerInventory: InventoryPlayer, val relay: tileentity.Relay) extends DynamicGuiContainer(new container.Relay(playerInventory, relay)) with INEIGuiHandler {
private val format = new DecimalFormat("#.##hz")
private val tabPosition = new Rectangle(xSize, 10, 23, 26)
override protected def drawSecondaryBackgroundLayer(): Unit = {
super.drawSecondaryBackgroundLayer()
// Tab background.
GL11.glColor4f(1, 1, 1, 1)
Minecraft.getMinecraft.getTextureManager.bindTexture(Textures.GUI.UpgradeTab)
val x = windowX + tabPosition.getX
val y = windowY + tabPosition.getY
val w = tabPosition.getWidth
val h = tabPosition.getHeight
val t = Tessellator.getInstance
val r = t.getWorldRenderer
r.startDrawingQuads()
r.addVertexWithUV(x, y + h, zLevel, 0, 1)
r.addVertexWithUV(x + w, y + h, zLevel, 1, 1)
r.addVertexWithUV(x + w, y, zLevel, 1, 0)
r.addVertexWithUV(x, y, zLevel, 0, 0)
t.draw()
}
override def mouseClicked(mouseX: Int, mouseY: Int, button: Int): Unit = {
// So MC doesn't throw away the item in the upgrade slot when we're trying to pick it up...
val originalWidth = xSize
try {
xSize += tabPosition.getWidth
super.mouseClicked(mouseX, mouseY, button)
}
finally {
xSize = originalWidth
}
}
override def mouseReleased(mouseX: Int, mouseY: Int, button: Int): Unit = {
// So MC doesn't throw away the item in the upgrade slot when we're trying to pick it up...
val originalWidth = xSize
try {
xSize += tabPosition.getWidth
super.mouseReleased(mouseX, mouseY, button)
}
finally {
xSize = originalWidth
}
}
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
super.drawSecondaryForegroundLayer(mouseX, mouseY)
fontRendererObj.drawString(
Localization.localizeImmediately(relay.getName),
8, 6, 0x404040)
fontRendererObj.drawString(
Localization.Switch.TransferRate,
14, 20, 0x404040)
fontRendererObj.drawString(
Localization.Switch.PacketsPerCycle,
14, 39, 0x404040)
fontRendererObj.drawString(
Localization.Switch.QueueSize,
14, 58, 0x404040)
fontRendererObj.drawString(
format.format(20f / inventoryContainer.relayDelay),
108, 20, 0x404040)
fontRendererObj.drawString(
inventoryContainer.packetsPerCycleAvg + " / " + inventoryContainer.relayAmount,
108, 39, thresholdBasedColor(inventoryContainer.packetsPerCycleAvg, math.ceil(inventoryContainer.relayAmount / 2f).toInt, inventoryContainer.relayAmount))
fontRendererObj.drawString(
inventoryContainer.queueSize + " / " + inventoryContainer.maxQueueSize,
108, 58, thresholdBasedColor(inventoryContainer.queueSize, inventoryContainer.maxQueueSize / 2, inventoryContainer.maxQueueSize))
}
private def thresholdBasedColor(value: Int, yellow: Int, red: Int) = {
if (value < yellow) 0x009900
else if (value < red) 0x999900
else 0x990000
}
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
override def modifyVisiblity(gui: GuiContainer, currentVisibility: VisiblityData): VisiblityData = null
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
override def getItemSpawnSlots(gui: GuiContainer, stack: ItemStack): Iterable[Integer] = null
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
override def getInventoryAreas(gui: GuiContainer): util.List[TaggedInventoryArea] = null
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
override def handleDragNDrop(gui: GuiContainer, mouseX: Int, mouseY: Int, stack: ItemStack, button: Int): Boolean = false
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
override def hideItemPanelSlot(gui: GuiContainer, x: Int, y: Int, w: Int, h: Int): Boolean = {
new Rectangle(x - windowX, y - windowY, w, h).intersects(tabPosition)
}
}

View File

@ -7,6 +7,7 @@ import li.cil.oc.common.container
import li.cil.oc.common.tileentity
import net.minecraft.entity.player.InventoryPlayer
// TODO Remove in 1.7
class Switch(playerInventory: InventoryPlayer, val switch: tileentity.Switch) extends DynamicGuiContainer(new container.Switch(playerInventory, switch)) {
private val format = new DecimalFormat("#.##hz")

View File

@ -12,7 +12,7 @@ object SwitchRenderer extends TileEntitySpecialRenderer {
override def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, f: Float, damage: Int) {
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
val switch = tileEntity.asInstanceOf[tileentity.Switch]
val switch = tileEntity.asInstanceOf[tileentity.traits.SwitchLike]
val activity = math.max(0, 1 - (System.currentTimeMillis() - switch.lastMessage) / 1000.0)
if (activity > 0) {
RenderState.pushAttrib()

View File

@ -30,6 +30,8 @@ abstract class GuiHandler extends IGuiHandler {
new container.Printer(player.inventory, t)
case t: tileentity.Raid if id == GuiType.Raid.id =>
new container.Raid(player.inventory, t)
case t: tileentity.Relay if id == GuiType.Relay.id =>
new container.Relay(player.inventory, t)
case t: tileentity.RobotProxy if id == GuiType.Robot.id =>
new container.Robot(player.inventory, t.robot)
case t: tileentity.ServerRack if id == GuiType.Rack.id =>

View File

@ -28,6 +28,7 @@ object GuiType extends ScalaEnum {
val Printer = new EnumVal { def name = "Printer"; def subType = GuiType.Category.Block }
val Rack = new EnumVal { def name = "Rack"; def subType = GuiType.Category.Block }
val Raid = new EnumVal { def name = "Raid"; def subType = GuiType.Category.Block }
val Relay = new EnumVal { def name = "Relay"; def subType = GuiType.Category.Block }
val Robot = new EnumVal { def name = "Robot"; def subType = GuiType.Category.Block }
val Screen = new EnumVal { def name = "Screen"; def subType = GuiType.Category.Block }
val Server = new EnumVal { def name = "Server"; def subType = GuiType.Category.Item }

View File

@ -120,6 +120,13 @@ object InventorySlots {
)
)
val relay = Array(
InventorySlot(Slot.CPU, Tier.Three),
InventorySlot(Slot.Memory, Tier.Three),
InventorySlot(Slot.HDD, Tier.Three),
InventorySlot(Slot.Card, Tier.Three)
)
val switch = Array(
InventorySlot(Slot.CPU, Tier.Three),
InventorySlot(Slot.Memory, Tier.Three),

View File

@ -4,6 +4,7 @@ import li.cil.oc.Settings
import li.cil.oc.common.tileentity
import net.minecraft.world.World
// TODO Remove in 1.7
class AccessPoint extends Switch with traits.PowerAcceptor {
override def energyThroughput = Settings.get.accessPointRate

View File

@ -0,0 +1,17 @@
package li.cil.oc.common.block
import li.cil.oc.Settings
import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity
import net.minecraft.block.state.IBlockState
import net.minecraft.world.World
class Relay extends SimpleBlock with traits.GUI with traits.PowerAcceptor {
override def guiType = GuiType.Relay
override def energyThroughput = Settings.get.accessPointRate
override def hasTileEntity(state: IBlockState) = true
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Relay()
}

View File

@ -5,6 +5,7 @@ import li.cil.oc.common.tileentity
import net.minecraft.block.state.IBlockState
import net.minecraft.world.World
// TODO Remove in 1.7
class Switch extends SimpleBlock with traits.GUI {
override def guiType = GuiType.Switch

View File

@ -0,0 +1,33 @@
package li.cil.oc.common.container
import li.cil.oc.common.Slot
import li.cil.oc.common.tileentity
import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.nbt.NBTTagCompound
class Relay(playerInventory: InventoryPlayer, relay: tileentity.Relay) extends Player(playerInventory, relay) {
addSlotToContainer(151, 15, Slot.CPU)
addSlotToContainer(151, 34, Slot.Memory)
addSlotToContainer(151, 53, Slot.HDD)
addSlotToContainer(178, 15, Slot.Card)
addPlayerInventorySlots(8, 84)
def relayDelay = synchronizedData.getInteger("relayDelay")
def relayAmount = synchronizedData.getInteger("relayAmount")
def maxQueueSize = synchronizedData.getInteger("maxQueueSize")
def packetsPerCycleAvg = synchronizedData.getInteger("packetsPerCycleAvg")
def queueSize = synchronizedData.getInteger("queueSize")
override protected def detectCustomDataChanges(nbt: NBTTagCompound): Unit = {
synchronizedData.setInteger("relayDelay", relay.relayDelay)
synchronizedData.setInteger("relayAmount", relay.relayAmount)
synchronizedData.setInteger("maxQueueSize", relay.maxQueueSize)
synchronizedData.setInteger("packetsPerCycleAvg", relay.packetsPerCycleAvg())
synchronizedData.setInteger("queueSize", relay.queue.size)
super.detectCustomDataChanges(nbt)
}
}

View File

@ -5,6 +5,7 @@ import li.cil.oc.common.tileentity
import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.nbt.NBTTagCompound
// TODO Remove in 1.7
class Switch(playerInventory: InventoryPlayer, switch: tileentity.Switch) extends Player(playerInventory, switch) {
addSlotToContainer(151, 15, Slot.CPU)
addSlotToContainer(151, 34, Slot.Memory)

View File

@ -30,6 +30,7 @@ object Blocks {
GameRegistry.registerTileEntity(classOf[tileentity.Printer], Settings.namespace + "printer")
GameRegistry.registerTileEntity(classOf[tileentity.Raid], Settings.namespace + "raid")
GameRegistry.registerTileEntity(classOf[tileentity.Redstone], Settings.namespace + "redstone")
GameRegistry.registerTileEntity(classOf[tileentity.Relay], Settings.namespace + "relay")
GameRegistry.registerTileEntity(classOf[tileentity.RobotProxy], Settings.namespace + "robot")
GameRegistry.registerTileEntity(classOf[tileentity.Switch], Settings.namespace + "switch")
GameRegistry.registerTileEntity(classOf[tileentity.Screen], Settings.namespace + "screen")
@ -37,7 +38,7 @@ object Blocks {
GameRegistry.registerTileEntity(classOf[tileentity.NetSplitter], Settings.namespace + "netSplitter")
GameRegistry.registerTileEntity(classOf[tileentity.Waypoint], Settings.namespace + "waypoint")
Recipes.addBlock(new AccessPoint(), Constants.BlockName.AccessPoint, "oc:accessPoint")
Items.registerBlock(new AccessPoint(), Constants.BlockName.AccessPoint)
Recipes.addBlock(new Adapter(), Constants.BlockName.Adapter, "oc:adapter")
Recipes.addBlock(new Assembler(), Constants.BlockName.Assembler, "oc:assembler")
Recipes.addBlock(new Cable(), Constants.BlockName.Cable, "oc:cable")
@ -59,11 +60,12 @@ object Blocks {
Recipes.addBlock(new Printer(), Constants.BlockName.Printer, "oc:printer")
Recipes.addBlock(new Raid(), Constants.BlockName.Raid, "oc:raid")
Recipes.addBlock(new Redstone(), Constants.BlockName.Redstone, "oc:redstone")
Recipes.addBlock(new Relay(), Constants.BlockName.Relay, "oc:relay")
Recipes.addBlock(new Screen(Tier.One), Constants.BlockName.ScreenTier1, "oc:screen1")
Recipes.addBlock(new Screen(Tier.Three), Constants.BlockName.ScreenTier3, "oc:screen3")
Recipes.addBlock(new Screen(Tier.Two), Constants.BlockName.ScreenTier2, "oc:screen2")
Recipes.addBlock(new ServerRack(), Constants.BlockName.ServerRack, "oc:serverRack")
Recipes.addBlock(new Switch(), Constants.BlockName.Switch, "oc:switch")
Items.registerBlock(new Switch(), Constants.BlockName.Switch)
Recipes.addBlock(new Waypoint(), Constants.BlockName.Waypoint, "oc:waypoint")
Items.registerBlock(new Case(Tier.Four), Constants.BlockName.CaseCreative)

View File

@ -326,6 +326,12 @@ object Recipes {
GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(
lightPrint,
print.createItemStack(1), new ItemStack(net.minecraft.init.Blocks.glowstone)))
// Switch/AccessPoint -> Relay conversion
GameRegistry.addShapelessRecipe(api.Items.get(Constants.BlockName.Relay).createItemStack(1),
api.Items.get(Constants.BlockName.AccessPoint).createItemStack(1))
GameRegistry.addShapelessRecipe(api.Items.get(Constants.BlockName.Relay).createItemStack(1),
api.Items.get(Constants.BlockName.Switch).createItemStack(1))
}
catch {
case e: Throwable => OpenComputers.log.error("Error parsing recipes, you may not be able to craft any items from this mod!", e)

View File

@ -15,6 +15,7 @@ import net.minecraftforge.common.util.Constants.NBT
import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly
// TODO Remove in 1.7
class AccessPoint extends Switch with WirelessEndpoint with traits.PowerAcceptor {
var strength = Settings.get.maxWirelessRange
@ -24,6 +25,8 @@ class AccessPoint extends Switch with WirelessEndpoint with traits.PowerAcceptor
withComponent("access_point").
create())
override def isWirelessEnabled = true
// ----------------------------------------------------------------------- //
@SideOnly(Side.CLIENT)
@ -71,7 +74,7 @@ class AccessPoint extends Switch with WirelessEndpoint with traits.PowerAcceptor
override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet) {
super.relayPacket(sourceSide, packet)
if (strength > 0 && (sourceSide != None || isRepeater)) {
if (strength > 0 && (sourceSide.isDefined || isRepeater)) {
val cost = Settings.get.wirelessCostPerRange
val tryChangeBuffer = sourceSide match {
case Some(side) =>

View File

@ -0,0 +1,282 @@
package li.cil.oc.common.tileentity
import li.cil.oc.Constants
import li.cil.oc.Localization
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.Driver
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network.Analyzable
import li.cil.oc.api.network.Connector
import li.cil.oc.api.network.Node
import li.cil.oc.api.network.Packet
import li.cil.oc.api.network.Visibility
import li.cil.oc.api.network.WirelessEndpoint
import li.cil.oc.common.InventorySlots
import li.cil.oc.common.Slot
import li.cil.oc.common.item
import li.cil.oc.common.item.Delegator
import li.cil.oc.integration.Mods
import li.cil.oc.integration.opencomputers.DriverLinkedCard
import li.cil.oc.server.network.QuantumNetwork
import li.cil.oc.util.ExtendedNBT._
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
import net.minecraftforge.common.util.Constants.NBT
import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly
class Relay extends traits.SwitchLike with traits.ComponentInventory with traits.PowerAcceptor with Analyzable with WirelessEndpoint with QuantumNetwork.QuantumNode {
lazy final val WirelessNetworkCard = api.Items.get(Constants.ItemName.WirelessNetworkCard)
lazy final val LinkedCard = api.Items.get(Constants.ItemName.LinkedCard)
var strength = Settings.get.maxWirelessRange
var isRepeater = true
var isWirelessEnabled = false
var isLinkedEnabled = false
var tunnel = "creative"
val componentNodes = Array.fill(6)(api.Network.newNode(this, Visibility.Network).
withComponent("access_point").
create())
override def canUpdate = isServer
// ----------------------------------------------------------------------- //
@SideOnly(Side.CLIENT)
override protected def hasConnector(side: EnumFacing) = true
override protected def connector(side: EnumFacing) = sidedNode(side) match {
case connector: Connector => Option(connector)
case _ => None
}
override def energyThroughput = Settings.get.accessPointRate
// ----------------------------------------------------------------------- //
override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = {
if (isWirelessEnabled) {
player.addChatMessage(Localization.Analyzer.WirelessStrength(strength))
Array(componentNodes(side.getIndex))
}
else null
}
// ----------------------------------------------------------------------- //
@Callback(direct = true, doc = """function():number -- Get the signal strength (range) used when relaying messages.""")
def getStrength(context: Context, args: Arguments): Array[AnyRef] = synchronized(result(strength))
@Callback(doc = """function(strength:number):number -- Set the signal strength (range) used when relaying messages.""")
def setStrength(context: Context, args: Arguments): Array[AnyRef] = synchronized {
strength = math.max(args.checkDouble(0), math.min(0, Settings.get.maxWirelessRange))
result(strength)
}
@Callback(direct = true, doc = """function():boolean -- Get whether the access point currently acts as a repeater (resend received wireless packets wirelessly).""")
def isRepeater(context: Context, args: Arguments): Array[AnyRef] = synchronized(result(isRepeater))
@Callback(doc = """function(enabled:boolean):boolean -- Set whether the access point should act as a repeater.""")
def setRepeater(context: Context, args: Arguments): Array[AnyRef] = synchronized {
isRepeater = args.checkBoolean(0)
result(isRepeater)
}
// ----------------------------------------------------------------------- //
protected def queueMessage(source: String, destination: String, port: Int, answerPort: Int, args: Array[AnyRef]) {
/* TODO ComputerCraft
for (computer <- computers.map(_.asInstanceOf[IComputerAccess])) {
val address = s"cc${computer.getID}_${computer.getAttachmentName}"
if (source != address && Option(destination).forall(_ == address) && openPorts(computer).contains(port))
computer.queueEvent("modem_message", Array(Seq(computer.getAttachmentName, Int.box(port), Int.box(answerPort)) ++ args.map {
case x: Array[Byte] => new String(x, Charsets.UTF_8)
case x => x
}: _*))
}
*/
}
// ----------------------------------------------------------------------- //
override def receivePacket(packet: Packet, source: WirelessEndpoint): Unit = {
if (isWirelessEnabled) {
tryEnqueuePacket(None, packet)
}
}
override def receivePacket(packet: Packet): Unit = {
if (isLinkedEnabled) {
tryEnqueuePacket(None, packet)
}
}
override def tryEnqueuePacket(sourceSide: Option[EnumFacing], packet: Packet): Boolean = {
if (Mods.ComputerCraft.isAvailable) {
packet.data.headOption match {
case Some(answerPort: java.lang.Double) => queueMessage(packet.source, packet.destination, packet.port, answerPort.toInt, packet.data.drop(1))
case _ => queueMessage(packet.source, packet.destination, packet.port, -1, packet.data)
}
}
super.tryEnqueuePacket(sourceSide, packet)
}
override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet): Unit = {
super.relayPacket(sourceSide, packet)
val tryChangeBuffer = sourceSide match {
case Some(side) =>
(amount: Double) => plugs(side.ordinal).node.asInstanceOf[Connector].tryChangeBuffer(amount)
case _ =>
(amount: Double) => plugs.exists(_.node.asInstanceOf[Connector].tryChangeBuffer(amount))
}
if (isWirelessEnabled && strength > 0 && (sourceSide.isDefined || isRepeater)) {
val cost = Settings.get.wirelessCostPerRange
if (tryChangeBuffer(-strength * cost)) {
api.Network.sendWirelessPacket(this, strength, packet)
}
}
if (isLinkedEnabled && (sourceSide.isDefined || isRepeater)) {
val cost = packet.size / 32.0 + Settings.get.wirelessCostPerRange * Settings.get.maxWirelessRange * 5
if (tryChangeBuffer(-cost)) {
val endpoints = QuantumNetwork.getEndpoints(tunnel).filter(_ != this)
for (endpoint <- endpoints) {
endpoint.receivePacket(packet)
}
}
}
onSwitchActivity()
}
// ----------------------------------------------------------------------- //
override protected def createNode(plug: Plug) = api.Network.newNode(plug, Visibility.Network).
withConnector(math.round(Settings.get.bufferAccessPoint)).
create()
override protected def onPlugConnect(plug: Plug, node: Node) {
super.onPlugConnect(plug, node)
if (node == plug.node) {
api.Network.joinWirelessNetwork(this)
}
if (plug.isPrimary)
plug.node.connect(componentNodes(plug.side.ordinal()))
else
componentNodes(plug.side.ordinal).remove()
}
override protected def onPlugDisconnect(plug: Plug, node: Node) {
super.onPlugDisconnect(plug, node)
if (node == plug.node) {
api.Network.leaveWirelessNetwork(this)
}
if (plug.isPrimary && node != plug.node)
plug.node.connect(componentNodes(plug.side.ordinal()))
else
componentNodes(plug.side.ordinal).remove()
}
// ----------------------------------------------------------------------- //
override protected def onItemAdded(slot: Int, stack: ItemStack) {
super.onItemAdded(slot, stack)
updateLimits(slot, stack)
}
private def updateLimits(slot: Int, stack: ItemStack) {
Option(Driver.driverFor(stack, getClass)) match {
case Some(driver) if driver.slot(stack) == Slot.CPU =>
relayDelay = math.max(1, relayBaseDelay - ((driver.tier(stack) + 1) * relayDelayPerUpgrade))
case Some(driver) if driver.slot(stack) == Slot.Memory =>
relayAmount = math.max(1, relayBaseAmount + (Delegator.subItem(stack) match {
case Some(ram: item.Memory) => (ram.tier + 1) * relayAmountPerUpgrade
case _ => (driver.tier(stack) + 1) * (relayAmountPerUpgrade * 2)
}))
case Some(driver) if driver.slot(stack) == Slot.HDD =>
maxQueueSize = math.max(1, queueBaseSize + (driver.tier(stack) + 1) * queueSizePerUpgrade)
case Some(driver) if driver.slot(stack) == Slot.Card =>
val descriptor = api.Items.get(stack)
if (descriptor == WirelessNetworkCard) {
isWirelessEnabled = true
}
if (descriptor == LinkedCard) {
val data = DriverLinkedCard.dataTag(stack)
if (data.hasKey(Settings.namespace + "tunnel")) {
tunnel = data.getString(Settings.namespace + "tunnel")
isLinkedEnabled = true
QuantumNetwork.add(this)
}
}
case _ => // Dafuq u doin.
}
}
override protected def onItemRemoved(slot: Int, stack: ItemStack) {
super.onItemRemoved(slot, stack)
Driver.driverFor(stack, getClass) match {
case driver if driver.slot(stack) == Slot.CPU => relayDelay = relayBaseDelay
case driver if driver.slot(stack) == Slot.Memory => relayAmount = relayBaseAmount
case driver if driver.slot(stack) == Slot.HDD => maxQueueSize = queueBaseSize
case driver if driver.slot(stack) == Slot.Card =>
isWirelessEnabled = false
isLinkedEnabled = false
QuantumNetwork.remove(this)
}
}
override def getSizeInventory = InventorySlots.relay.length
override def isItemValidForSlot(slot: Int, stack: ItemStack) =
Option(Driver.driverFor(stack, getClass)).fold(false)(driver => {
val provided = InventorySlots.relay(slot)
val tierSatisfied = driver.slot(stack) == provided.slot && driver.tier(stack) <= provided.tier
val cardTypeSatisfied = if (provided.slot == Slot.Card) api.Items.get(stack) == WirelessNetworkCard || api.Items.get(stack) == LinkedCard else true
tierSatisfied && cardTypeSatisfied
})
// ----------------------------------------------------------------------- //
override def readFromNBTForServer(nbt: NBTTagCompound) {
super.readFromNBTForServer(nbt)
for (slot <- items.indices) items(slot) collect {
case stack => updateLimits(slot, stack)
}
if (nbt.hasKey(Settings.namespace + "strength")) {
strength = nbt.getDouble(Settings.namespace + "strength") max 0 min Settings.get.maxWirelessRange
}
if (nbt.hasKey(Settings.namespace + "isRepeater")) {
isRepeater = nbt.getBoolean(Settings.namespace + "isRepeater")
}
nbt.getTagList(Settings.namespace + "componentNodes", NBT.TAG_COMPOUND).toArray[NBTTagCompound].
zipWithIndex.foreach {
case (tag, index) => componentNodes(index).load(tag)
}
}
override def writeToNBTForServer(nbt: NBTTagCompound) = {
super.writeToNBTForServer(nbt)
nbt.setDouble(Settings.namespace + "strength", strength)
nbt.setBoolean(Settings.namespace + "isRepeater", isRepeater)
nbt.setNewTagList(Settings.namespace + "componentNodes", componentNodes.map {
case node: Node =>
val tag = new NBTTagCompound()
node.save(tag)
tag
case _ => new NBTTagCompound()
})
}
}

View File

@ -6,25 +6,49 @@ import li.cil.oc.common.InventorySlots
import li.cil.oc.common.Slot
import li.cil.oc.common.item
import li.cil.oc.common.item.Delegator
import li.cil.oc.server.PacketSender
import li.cil.oc.integration.Mods
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
class Switch extends traits.Hub with traits.NotAnalyzable with traits.ComponentInventory {
var lastMessage = 0L
// TODO Remove in 1.7
class Switch extends traits.SwitchLike with traits.NotAnalyzable with traits.ComponentInventory {
override def isWirelessEnabled = false
override def isLinkedEnabled = false
override def canUpdate = isServer
// ----------------------------------------------------------------------- //
protected def queueMessage(source: String, destination: String, port: Int, answerPort: Int, args: Array[AnyRef]) {
/* TODO ComputerCraft
for (computer <- computers.map(_.asInstanceOf[IComputerAccess])) {
val address = s"cc${computer.getID}_${computer.getAttachmentName}"
if (source != address && Option(destination).forall(_ == address) && openPorts(computer).contains(port))
computer.queueEvent("modem_message", Array(Seq(computer.getAttachmentName, Int.box(port), Int.box(answerPort)) ++ args.map {
case x: Array[Byte] => new String(x, Charsets.UTF_8)
case x => x
}: _*))
}
*/
}
// ----------------------------------------------------------------------- //
override def tryEnqueuePacket(sourceSide: Option[EnumFacing], packet: Packet): Boolean = {
if (Mods.ComputerCraft.isAvailable) {
packet.data.headOption match {
case Some(answerPort: java.lang.Double) => queueMessage(packet.source, packet.destination, packet.port, answerPort.toInt, packet.data.drop(1))
case _ => queueMessage(packet.source, packet.destination, packet.port, -1, packet.data)
}
}
super.tryEnqueuePacket(sourceSide, packet)
}
override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet) {
super.relayPacket(sourceSide, packet)
val now = System.currentTimeMillis()
if (now - lastMessage >= (relayDelay - 1) * 50) {
lastMessage = now
PacketSender.sendSwitchActivity(this)
}
onSwitchActivity()
}
// ----------------------------------------------------------------------- //

View File

@ -0,0 +1,27 @@
package li.cil.oc.common.tileentity.traits
import li.cil.oc.server.PacketSender
import scala.collection.mutable
trait SwitchLike extends Hub {
def relayDelay: Int
def isWirelessEnabled: Boolean
def isLinkedEnabled: Boolean
val computers = mutable.Buffer.empty[AnyRef]
val openPorts = mutable.Map.empty[AnyRef, mutable.Set[Int]]
var lastMessage = 0L
def onSwitchActivity(): Unit = {
val now = System.currentTimeMillis()
if (now - lastMessage >= (relayDelay - 1) * 50) {
lastMessage = now
PacketSender.sendSwitchActivity(this)
}
}
}

View File

@ -2,7 +2,7 @@ package li.cil.oc.integration.computercraft
import dan200.computercraft.api.ComputerCraftAPI
import dan200.computercraft.api.peripheral.IPeripheralProvider
import li.cil.oc.common.tileentity.Switch
import li.cil.oc.common.tileentity.traits.SwitchLike
import net.minecraft.world.World
object PeripheralProvider extends IPeripheralProvider {
@ -11,7 +11,7 @@ object PeripheralProvider extends IPeripheralProvider {
}
override def getPeripheral(world: World, x: Int, y: Int, z: Int, side: Int) = world.getTileEntity(x, y, z) match {
case switch: Switch => new SwitchPeripheral(switch)
case switch: SwitchLike => new SwitchPeripheral(switch)
case _ => null
}
}

View File

@ -8,8 +8,7 @@ import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network.Component
import li.cil.oc.common.tileentity.AccessPoint
import li.cil.oc.common.tileentity.Switch
import li.cil.oc.common.tileentity.traits.SwitchLike
import li.cil.oc.util.ResultWrapper._
import net.minecraftforge.common.util.ForgeDirection
@ -17,7 +16,7 @@ import scala.collection.convert.WrapAsJava._
import scala.collection.convert.WrapAsScala._
import scala.collection.mutable
class SwitchPeripheral(val switch: Switch) extends IPeripheral {
class SwitchPeripheral(val switch: SwitchLike) extends IPeripheral {
private val methods = Map[String, (IComputerAccess, ILuaContext, Array[AnyRef]) => Array[AnyRef]](
// Generic modem methods.
"open" -> ((computer, context, arguments) => {
@ -86,7 +85,10 @@ class SwitchPeripheral(val switch: Switch) extends IPeripheral {
// OC specific.
"isAccessPoint" -> ((computer, context, arguments) => {
result(switch.isInstanceOf[AccessPoint])
result(switch.isWirelessEnabled)
}),
"isTunnel" -> ((computer, context, arguments) => {
result(switch.isLinkedEnabled)
}),
"maxPacketSize" -> ((computer, context, arguments) => {
result(Settings.get.maxNetworkPacketSize)

View File

@ -385,7 +385,7 @@ object PacketSender {
pb.sendToPlayersNearTileEntity(t)
}
def sendSwitchActivity(t: tileentity.Switch) {
def sendSwitchActivity(t: tileentity.traits.SwitchLike) {
val pb = new SimplePacketBuilder(PacketType.SwitchActivity)
pb.writeTileEntity(t)

View File

@ -12,7 +12,7 @@ import net.minecraft.nbt.NBTTagCompound
import scala.collection.convert.WrapAsScala._
class LinkedCard extends prefab.ManagedEnvironment {
class LinkedCard extends prefab.ManagedEnvironment with QuantumNetwork.QuantumNode {
override val node = Network.newNode(this, Visibility.Network).
withComponent("tunnel", Visibility.Neighbors).
withConnector().
@ -28,8 +28,8 @@ class LinkedCard extends prefab.ManagedEnvironment {
// Cast to iterable to use Scala's toArray instead of the Arguments' one (which converts byte arrays to Strings).
val packet = Network.newPacket(node.address, null, 0, args.asInstanceOf[java.lang.Iterable[AnyRef]].toArray)
if (node.tryChangeBuffer(-(packet.size / 32.0 + Settings.get.wirelessCostPerRange * Settings.get.maxWirelessRange * 5))) {
for (card <- endpoints) {
card.receivePacket(packet)
for (endpoint <- endpoints) {
endpoint.receivePacket(packet)
}
result(true)
}

View File

@ -1,20 +1,27 @@
package li.cil.oc.server.network
import li.cil.oc.server.component.LinkedCard
import li.cil.oc.api.network.Packet
import scala.collection.mutable
// Just because the name if so fancy!
object QuantumNetwork {
val tunnels = mutable.Map.empty[String, mutable.WeakHashMap[LinkedCard, Unit]]
val tunnels = mutable.Map.empty[String, mutable.WeakHashMap[QuantumNode, Unit]]
def add(card: LinkedCard) {
def add(card: QuantumNode) {
tunnels.getOrElseUpdate(card.tunnel, mutable.WeakHashMap.empty).put(card, Unit)
}
def remove(card: LinkedCard) {
def remove(card: QuantumNode) {
tunnels.get(card.tunnel).foreach(_.remove(card))
}
def getEndpoints(tunnel: String) = tunnels.get(tunnel).fold(Iterable.empty[LinkedCard])(_.keys)
def getEndpoints(tunnel: String) = tunnels.get(tunnel).fold(Iterable.empty[QuantumNode])(_.keys)
trait QuantumNode {
def tunnel: String
def receivePacket(packet: Packet): Unit
}
}