mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-12 16:57:32 -04:00
defaulting to standard lua string functions and making unicode ones available prefixed with a u (uchar, ulen, usub, ureverse); fixed event erroring being weird; fixed wrong case check order in kernel; fixed error when netsplitting a component from a computer; fixed localization for disk drive; config for name to provide when running command in command block; increased range of keyboards; adapter blocks re-use the same addresses for the blocks attached to them to avoid computers losing track of those nodes after reloading
This commit is contained in:
parent
87aa1f44a9
commit
ccf53d6b85
@ -1,9 +1,10 @@
|
||||
oc.block.Adapter.name=Adapter
|
||||
oc.block.Computer.name=Computer
|
||||
oc.block.DiskDrive.name=Diskettenlaufwerk
|
||||
oc.block.Keyboard.name=Tastatur
|
||||
oc.block.Screen.name=Bildschirm
|
||||
oc.container.computer=Computer
|
||||
oc.container.disk_drive=Diskettenlaufwerk
|
||||
oc.container.Computer=Computer
|
||||
oc.container.DiskDrive=Diskettenlaufwerk
|
||||
oc.item.Disk.name=Diskette
|
||||
oc.item.GraphicsCard.name=Grafikkarte
|
||||
oc.item.HardDiskDrive2m.name=Festplatte (2MB)
|
||||
|
@ -1,9 +1,10 @@
|
||||
oc.block.Adapter.name=Adapter
|
||||
oc.block.Computer.name=Computer
|
||||
oc.block.DiskDrive.name=Disk Drive
|
||||
oc.block.Keyboard.name=Keyboard
|
||||
oc.block.Screen.name=Screen
|
||||
oc.container.computer=Computer
|
||||
oc.container.disk_drive=Disk Drive
|
||||
oc.container.Computer=Computer
|
||||
oc.container.DiskDrive=Disk Drive
|
||||
oc.item.Disk.name=Floppy Disk
|
||||
oc.item.GraphicsCard.name=Graphics Card
|
||||
oc.item.HardDiskDrive2m.name=Hard Disk Drive (2MB)
|
||||
|
@ -181,7 +181,7 @@ function driver.filesystem.isDirectory(path)
|
||||
if node.fs and rest then
|
||||
return send(node.fs, "fs.isDirectory", rest)
|
||||
else
|
||||
return not rest or rest:len() == 0
|
||||
return not rest or rest:ulen() == 0
|
||||
end
|
||||
end
|
||||
|
||||
@ -339,12 +339,12 @@ function file:read(...)
|
||||
local function readBytesOrChars(n)
|
||||
local len, sub
|
||||
if self.mode == "r" then
|
||||
len = string.len
|
||||
sub = string.sub
|
||||
len = string.ulen
|
||||
sub = string.usub
|
||||
else
|
||||
assert(self.mode == "rb")
|
||||
len = rawlen
|
||||
sub = string.bsub
|
||||
sub = string.sub
|
||||
end
|
||||
local buffer = ""
|
||||
repeat
|
||||
@ -370,8 +370,8 @@ function file:read(...)
|
||||
while true do
|
||||
local l = self.buffer:find("\n", start, true)
|
||||
if l then
|
||||
local result = self.buffer:bsub(1, l + (chop and -1 or 0))
|
||||
self.buffer = self.buffer:bsub(l + 1)
|
||||
local result = self.buffer:sub(1, l + (chop and -1 or 0))
|
||||
self.buffer = self.buffer:sub(l + 1)
|
||||
return result
|
||||
else
|
||||
start = #self.buffer
|
||||
@ -405,10 +405,10 @@ function file:read(...)
|
||||
if type(format) == "number" then
|
||||
return readBytesOrChars(format)
|
||||
else
|
||||
if type(format) ~= "string" or format:sub(1, 1) ~= "*" then
|
||||
if type(format) ~= "string" or format:usub(1, 1) ~= "*" then
|
||||
error("bad argument #" .. n .. " (invalid option)")
|
||||
end
|
||||
format = format:sub(2, 2)
|
||||
format = format:usub(2, 2)
|
||||
if format == "n" then
|
||||
--[[ TODO ]]
|
||||
error("not implemented")
|
||||
@ -529,11 +529,11 @@ function file:write(...)
|
||||
end
|
||||
end
|
||||
if l then
|
||||
result, reason = self.stream:write(arg:bsub(1, l))
|
||||
result, reason = self.stream:write(arg:sub(1, l))
|
||||
if not result then
|
||||
return nil, reason
|
||||
end
|
||||
arg = arg:bsub(l + 1)
|
||||
arg = arg:sub(l + 1)
|
||||
end
|
||||
if #arg > self.bufferSize then
|
||||
result, reason = self.stream:write(arg)
|
||||
|
@ -100,8 +100,6 @@ local sandbox = {
|
||||
},
|
||||
|
||||
string = {
|
||||
breverse = string.breverse,
|
||||
bsub = string.bsub,
|
||||
byte = string.byte,
|
||||
char = string.char,
|
||||
dump = string.dump,
|
||||
@ -115,7 +113,11 @@ local sandbox = {
|
||||
rep = string.rep,
|
||||
reverse = string.reverse,
|
||||
sub = string.sub,
|
||||
upper = string.upper
|
||||
upper = string.upper,
|
||||
uchar = string.uchar,
|
||||
ulen = string.ulen,
|
||||
ureverse = string.breverse,
|
||||
usub = string.bsub
|
||||
},
|
||||
|
||||
table = {
|
||||
@ -180,12 +182,12 @@ local function main(args)
|
||||
debug.sethook(co, checkDeadline, "", 10000)
|
||||
end
|
||||
local result = table.pack(coroutine.resume(co, table.unpack(args, 1, args.n)))
|
||||
if coroutine.status(co) == "dead" then
|
||||
if not result[1] then
|
||||
error(result[2] or "unknown error", 0)
|
||||
elseif coroutine.status(co) == "dead" then
|
||||
error("computer stopped unexpectedly", 0)
|
||||
elseif result[1] then
|
||||
args = table.pack(coroutine.yield(result[2])) -- system yielded value
|
||||
else
|
||||
error(result[2], 0)
|
||||
args = table.pack(coroutine.yield(result[2])) -- system yielded value
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -267,7 +269,8 @@ do
|
||||
return debug.traceback(msg, 2)
|
||||
end)
|
||||
if not result then
|
||||
print("Failed initializing driver '" .. name .. "': " .. reason)
|
||||
print("Failed initializing driver '" .. name .. "': " ..
|
||||
(reason or "unknown error"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -24,8 +24,18 @@ function component.primary(componentType, ...)
|
||||
local args = table.pack(...)
|
||||
if args.n > 0 then
|
||||
checkArg(2, args[1], "string", "nil")
|
||||
local address
|
||||
if args[1] ~= nil then
|
||||
for c in component.list(componentType) do
|
||||
if c:usub(1, args[1]:ulen()) == args[1] then
|
||||
address = c
|
||||
break
|
||||
end
|
||||
end
|
||||
assert(address, "no such component")
|
||||
end
|
||||
local wasAvailable = component.isAvailable(componentType)
|
||||
primaries[componentType] = args[1]
|
||||
primaries[componentType] = address
|
||||
if not wasAvailable and component.isAvailable(componentType) then
|
||||
event.fire("component_available", componentType)
|
||||
elseif wasAvailable and not component.isAvailable(componentType) then
|
||||
@ -45,6 +55,9 @@ end
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function onComponentAdded(_, address)
|
||||
if components[address] then
|
||||
return false -- cancel this event, it is invalid
|
||||
end
|
||||
local componentType = driver.componentType(address)
|
||||
components[address] = componentType
|
||||
if not component.isAvailable(componentType) then
|
||||
@ -53,16 +66,15 @@ local function onComponentAdded(_, address)
|
||||
end
|
||||
|
||||
local function onComponentRemoved(_, address)
|
||||
if not components[address] then
|
||||
return false -- cancel this event, it is invalid
|
||||
end
|
||||
local componentType = component.type(address)
|
||||
components[address] = nil
|
||||
if primaries[componentType] == address then
|
||||
component.primary(componentType, nil)
|
||||
for address in component.list() do
|
||||
if component.type(address) == componentType then
|
||||
component.primary(componentType, address)
|
||||
return
|
||||
end
|
||||
end
|
||||
address = component.list(componentType)()
|
||||
component.primary(componentType, address)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2,14 +2,18 @@ local listeners = {}
|
||||
local weakListeners = {}
|
||||
local timers = {}
|
||||
|
||||
local function listenersFor(name, weak)
|
||||
local function listenersFor(name, weak, create)
|
||||
checkArg(1, name, "string")
|
||||
if weak then
|
||||
weakListeners[name] = weakListeners[name] or setmetatable({}, {__mode = "v"})
|
||||
return weakListeners[name]
|
||||
if not weakListeners[name] and create then
|
||||
weakListeners[name] = weakListeners[name] or setmetatable({}, {__mode = "v"})
|
||||
end
|
||||
return weakListeners[name] or {}
|
||||
else
|
||||
listeners[name] = listeners[name] or {}
|
||||
return listeners[name]
|
||||
if not listeners[name] and create then
|
||||
listeners[name] = listeners[name] or {}
|
||||
end
|
||||
return listeners[name] or {}
|
||||
end
|
||||
end
|
||||
|
||||
@ -28,16 +32,20 @@ function event.fire(name, ...)
|
||||
-- timer check (for example if we had no signal in event.wait()).
|
||||
if name then
|
||||
checkArg(1, name, "string")
|
||||
for _, callback in ipairs(listenersFor(name, false)) do
|
||||
local result, message = xpcall(callback, event.error, name, ...)
|
||||
if not result and message then
|
||||
error(message, 0)
|
||||
end
|
||||
local function copy(listA, listB)
|
||||
local result = {}
|
||||
for _, v in ipairs(listA) do table.insert(result, v) end
|
||||
for _, v in ipairs(listB) do table.insert(result, v) end
|
||||
return result
|
||||
end
|
||||
for _, callback in ipairs(listenersFor(name, true)) do
|
||||
-- Copy the listener lists because they may be changed by callbacks.
|
||||
local listeners = copy(listenersFor(name, false), listenersFor(name, true))
|
||||
for _, callback in ipairs(listeners) do
|
||||
local result, message = xpcall(callback, event.error, name, ...)
|
||||
if not result and message then
|
||||
if not result and message then -- only if handler returned something.
|
||||
error(message, 0)
|
||||
elseif result and message == false then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -50,7 +58,7 @@ function event.fire(name, ...)
|
||||
end
|
||||
for _, callback in ipairs(elapsed) do
|
||||
local result, message = xpcall(callback, event.error)
|
||||
if not result and message then
|
||||
if not result and message then -- only if handler returned something.
|
||||
error(message, 0)
|
||||
end
|
||||
end
|
||||
@ -71,7 +79,7 @@ end
|
||||
|
||||
function event.listen(name, callback, weak)
|
||||
checkArg(2, callback, "function")
|
||||
local list = listenersFor(name, weak)
|
||||
local list = listenersFor(name, weak, true)
|
||||
for i = 1, #list do
|
||||
if list[i] == callback then
|
||||
return
|
||||
|
@ -28,9 +28,9 @@ local function onComponentAdded(_, address)
|
||||
address ~= os.romAddress() and
|
||||
address ~= os.tmpAddress()
|
||||
then
|
||||
local name = address:sub(1, 3)
|
||||
local name = address:usub(1, 3)
|
||||
repeat
|
||||
name = address:sub(1, name:len() + 1)
|
||||
name = address:usub(1, name:ulen() + 1)
|
||||
until not fs.exists("/mnt/" .. name)
|
||||
fs.mount(address, "/mnt/" .. name)
|
||||
if isAutorunEnabled then
|
||||
|
@ -47,7 +47,7 @@ function term.cursorBlink(enabled)
|
||||
if not cursorBlink then
|
||||
cursorBlink = event.interval(0.5, toggleBlink)
|
||||
cursorBlink.state = false
|
||||
cursorBlink.solid = string.char(0x2588) -- 0x2588 is a solid block.
|
||||
cursorBlink.solid = string.uchar(0x2588) -- 0x2588 is a solid block.
|
||||
elseif cursorBlink.state then
|
||||
toggleBlink()
|
||||
end
|
||||
@ -67,10 +67,10 @@ function term.cursorBlink(enabled)
|
||||
stop()
|
||||
end
|
||||
elseif type(enabled) == "string" and
|
||||
(not cursorBlink or enabled:sub(1, 1) ~= cursorBlink.alt)
|
||||
(not cursorBlink or enabled:usub(1, 1) ~= cursorBlink.alt)
|
||||
then
|
||||
if enabled:len() > 0 then
|
||||
start(enabled:sub(1, 1))
|
||||
if enabled:ulen() > 0 then
|
||||
start(enabled:usub(1, 1))
|
||||
else
|
||||
stop()
|
||||
end
|
||||
@ -85,63 +85,68 @@ function term.read(history)
|
||||
table.insert(history, "")
|
||||
local current = #history
|
||||
local keys = driver.keyboard.keys
|
||||
local start, y = term.cursor()
|
||||
local start = term.cursor()
|
||||
local cursor, scroll = 1, 0
|
||||
local keyRepeat = nil
|
||||
local result = nil
|
||||
local function remove()
|
||||
local x = start - 1 + cursor - scroll
|
||||
local _, y = term.cursor()
|
||||
local w = gpu.resolution()
|
||||
gpu.copy(x + 1, y, w - x, 1, -1, 0)
|
||||
local cursor = cursor + (w - x)
|
||||
local char = history[current]:sub(cursor, cursor)
|
||||
if char:len() == 0 then
|
||||
local char = history[current]:usub(cursor, cursor)
|
||||
if char:ulen() == 0 then
|
||||
char = " "
|
||||
end
|
||||
gpu.set(w, y, char)
|
||||
end
|
||||
local function render()
|
||||
local _, y = term.cursor()
|
||||
local w = gpu.resolution()
|
||||
local str = history[current]:sub(1 + scroll, 1 + scroll + w - (start - 1))
|
||||
str = str .. string.rep(" ", (w - (start - 1)) - str:len())
|
||||
local str = history[current]:usub(1 + scroll, 1 + scroll + w - (start - 1))
|
||||
str = str .. string.rep(" ", (w - (start - 1)) - str:ulen())
|
||||
gpu.set(start, y, str)
|
||||
end
|
||||
local function scrollEnd()
|
||||
local w = gpu.resolution()
|
||||
cursor = history[current]:len() + 1
|
||||
cursor = history[current]:ulen() + 1
|
||||
scroll = math.max(0, cursor - (w - (start - 1)))
|
||||
render()
|
||||
end
|
||||
local function scrollLeft()
|
||||
scroll = scroll - 1
|
||||
local _, y = term.cursor()
|
||||
local w = gpu.resolution()
|
||||
gpu.copy(start, y, w - start - 1, 1, 1, 0)
|
||||
local cursor = w - (start - 1) + scroll
|
||||
local char = history[current]:sub(cursor, cursor)
|
||||
if char:len() == 0 then
|
||||
local char = history[current]:usub(cursor, cursor)
|
||||
if char:ulen() == 0 then
|
||||
char = " "
|
||||
end
|
||||
gpu.set(1, y, char)
|
||||
end
|
||||
local function scrollRight()
|
||||
scroll = scroll + 1
|
||||
local _, y = term.cursor()
|
||||
local w = gpu.resolution()
|
||||
gpu.copy(start + 1, y, w - start, 1, -1, 0)
|
||||
local cursor = w - (start - 1) + scroll
|
||||
local char = history[current]:sub(cursor, cursor)
|
||||
if char:len() == 0 then
|
||||
local char = history[current]:usub(cursor, cursor)
|
||||
if char:ulen() == 0 then
|
||||
char = " "
|
||||
end
|
||||
gpu.set(w, y, char)
|
||||
end
|
||||
local function update()
|
||||
local _, y = term.cursor()
|
||||
local w = gpu.resolution()
|
||||
local cursor = cursor - 1
|
||||
local x = start - 1 + cursor - scroll
|
||||
if cursor < history[current]:len() then
|
||||
if cursor < history[current]:ulen() then
|
||||
gpu.copy(x, y, w - x, 1, 1, 0)
|
||||
end
|
||||
gpu.set(x, y, history[current]:sub(cursor, cursor))
|
||||
gpu.set(x, y, history[current]:usub(cursor, cursor))
|
||||
end
|
||||
local function copyIfNecessary()
|
||||
if current ~= #history then
|
||||
@ -150,9 +155,10 @@ function term.read(history)
|
||||
end
|
||||
end
|
||||
local function updateCursor()
|
||||
local _, y = term.cursor()
|
||||
term.cursor(start - 1 + cursor - scroll, y)
|
||||
term.cursorBlink(cursor <= history[current]:len() and
|
||||
history[current]:sub(cursor, cursor) or " ")
|
||||
term.cursorBlink(cursor <= history[current]:ulen() and
|
||||
history[current]:usub(cursor, cursor) or " ")
|
||||
end
|
||||
local function handleKeyPress(char, code)
|
||||
if not term.isAvailable() then return end
|
||||
@ -162,8 +168,8 @@ function term.read(history)
|
||||
if code == keys.back then
|
||||
if cursor > 1 then
|
||||
copyIfNecessary()
|
||||
history[current] = history[current]:sub(1, cursor - 2) ..
|
||||
history[current]:sub(cursor)
|
||||
history[current] = history[current]:usub(1, cursor - 2) ..
|
||||
history[current]:usub(cursor)
|
||||
cursor = cursor - 1
|
||||
if cursor - scroll < 1 then
|
||||
scrollLeft()
|
||||
@ -172,13 +178,13 @@ function term.read(history)
|
||||
end
|
||||
cancel = cursor == 1
|
||||
elseif code == keys.delete then
|
||||
if cursor <= history[current]:len() then
|
||||
if cursor <= history[current]:ulen() then
|
||||
copyIfNecessary()
|
||||
history[current] = history[current]:sub(1, cursor - 1) ..
|
||||
history[current]:sub(cursor + 1)
|
||||
history[current] = history[current]:usub(1, cursor - 1) ..
|
||||
history[current]:usub(cursor + 1)
|
||||
remove()
|
||||
end
|
||||
cancel = cursor == history[current]:len() + 1
|
||||
cancel = cursor == history[current]:ulen() + 1
|
||||
elseif code == keys.left then
|
||||
if cursor > 1 then
|
||||
cursor = cursor - 1
|
||||
@ -188,13 +194,13 @@ function term.read(history)
|
||||
end
|
||||
cancel = cursor == 1
|
||||
elseif code == keys.right then
|
||||
if cursor < history[current]:len() + 1 then
|
||||
if cursor < history[current]:ulen() + 1 then
|
||||
cursor = cursor + 1
|
||||
if cursor - scroll > w - (start - 1) then
|
||||
scrollRight()
|
||||
end
|
||||
end
|
||||
cancel = cursor == history[current]:len() + 1
|
||||
cancel = cursor == history[current]:ulen() + 1
|
||||
elseif code == keys.home then
|
||||
if cursor > 1 then
|
||||
cursor, scroll = 1, 0
|
||||
@ -202,7 +208,7 @@ function term.read(history)
|
||||
end
|
||||
cancel = true
|
||||
elseif code == keys["end"] then
|
||||
if cursor < history[current]:len() + 1 then
|
||||
if cursor < history[current]:ulen() + 1 then
|
||||
scrollEnd()
|
||||
end
|
||||
cancel = true
|
||||
@ -225,15 +231,15 @@ function term.read(history)
|
||||
current = #history
|
||||
end
|
||||
result = history[current] .. "\n"
|
||||
if history[current]:len() == 0 then
|
||||
if history[current]:ulen() == 0 then
|
||||
table.remove(history, current)
|
||||
end
|
||||
return true
|
||||
elseif not keys.isControl(char) then
|
||||
copyIfNecessary()
|
||||
history[current] = history[current]:sub(1, cursor - 1) ..
|
||||
string.char(char) ..
|
||||
history[current]:sub(cursor)
|
||||
history[current] = history[current]:usub(1, cursor - 1) ..
|
||||
string.uchar(char) ..
|
||||
history[current]:usub(cursor)
|
||||
cursor = cursor + 1
|
||||
update()
|
||||
if cursor - scroll > w - (start - 1) then
|
||||
@ -281,7 +287,7 @@ function term.read(history)
|
||||
term.cursorBlink(false)
|
||||
local l = value:find("\n", 1, true)
|
||||
if l then
|
||||
history[current] = history[current] .. value:sub(1, l - 1)
|
||||
history[current] = history[current] .. value:usub(1, l - 1)
|
||||
result = history[current] .. "\n"
|
||||
else
|
||||
history[current] = history[current] .. value
|
||||
@ -312,7 +318,7 @@ end
|
||||
|
||||
function term.write(value, wrap)
|
||||
value = tostring(value)
|
||||
if value:len() == 0 or not term.isAvailable() then
|
||||
if value:ulen() == 0 or not term.isAvailable() then
|
||||
return
|
||||
end
|
||||
value = value:gsub("\t", " ")
|
||||
@ -329,18 +335,18 @@ function term.write(value, wrap)
|
||||
end
|
||||
end
|
||||
for line, nl in value:gmatch("([^\r\n]*)([\r\n]?)") do
|
||||
while wrap and line:len() > w - cursorX + 1 do
|
||||
local partial = line:sub(1, w - cursorX + 1)
|
||||
line = line:sub(partial:len() + 1)
|
||||
while wrap and line:ulen() > w - cursorX + 1 do
|
||||
local partial = line:usub(1, w - cursorX + 1)
|
||||
line = line:usub(partial:ulen() + 1)
|
||||
gpu.set(cursorX, cursorY, partial)
|
||||
cursorX = cursorX + partial:len()
|
||||
cursorX = cursorX + partial:ulen()
|
||||
checkCursor()
|
||||
end
|
||||
if line:len() > 0 then
|
||||
if line:ulen() > 0 then
|
||||
gpu.set(cursorX, cursorY, line)
|
||||
cursorX = cursorX + line:len()
|
||||
cursorX = cursorX + line:ulen()
|
||||
end
|
||||
if nl:len() == 1 then
|
||||
if nl:ulen() == 1 then
|
||||
cursorX = 1
|
||||
cursorY = cursorY + 1
|
||||
checkCursor()
|
||||
|
@ -24,6 +24,7 @@ object Config {
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
var baseMemory = 0
|
||||
var commandUser = "OpenComputers"
|
||||
var fileCost = 512
|
||||
var filesBuffered = true
|
||||
var maxScreenHeight = 6
|
||||
@ -83,6 +84,12 @@ object Config {
|
||||
"global and applies to all computers!").
|
||||
getInt(baseMemory)
|
||||
|
||||
commandUser = config.get("server", "commandUser", commandUser, "" +
|
||||
"The user name to specify when executing a command via a command block. If\n" +
|
||||
"you leave this empty it will use the address of the network node that sent\n" +
|
||||
"the execution request - which will usually be a computer.").
|
||||
getString
|
||||
|
||||
fileCost = config.get("server", "fileCost", fileCost, "" +
|
||||
"The base 'cost' of a single file or directory on a limited file system,\n" +
|
||||
"such as hard drives. When computing the used space we add this cost to\n" +
|
||||
|
@ -84,7 +84,7 @@ trait Component extends Node {
|
||||
def canBeSeenBy(other: Node) = componentVisibility match {
|
||||
case Visibility.None => false
|
||||
case Visibility.Network => true
|
||||
case Visibility.Neighbors => network.exists(_.neighbors(other).exists(_ == this))
|
||||
case Visibility.Neighbors => other.network.exists(_.neighbors(other).exists(_ == this))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -9,7 +9,7 @@ class Computer(playerInventory: InventoryPlayer, val computer: tileentity.Comput
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
fontRenderer.drawString(
|
||||
StatCollector.translateToLocal("oc.container.computer"),
|
||||
StatCollector.translateToLocal("oc.container.Computer"),
|
||||
8, 6, 0x404040)
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ class DiskDrive(playerInventory: InventoryPlayer, val drive: tileentity.DiskDriv
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
fontRenderer.drawString(
|
||||
StatCollector.translateToLocal("oc.container.disk_drive"),
|
||||
StatCollector.translateToLocal("oc.container.DiskDrive"),
|
||||
8, 6, 0x404040)
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,6 @@ class Keyboard(val parent: SpecialDelegator) extends SpecialDelegate {
|
||||
|
||||
val unlocalizedName = "Keyboard"
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Tile entity
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def hasTileEntity = true
|
||||
|
||||
override def createTileEntity(world: World, metadata: Int) = Some(new tileentity.Keyboard)
|
||||
|
@ -4,9 +4,9 @@ import dan200.computer.api.{ILuaContext, IComputerAccess, IPeripheral}
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.network.{Message, Visibility, Node}
|
||||
import li.cil.oc.server.driver
|
||||
import net.minecraft.nbt.{NBTTagString, NBTTagList, NBTTagCompound}
|
||||
import net.minecraftforge.common.ForgeDirection
|
||||
import scala.collection.mutable
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class Adapter extends Rotatable with Node with IPeripheral {
|
||||
val name = "adapter"
|
||||
@ -15,6 +15,8 @@ class Adapter extends Rotatable with Node with IPeripheral {
|
||||
|
||||
private val blocks = Array.fill[Option[(Node, api.driver.Block)]](6)(None)
|
||||
|
||||
private val blocksAddresses = Array.fill[String](6)(java.util.UUID.randomUUID.toString)
|
||||
|
||||
private val computers = mutable.ArrayBuffer.empty[IComputerAccess]
|
||||
|
||||
private val openPorts = mutable.Map.empty[IComputerAccess, mutable.Set[Int]]
|
||||
@ -52,12 +54,14 @@ class Adapter extends Rotatable with Node with IPeripheral {
|
||||
// This is... odd.
|
||||
network.foreach(_.disconnect(this, node))
|
||||
val newNode = newDriver.node(worldObj, x, y, z)
|
||||
newNode.address = Some(blocksAddresses(d.ordinal()))
|
||||
network.foreach(_.connect(this, newNode))
|
||||
blocks(d.ordinal()) = Some((newNode, newDriver))
|
||||
} // else: the more things change, the more they stay the same.
|
||||
case _ =>
|
||||
// A challenger appears.
|
||||
val node = newDriver.node(worldObj, x, y, z)
|
||||
node.address = Some(blocksAddresses(d.ordinal()))
|
||||
network.foreach(_.connect(this, node))
|
||||
blocks(d.ordinal()) = Some((node, newDriver))
|
||||
}
|
||||
@ -75,14 +79,29 @@ class Adapter extends Rotatable with Node with IPeripheral {
|
||||
override def readFromNBT(nbt: NBTTagCompound) {
|
||||
super.readFromNBT(nbt)
|
||||
load(nbt.getCompoundTag("node"))
|
||||
|
||||
val addressesNbt = nbt.getTagList("addresses")
|
||||
(0 until (addressesNbt.tagCount min blocksAddresses.length)).
|
||||
map(addressesNbt.tagAt).
|
||||
map(_.asInstanceOf[NBTTagString].data).
|
||||
zipWithIndex.
|
||||
foreach {
|
||||
case (a, i) => blocksAddresses(i) = a
|
||||
}
|
||||
}
|
||||
|
||||
override def writeToNBT(nbt: NBTTagCompound) {
|
||||
super.writeToNBT(nbt)
|
||||
|
||||
val nodeNbt = new NBTTagCompound
|
||||
val nodeNbt = new NBTTagCompound()
|
||||
save(nodeNbt)
|
||||
nbt.setCompoundTag("node", nodeNbt)
|
||||
|
||||
val addressesNbt = new NBTTagList()
|
||||
for (i <- 0 until blocksAddresses.length) {
|
||||
addressesNbt.appendTag(new NBTTagString(null, blocksAddresses(i)))
|
||||
}
|
||||
nbt.setTag("addresses", addressesNbt)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -88,7 +88,7 @@ class Computer(isClient: Boolean) extends Rotatable with component.Computer.Envi
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def getInvName = "oc.container.computer"
|
||||
def getInvName = "oc.container.Computer"
|
||||
|
||||
def getSizeInventory = 8
|
||||
|
||||
|
@ -46,7 +46,7 @@ class DiskDrive extends Rotatable with Component with ComponentInventory {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def getInvName = "oc.container.disk_drive"
|
||||
def getInvName = "oc.container.DiskDrive"
|
||||
|
||||
def getSizeInventory = 1
|
||||
|
||||
|
@ -44,5 +44,5 @@ class Keyboard extends Rotatable with Component {
|
||||
}
|
||||
|
||||
def isUseableByPlayer(p: Player) = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) == this &&
|
||||
p.asInstanceOf[EntityPlayer].getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 16
|
||||
p.asInstanceOf[EntityPlayer].getDistanceSq(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5) < 64
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package li.cil.oc.server.component
|
||||
|
||||
import li.cil.oc.Config
|
||||
import li.cil.oc.api.network.{Component, Message, Visibility}
|
||||
import net.minecraft.tileentity.TileEntityCommandBlock
|
||||
|
||||
@ -19,7 +20,11 @@ class CommandBlock(entity: TileEntityCommandBlock) extends Component {
|
||||
entity.worldObj.markBlockForUpdate(entity.xCoord, entity.yCoord, entity.zCoord)
|
||||
result(true)
|
||||
case Array() if message.name == "command.run" =>
|
||||
entity.setCommandSenderName(message.source.address.get)
|
||||
val name = if (Config.commandUser != null && !Config.commandUser.trim.isEmpty)
|
||||
Config.commandUser.trim
|
||||
else
|
||||
message.source.address.get
|
||||
entity.setCommandSenderName(name)
|
||||
result(entity.executeCommandOnPowered(entity.worldObj) != 0)
|
||||
case _ => None
|
||||
}
|
||||
|
@ -606,8 +606,13 @@ class Computer(val owner: Computer.Environment) extends Persistable with Runnabl
|
||||
|
||||
lua.pushScalaFunction(lua => {
|
||||
owner.network.fold(None: Option[Node])(_.node(lua.checkString(1))) match {
|
||||
case None => 0
|
||||
case Some(node) => lua.pushString(node.name); 1
|
||||
case Some(node: Component) if node.canBeSeenBy(this.owner) =>
|
||||
lua.pushString(node.name)
|
||||
1
|
||||
case None =>
|
||||
lua.pushNil()
|
||||
lua.pushString("invalid address")
|
||||
2
|
||||
}
|
||||
})
|
||||
lua.setGlobal("nodeName")
|
||||
@ -865,7 +870,10 @@ object Computer {
|
||||
message.data match {
|
||||
case Array() if message.name == "system.disconnect" && computer.isRunning =>
|
||||
message.source match {
|
||||
case node: Component if node.canBeSeenBy(this) =>
|
||||
case node: Component =>
|
||||
// This is also generated for components that were never added,
|
||||
// because the node has already been removed from the network at
|
||||
// this point, so we cannot check for visibility anymore.
|
||||
computer.signal("component_removed", message.source.address.get); None
|
||||
case _ => None
|
||||
}
|
||||
|
@ -142,10 +142,6 @@ object LuaStateFactory {
|
||||
state.setGlobal("dofile")
|
||||
state.pushNil()
|
||||
state.setGlobal("loadfile")
|
||||
state.pushNil()
|
||||
state.setGlobal("module")
|
||||
state.pushNil()
|
||||
state.setGlobal("require")
|
||||
|
||||
// Push a couple of functions that override original Lua API functions or
|
||||
// that add new functionality to it.
|
||||
@ -218,20 +214,6 @@ object LuaStateFactory {
|
||||
// Provide some better Unicode support.
|
||||
state.getGlobal("string")
|
||||
|
||||
// Rename stuff for binary functionality, to allow byte-wise operations
|
||||
// operations on the string.
|
||||
state.getField(-1, "sub")
|
||||
state.setField(-2, "bsub")
|
||||
|
||||
state.getField(-1, "reverse")
|
||||
state.setField(-2, "breverse")
|
||||
|
||||
state.pushScalaFunction(lua => {
|
||||
lua.pushString(String.valueOf((1 to lua.getTop).map(lua.checkInteger).map(_.toChar).toArray))
|
||||
1
|
||||
})
|
||||
state.setField(-2, "char")
|
||||
|
||||
// TODO find (probably not necessary?)
|
||||
|
||||
// TODO format (probably not necessary?)
|
||||
@ -240,11 +222,7 @@ object LuaStateFactory {
|
||||
|
||||
// TODO gsub (probably not necessary?)
|
||||
|
||||
state.pushScalaFunction(lua => {
|
||||
lua.pushInteger(lua.checkString(1).length)
|
||||
1
|
||||
})
|
||||
state.setField(-2, "len")
|
||||
// TODO match (probably not necessary?)
|
||||
|
||||
state.pushScalaFunction(lua => {
|
||||
lua.pushString(lua.checkString(1).toLowerCase)
|
||||
@ -252,13 +230,29 @@ object LuaStateFactory {
|
||||
})
|
||||
state.setField(-2, "lower")
|
||||
|
||||
// TODO match (probably not necessary?)
|
||||
state.pushScalaFunction(lua => {
|
||||
lua.pushString(lua.checkString(1).toUpperCase)
|
||||
1
|
||||
})
|
||||
state.setField(-2, "upper")
|
||||
|
||||
state.pushScalaFunction(lua => {
|
||||
lua.pushString(String.valueOf((1 to lua.getTop).map(lua.checkInteger).map(_.toChar).toArray))
|
||||
1
|
||||
})
|
||||
state.setField(-2, "uchar")
|
||||
|
||||
state.pushScalaFunction(lua => {
|
||||
lua.pushInteger(lua.checkString(1).length)
|
||||
1
|
||||
})
|
||||
state.setField(-2, "ulen")
|
||||
|
||||
state.pushScalaFunction(lua => {
|
||||
lua.pushString(lua.checkString(1).reverse)
|
||||
1
|
||||
})
|
||||
state.setField(-2, "reverse")
|
||||
state.setField(-2, "ureverse")
|
||||
|
||||
state.pushScalaFunction(lua => {
|
||||
val string = lua.checkString(1)
|
||||
@ -276,13 +270,7 @@ object LuaStateFactory {
|
||||
else lua.pushString(string.substring(start, end))
|
||||
1
|
||||
})
|
||||
state.setField(-2, "sub")
|
||||
|
||||
state.pushScalaFunction(lua => {
|
||||
lua.pushString(lua.checkString(1).toUpperCase)
|
||||
1
|
||||
})
|
||||
state.setField(-2, "upper")
|
||||
state.setField(-2, "usub")
|
||||
|
||||
// Pop the string table.
|
||||
state.pop(1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user