mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-18 11:48:02 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8.9
This commit is contained in:
commit
25b6d214a7
@ -9,11 +9,14 @@ if #args < 2 then
|
||||
io.write(" -r: copy directories recursively.\n")
|
||||
io.write(" -u: copy only when the SOURCE file differs from the destination\n")
|
||||
io.write(" file or when the destination file is missing.\n")
|
||||
io.write(" -P: preserve attributes, e.g. symbolic links.\n")
|
||||
io.write(" -v: verbose output.\n")
|
||||
io.write(" -x: stay on original source file system.\n")
|
||||
return 1
|
||||
end
|
||||
|
||||
options.P = options.P or options.r
|
||||
|
||||
local from = {}
|
||||
for i = 1, #args - 1 do
|
||||
table.insert(from, shell.resolve(args[i]))
|
||||
@ -66,6 +69,10 @@ end
|
||||
|
||||
local function recurse(fromPath, toPath, origin)
|
||||
status(fromPath, toPath)
|
||||
local isLink, target = fs.isLink(fromPath)
|
||||
if isLink and options.P then
|
||||
return fs.link(target, toPath)
|
||||
end
|
||||
if fs.isDirectory(fromPath) then
|
||||
if not options.r then
|
||||
io.write("omitting directory `" .. fromPath .. "'\n")
|
||||
|
@ -240,13 +240,20 @@ function buffer:read(...)
|
||||
local function readLine(chop)
|
||||
local start = 1
|
||||
while true do
|
||||
local l = self.bufferRead:find("\n", start, true)
|
||||
if l then
|
||||
local result = self.bufferRead:sub(1, l + (chop and -1 or 0))
|
||||
self.bufferRead = self.bufferRead:sub(l + 1)
|
||||
local buf = self.bufferRead
|
||||
local i = buf:find("[\r\n]", start)
|
||||
local c = i and buf:sub(i,i)
|
||||
local is_cr = c == "\r"
|
||||
if i and (not is_cr or i < #buf) then
|
||||
local n = buf:sub(i+1,i+1)
|
||||
if is_cr and n == "\n" then
|
||||
c = c .. n
|
||||
end
|
||||
local result = buf:sub(1, i - 1) .. (chop and "" or c)
|
||||
self.bufferRead = buf:sub(i + #c)
|
||||
return result
|
||||
else
|
||||
start = #self.bufferRead
|
||||
start = #self.bufferRead - (is_cr and 1 or 0)
|
||||
local result, reason = readChunk()
|
||||
if not result then
|
||||
if reason then
|
||||
|
@ -267,12 +267,8 @@ private class Network private(private val data: mutable.Map[String, Network.Vert
|
||||
node.address = java.util.UUID.randomUUID().toString
|
||||
} while (data.contains(node.address) || otherNetwork.data.contains(node.address))
|
||||
|
||||
if (neighbors.isEmpty) {
|
||||
assert(otherNetwork.data.size == 1)
|
||||
Network.joinNewNetwork(node)
|
||||
} else {
|
||||
neighbors.foreach(_.connect(node))
|
||||
}
|
||||
neighbors.filter(_.network != null).foreach(_.connect(node))
|
||||
})
|
||||
|
||||
duplicates.head.data.network.asInstanceOf[Network.Wrapper].network
|
||||
@ -568,6 +564,8 @@ object Network extends api.detail.NetworkAPI {
|
||||
new Packet(source, destination, port, data, ttl)
|
||||
}
|
||||
|
||||
var isServer = SideTracker.isServer _
|
||||
|
||||
class NodeBuilder(val _host: Environment, val _reachability: Visibility) extends api.detail.Builder.NodeBuilder {
|
||||
def withComponent(name: String, visibility: Visibility) = new Network.ComponentBuilder(_host, _reachability, name, visibility)
|
||||
|
||||
@ -577,7 +575,7 @@ object Network extends api.detail.NetworkAPI {
|
||||
|
||||
def withConnector() = withConnector(0)
|
||||
|
||||
def create() = if (SideTracker.isServer) new MutableNode with NodeVarargPart {
|
||||
def create() = if (isServer()) new MutableNode with NodeVarargPart {
|
||||
val host = _host
|
||||
val reachability = _reachability
|
||||
}
|
||||
@ -589,7 +587,7 @@ object Network extends api.detail.NetworkAPI {
|
||||
|
||||
def withConnector() = withConnector(0)
|
||||
|
||||
def create() = if (SideTracker.isServer) new Component with NodeVarargPart {
|
||||
def create() = if (isServer()) new Component with NodeVarargPart {
|
||||
val host = _host
|
||||
val reachability = _reachability
|
||||
val name = _name
|
||||
@ -603,7 +601,7 @@ object Network extends api.detail.NetworkAPI {
|
||||
|
||||
def withComponent(name: String) = withComponent(name, _reachability)
|
||||
|
||||
def create() = if (SideTracker.isServer) new Connector with NodeVarargPart {
|
||||
def create() = if (isServer()) new Connector with NodeVarargPart {
|
||||
val host = _host
|
||||
val reachability = _reachability
|
||||
localBufferSize = _bufferSize
|
||||
@ -612,7 +610,7 @@ object Network extends api.detail.NetworkAPI {
|
||||
}
|
||||
|
||||
class ComponentConnectorBuilder(val _host: Environment, val _reachability: Visibility, val _name: String, val _visibility: Visibility, val _bufferSize: Double) extends api.detail.Builder.ComponentConnectorBuilder {
|
||||
def create() = if (SideTracker.isServer) new ComponentConnector with NodeVarargPart {
|
||||
def create() = if (isServer()) new ComponentConnector with NodeVarargPart {
|
||||
val host = _host
|
||||
val reachability = _reachability
|
||||
val name = _name
|
||||
@ -708,9 +706,8 @@ object Network extends api.detail.NetworkAPI {
|
||||
}
|
||||
nbt.setInteger("port", port)
|
||||
nbt.setInteger("ttl", ttl)
|
||||
val dataArray = data.toArray
|
||||
nbt.setInteger("dataLength", dataArray.length)
|
||||
for (i <- dataArray.indices) dataArray(i) match {
|
||||
nbt.setInteger("dataLength", data.length)
|
||||
for (i <- data.indices) data(i) match {
|
||||
case null | Unit | None =>
|
||||
case value: java.lang.Boolean => nbt.setBoolean("data" + i, value)
|
||||
case value: java.lang.Integer => nbt.setInteger("data" + i, value)
|
||||
|
235
src/test/scala/NetworkTest.scala
Normal file
235
src/test/scala/NetworkTest.scala
Normal file
@ -0,0 +1,235 @@
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.network.Environment
|
||||
import li.cil.oc.api.network.Message
|
||||
import li.cil.oc.api.network.Node
|
||||
import li.cil.oc.api.network.Visibility
|
||||
import li.cil.oc.server.network.Network
|
||||
import li.cil.oc.server.network.{Node => MutableNode}
|
||||
import org.scalatest._
|
||||
import org.scalatest.mock.MockitoSugar
|
||||
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
class NetworkTest extends FlatSpec with MockitoSugar {
|
||||
Network.isServer = () => true
|
||||
api.API.network = Network
|
||||
|
||||
val host = mock[Environment]
|
||||
|
||||
"A Node" should "not belong to a network after creation" in {
|
||||
val node = api.Network.newNode(host, Visibility.Network).create()
|
||||
assert(node.network == null)
|
||||
}
|
||||
|
||||
it should "belong to a network after joining a new network" in {
|
||||
val node = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node)
|
||||
assert(node.network != null)
|
||||
}
|
||||
|
||||
it should "not belong to a network after being removed from its new network" in {
|
||||
val node = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node)
|
||||
node.remove()
|
||||
assert(node.network == null)
|
||||
}
|
||||
|
||||
it should "have a neighbor after being connected to another node" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
assert(node1.neighbors.nonEmpty)
|
||||
assert(node2.neighbors.nonEmpty)
|
||||
assert(node1.isNeighborOf(node2))
|
||||
assert(node2.isNeighborOf(node1))
|
||||
}
|
||||
|
||||
it should "be reachable by neighbors when visibility is set to Neighbors" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Neighbors).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
assert(node1.canBeReachedFrom(node2))
|
||||
}
|
||||
|
||||
it should "be in the same network as nodes it is connected to" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
val node3 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node2.connect(node3)
|
||||
|
||||
assert(node1.network == node2.network)
|
||||
assert(node2.network == node3.network)
|
||||
assert(node1.network == node3.network)
|
||||
}
|
||||
|
||||
it should "have a different address than nodes it is connected to" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
val node3 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node2.connect(node3)
|
||||
|
||||
assert(node1.address != node2.address)
|
||||
assert(node2.address != node3.address)
|
||||
assert(node1.address != node3.address)
|
||||
}
|
||||
|
||||
it should "not be reachable by non neighbors when visibility is set to Neighbors" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Neighbors).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
val node3 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node2.connect(node3)
|
||||
assert(!node1.canBeReachedFrom(node3))
|
||||
}
|
||||
|
||||
it should "be reachable by all nodes when visibility is set to Network" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
val node3 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node2.connect(node3)
|
||||
assert(node1.canBeReachedFrom(node2))
|
||||
assert(node1.canBeReachedFrom(node3))
|
||||
}
|
||||
|
||||
it should "not be reachable by any node when visibility is set to None" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.None).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
val node3 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node2.connect(node3)
|
||||
assert(!node1.canBeReachedFrom(node2))
|
||||
assert(!node1.canBeReachedFrom(node3))
|
||||
}
|
||||
|
||||
it should "be in a separate network after a netsplit" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
val node3 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node2.connect(node3)
|
||||
|
||||
node2.remove()
|
||||
|
||||
assert(node1.network != null)
|
||||
assert(node2.network == null)
|
||||
assert(node3.network != null)
|
||||
assert(node1.network != node3.network)
|
||||
}
|
||||
|
||||
it should "change its address when joining a network containing a node with its address" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node2.asInstanceOf[MutableNode].address = node1.address
|
||||
node1.connect(node2)
|
||||
assert(node1.address != node2.address)
|
||||
}
|
||||
|
||||
"A Network" should "keep its local layout after being merged with another network" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
val node3 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node2.connect(node3)
|
||||
|
||||
val node4 = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node4)
|
||||
val node5 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node4.connect(node5)
|
||||
val node6 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node5.connect(node6)
|
||||
|
||||
node2.connect(node5)
|
||||
|
||||
assert(node1.neighbors.size == 1 && node1.isNeighborOf(node2))
|
||||
assert(node3.neighbors.size == 1 && node3.isNeighborOf(node2))
|
||||
|
||||
assert(node4.neighbors.size == 1 && node4.isNeighborOf(node5))
|
||||
assert(node6.neighbors.size == 1 && node6.isNeighborOf(node5))
|
||||
|
||||
assert(node2.isNeighborOf(node5))
|
||||
}
|
||||
|
||||
it should "keep its local layout after being merged with another network containing nodes with duplicate addresses at bridge points" in {
|
||||
val node1 = api.Network.newNode(host, Visibility.Network).create()
|
||||
api.Network.joinNewNetwork(node1)
|
||||
val node2 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node2)
|
||||
val node3 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node1.connect(node3)
|
||||
val node4 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node3.connect(node4)
|
||||
|
||||
val node5 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node5.asInstanceOf[MutableNode].address = node1.address
|
||||
api.Network.joinNewNetwork(node5)
|
||||
val node6 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node6.asInstanceOf[MutableNode].address = node2.address
|
||||
node5.connect(node6)
|
||||
val node7 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node7.asInstanceOf[MutableNode].address = node3.address
|
||||
node5.connect(node7)
|
||||
val node8 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node8.asInstanceOf[MutableNode].address = node4.address
|
||||
node7.connect(node8)
|
||||
|
||||
node3.connect(node7)
|
||||
|
||||
assert(node1.neighbors.size == 2 && node1.isNeighborOf(node2) && node1.isNeighborOf(node3))
|
||||
assert(node2.neighbors.size == 1 && node2.isNeighborOf(node1))
|
||||
assert(node3.neighbors.size == 3 && node3.isNeighborOf(node1) && node3.isNeighborOf(node4) && node3.isNeighborOf(node7))
|
||||
assert(node4.neighbors.size == 1 && node4.isNeighborOf(node3))
|
||||
|
||||
assert(node5.neighbors.size == 2 && node5.isNeighborOf(node6) && node5.isNeighborOf(node7))
|
||||
assert(node6.neighbors.size == 1 && node6.isNeighborOf(node5))
|
||||
assert(node7.neighbors.size == 3 && node7.isNeighborOf(node5) && node7.isNeighborOf(node8) && node7.isNeighborOf(node3))
|
||||
assert(node8.neighbors.size == 1 && node8.isNeighborOf(node7))
|
||||
}
|
||||
|
||||
it should "not error when nodes disconnect themselves in a remapping operation" in {
|
||||
val host = new Environment {
|
||||
val node1 = api.Network.newNode(this, Visibility.Network).create()
|
||||
val node2 = api.Network.newNode(this, Visibility.Network).create()
|
||||
|
||||
api.Network.joinNewNetwork(node1)
|
||||
|
||||
override def node: Node = node1
|
||||
|
||||
override def onMessage(message: Message): Unit = {}
|
||||
|
||||
override def onConnect(node: Node): Unit = {
|
||||
if (node == node1) {
|
||||
node.connect(node2)
|
||||
}
|
||||
}
|
||||
|
||||
override def onDisconnect(node: Node): Unit = {
|
||||
if (node == node1) {
|
||||
node2.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val node3 = api.Network.newNode(host, Visibility.Network).create()
|
||||
node3.asInstanceOf[MutableNode].address = host.node.address
|
||||
api.Network.joinNewNetwork(node3)
|
||||
|
||||
node3.connect(host.node)
|
||||
|
||||
assert(host.node1.neighbors.size == 2 && host.node1.isNeighborOf(host.node2) && host.node1.isNeighborOf(node3))
|
||||
assert(host.node2.neighbors.size == 1 && host.node2.isNeighborOf(host.node1))
|
||||
assert(node3.neighbors.size == 1 && node3.isNeighborOf(host.node1))
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user