mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 03:05:30 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8.9
# Conflicts: # src/main/scala/li/cil/oc/server/component/InternetCard.scala
This commit is contained in:
commit
ba0145c5b7
@ -31,13 +31,16 @@ if options.setlabel then
|
||||
end
|
||||
|
||||
if options.setboot then
|
||||
computer.setBootAddress(options.target.dev.address)
|
||||
local address = options.target.dev.address
|
||||
if computer.setBootAddress(address) then
|
||||
write("Boot address set to " .. address)
|
||||
end
|
||||
end
|
||||
|
||||
if options.reboot then
|
||||
write("Reboot now? [Y/n] ")
|
||||
local result = read()
|
||||
if not result or result == "" or result:sub(1, 1):lower() == "y" then
|
||||
local result = read() or "n"
|
||||
if result:sub(1, 1):lower() == "y" then
|
||||
write("\nRebooting now!\n")
|
||||
computer.shutdown(true)
|
||||
end
|
||||
|
@ -284,7 +284,7 @@ local function displayDirList(dirs)
|
||||
end
|
||||
end
|
||||
end
|
||||
local tr,cp={},{path=os.getenv("PWD")}
|
||||
local tr,cp={},{path=shell.getWorkingDirectory()}
|
||||
for _,dir in ipairs(dirsArg) do
|
||||
local path = shell.resolve(dir)
|
||||
if not fs.exists(path) then
|
||||
|
@ -44,7 +44,7 @@ local function load(name, args)
|
||||
return nil, reason
|
||||
end
|
||||
|
||||
function unload(name)
|
||||
function rc.unload(name)
|
||||
rc.loaded[name] = nil
|
||||
end
|
||||
|
||||
@ -60,15 +60,15 @@ local function rawRunCommand(conf, name, cmd, args, ...)
|
||||
end
|
||||
return true
|
||||
elseif type(result[cmd]) == "function" then
|
||||
res, what = xpcall(result[cmd], debug.traceback, ...)
|
||||
if res then
|
||||
result, what = xpcall(result[cmd], debug.traceback, ...)
|
||||
if result then
|
||||
return true
|
||||
end
|
||||
elseif cmd == "restart" and type(result["stop"]) == "function" and type(result["start"]) == "function" then
|
||||
res, what = xpcall(result["stop"], debug.traceback, ...)
|
||||
if res then
|
||||
res, what = xpcall(result["start"], debug.traceback, ...)
|
||||
if res then
|
||||
result, what = xpcall(result["stop"], debug.traceback, ...)
|
||||
if result then
|
||||
result, what = xpcall(result["start"], debug.traceback, ...)
|
||||
if result then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
@ -73,7 +73,7 @@ function buffer:read(...)
|
||||
if computer.uptime() > timeout then
|
||||
error("timeout")
|
||||
end
|
||||
local result, reason = self.stream:read(self.bufferSize)
|
||||
local result, reason = self.stream:read(math.max(1,self.bufferSize))
|
||||
if result then
|
||||
self.bufferRead = self.bufferRead .. result
|
||||
return self
|
||||
|
@ -61,15 +61,13 @@ end
|
||||
local delay_data = {}
|
||||
local delay_tools = setmetatable({},{__mode="v"})
|
||||
|
||||
package.delay_data = delay_data
|
||||
|
||||
function delay_data.__index(tbl,key)
|
||||
delay_data.lookup = delay_data.lookup or loadfile("/lib/tools/delayLookup.lua")
|
||||
return delay_data.lookup(delay_data, tbl, key)
|
||||
end
|
||||
delay_data.__pairs = delay_data.__index -- nil key acts like pairs
|
||||
|
||||
function delaySearcher(module)
|
||||
local function delaySearcher(module)
|
||||
if not delayed[module] then
|
||||
return "\tno field package.delayed['" .. module .. "']"
|
||||
end
|
||||
|
@ -367,7 +367,7 @@ function plib.popen(prog, mode, env)
|
||||
pm.pco=plib.internal.create(pm.root)
|
||||
|
||||
local pfd = require("buffer").new(mode, pipeStream.new(pm))
|
||||
pfd:setvbuf("no", nil) -- 2nd are to read chunk size
|
||||
pfd:setvbuf("no", 0) -- 2nd are to read chunk size
|
||||
|
||||
-- popen processes start on create (which is LAME :P)
|
||||
pfd.stream:resume()
|
||||
|
@ -12,8 +12,8 @@ sh.internal = {}
|
||||
|
||||
-- --[[@@]] are not just comments, but custom annotations for delayload methods.
|
||||
-- See package.lua and the api wiki for more information
|
||||
function isWordOf(w, vs) return w and #w == 1 and not w[1].qr and tx.first(vs,{{w[1].txt}}) ~= nil end
|
||||
function isWord(w,v) return isWordOf(w,{v}) end
|
||||
local function isWordOf(w, vs) return w and #w == 1 and not w[1].qr and tx.first(vs,{{w[1].txt}}) ~= nil end
|
||||
local function isWord(w,v) return isWordOf(w,{v}) end
|
||||
local local_env = {event=event,fs=fs,process=process,shell=shell,term=term,text=text,tx=tx,unicode=unicode,isWordOf=isWordOf,isWord=isWord}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@ -424,7 +424,7 @@ function --[[@delayloaded-start@]] sh.internal.buildPipeChain(threads)
|
||||
local pipe
|
||||
if i < #threads then
|
||||
pipe = require("buffer").new("rw", sh.internal.newMemoryStream())
|
||||
pipe:setvbuf("no")
|
||||
pipe:setvbuf("no", 0)
|
||||
-- buffer close flushes the buffer, but we have no buffer
|
||||
-- also, when the buffer is closed, read and writes don't pass through
|
||||
-- simply put, we don't want buffer:close
|
||||
@ -461,7 +461,7 @@ function --[[@delayloaded-start@]] sh.internal.glob(glob_pattern)
|
||||
end
|
||||
|
||||
local is_abs = glob_pattern:sub(1, 1) == "/"
|
||||
local root = is_abs and '' or shell.getWorkingDirectory()
|
||||
local root = is_abs and '' or shell.getWorkingDirectory():gsub("([^/])$","%1/")
|
||||
local paths = {is_abs and "/" or ''}
|
||||
local relative_separator = ''
|
||||
|
||||
|
@ -10,6 +10,7 @@ import net.minecraftforge.fml.common.event.FMLInterModComms.IMCEvent
|
||||
import net.minecraftforge.fml.common.event._
|
||||
import net.minecraftforge.fml.common.network.FMLEventChannel
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
|
||||
@Mod(modid = OpenComputers.ID, name = OpenComputers.Name,
|
||||
version = OpenComputers.Version,
|
||||
@ -21,7 +22,9 @@ object OpenComputers {
|
||||
|
||||
final val Version = "@VERSION@"
|
||||
|
||||
var log = LogManager.getLogger(Name)
|
||||
def log = logger.getOrElse(LogManager.getLogger(Name))
|
||||
|
||||
var logger: Option[Logger] = None
|
||||
|
||||
@SidedProxy(clientSide = "li.cil.oc.client.Proxy", serverSide = "li.cil.oc.server.Proxy")
|
||||
var proxy: Proxy = null
|
||||
@ -30,7 +33,7 @@ object OpenComputers {
|
||||
|
||||
@EventHandler
|
||||
def preInit(e: FMLPreInitializationEvent) {
|
||||
log = e.getModLog
|
||||
logger = Option(e.getModLog)
|
||||
proxy.preInit(e)
|
||||
OpenComputers.log.info("Done with pre init phase.")
|
||||
}
|
||||
|
@ -7,17 +7,20 @@ import java.io.InputStream
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net._
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.channels.SelectionKey
|
||||
import java.nio.channels.Selector
|
||||
import java.nio.channels.SocketChannel
|
||||
import java.util
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import java.util.concurrent.ExecutionException
|
||||
import java.util.concurrent.Future
|
||||
import java.util.UUID
|
||||
import java.util.concurrent._
|
||||
|
||||
import li.cil.oc.Constants
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api.Network
|
||||
import li.cil.oc.api.driver.DeviceInfo
|
||||
import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute
|
||||
import li.cil.oc.api.driver.DeviceInfo.DeviceClass
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api.Network
|
||||
import li.cil.oc.api.driver.DeviceInfo
|
||||
import li.cil.oc.api.machine.Arguments
|
||||
@ -183,6 +186,41 @@ object InternetCard {
|
||||
def close(): Unit
|
||||
}
|
||||
|
||||
object TCPNotifier extends Thread {
|
||||
private val selector = Selector.open()
|
||||
private val toAccept = new ConcurrentLinkedQueue[(SocketChannel, () => Unit)]
|
||||
|
||||
override def run(): Unit = {
|
||||
while (true) {
|
||||
try {
|
||||
Stream.continually(toAccept.poll).takeWhile(_ != null).foreach({
|
||||
case (channel: SocketChannel, action: (() => Unit)) =>
|
||||
channel.register(selector, SelectionKey.OP_READ, action)
|
||||
})
|
||||
|
||||
selector.select()
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
val selectedKeys = selector.selectedKeys
|
||||
selectedKeys.filter(_.isReadable).foreach(key => {
|
||||
key.cancel()
|
||||
key.attachment().asInstanceOf[() => Unit].apply()
|
||||
})
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
OpenComputers.log.error("Error in TCP selector loop.", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def add(e: (SocketChannel, () => Unit)) {
|
||||
toAccept.offer(e)
|
||||
selector.wakeup()
|
||||
}
|
||||
}
|
||||
|
||||
TCPNotifier.start()
|
||||
|
||||
class TCPSocket extends AbstractValue with Closable {
|
||||
def this(owner: InternetCard, uri: URI, port: Int) {
|
||||
this()
|
||||
@ -196,9 +234,25 @@ object InternetCard {
|
||||
private var address: Future[InetAddress] = null
|
||||
private var channel: SocketChannel = null
|
||||
private var isAddressResolved = false
|
||||
private val id = UUID.randomUUID()
|
||||
|
||||
private def setupSelector() {
|
||||
TCPNotifier.add((channel, () => {
|
||||
owner match {
|
||||
case Some(internetCard) =>
|
||||
internetCard.node.sendToVisible("computer.signal", "internet_ready", internetCard.node.address(), id.toString)
|
||||
case _ =>
|
||||
channel.close()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
@Callback(doc = """function():boolean -- Ensures a socket is connected. Errors if the connection failed.""")
|
||||
def finishConnect(context: Context, args: Arguments): Array[AnyRef] = this.synchronized(result(checkConnected()))
|
||||
def finishConnect(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val r = this.synchronized(result(checkConnected()))
|
||||
setupSelector()
|
||||
r
|
||||
}
|
||||
|
||||
@Callback(doc = """function([n:number]):string -- Tries to read data from the socket stream. Returns the read byte array.""")
|
||||
def read(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
|
||||
@ -207,7 +261,10 @@ object InternetCard {
|
||||
val buffer = ByteBuffer.allocate(n)
|
||||
val read = channel.read(buffer)
|
||||
if (read == -1) result(Unit)
|
||||
else result(buffer.array.view(0, read).toArray)
|
||||
else {
|
||||
setupSelector()
|
||||
result(buffer.array.view(0, read).toArray)
|
||||
}
|
||||
}
|
||||
else result(Array.empty[Byte])
|
||||
}
|
||||
@ -227,6 +284,11 @@ object InternetCard {
|
||||
null
|
||||
}
|
||||
|
||||
@Callback(direct = true, doc = """function():string -- Returns connection ID.""")
|
||||
def id(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
|
||||
result(id.toString)
|
||||
}
|
||||
|
||||
override def dispose(context: Context): Unit = {
|
||||
super.dispose(context)
|
||||
close()
|
||||
|
Loading…
x
Reference in New Issue
Block a user