diff --git a/build.properties b/build.properties index 068350f22..6beec2877 100644 --- a/build.properties +++ b/build.properties @@ -4,7 +4,7 @@ forge.version=13.20.0.2252 mod.name=OpenComputers mod.group=li.cil.oc -mod.version=1.7.3 +mod.version=1.7.4 forestry.version=5.3.1.38 ic2.version=2.7.85-ex111 diff --git a/changelog.md b/changelog.md index 3395dcbf1..96ec772db 100644 --- a/changelog.md +++ b/changelog.md @@ -1,121 +1,25 @@ ## New Features/Support -* Misc: Greatly improved Lua execution speed (asiekierka) - - That means OC now executes Lua code roughly 70% faster than before. -* Misc: Improved Filesystem and block data saving performance - - Saving computers to disk is now anything between 5 and 500 times faster than before, depending on your system. Maybe even more. -* **Added: The Net Splitter is now a `net_splitter` component** - - This allows using computers to connect and disconnect various parts of your network. - - Make sure not to accidentally disconnect your controller! -* **Added: New feature for filesystems: Locked mode!** - - A locked filesystem is read-only and cannot be unlocked unless recrafted or its mode is switched between managed and unmanaged, either action wiping the drive. - - The name of the player who locked it is shown in the tooltip, allowing authenticated sharing of data. -* Added: Bundled redstone support for ComputerCraft (SquidDev) -* Added: `debug.getlocal` and `debug.getupvalue` - - They only return the name of the variable, and nothing else. -* Added: `isSunVisible`, `canSeeSky`, and `detect` to geolyzers -* Added: Allow using morse code patterns like `.-.` in `computer.beep` -* Added: redstone component's `setOutput` can now accept values larger than 15 -* Added: Allow the keyboard to connect to screens in more ways than before, e.g. facing a side of the screen other than its front -* Added: Readded Project Red support on Minecraft 1.12 (BrisingrAerowing) -* Added: Driver for the Reactor Chamber from IC2 -* Added: Inventory GUI for the rack-mounted disk drives - - Can be accessed either by clicking on the rack or by right clicking the drive in your inventory. -* Added: `getMerchantId` to trade offers from the Trading Upgrade to help with sorting them -* Added: Readded AE2 power support on Minecraft 1.12, meaning you can now power your computers directly off the ME network again. -* Added: `scanContentsAt` to debug card -* Added: More accessible information from Draconic Evolution items -* Added: Waypoints can now be placed facing up or down -* Added: You can now craft two linked cards together to link them to one another - - This will unlink them from any previously connected Linked Card. - - The link channel is also exposed as a property on the item that transposers etc. can read, meaning that you can easily manage multiple linked cards. -* Added: Allow `setFrequency` on owned Ender Storage chests (payonel and amesgen) -* Added: You can now trigger wake-on-LAN over Linked Cards -* Added: `chunkloaderDimensionBlacklist` and `chunkloaderDimensionWhitelist` to config for (dis)allowing certain dimensions for the chunkloader upgrade -* Added: `disk_drive.media` function that returns the address of the inserted floppy disk -* Added: Forge Energy support to items - - Battery upgrades, tablets, and hover boots can be charged in Forge Energy compatible devices - - Battery upgrades also support power extraction, allowing them to recharge Forge Energy devices acting as normal batteries -* Added: The Analyzer now reports the internal components of an Adapter block when right-clicked -* **Changed: `redstone_changed` event for bundled signals** - - Now includes the colour that changed, and only reports the old and new values for that colour -* Changed: The order in which cases are filled with components is now based on the slot tiers -* Changed: OpenComputers is now a lot more quiet in the server log. (kmecpp) -* **Changed: `robot.suck`, `robot.suckFromSlot`, and `transposer.transferItem` return values** - - Instead of `true`, they now return the number of transferred items on success. -* Changed: Use less annoying particles for nanomachines -* Changed: Increased default number of platters in an (unmanaged) Tier 3 Hard Drive from 6 to 8 - - You will have to update an existing config yourself by changing `hddPlatterCounts`. -* Misc: Improved cable rendering (SquidDev) -* Misc: Robot inventories should now be compatible with even more modded inventory manipulation things -* Misc: Robot Crafting (the Crafting Upgrade) should now be compatible with even more modded recipes -* Misc: Screens should now stop working a lot less on server restarts etc. and be generally a lot more robust -* Misc: Robot `swing` and `use` should now be _a lot_ more robust and work with a lot more modded items like Hammers and Bows from Tinkers' Construct -* Misc: Robot tank interactions should now work well with a wide range of modded tanks. -* Misc: Improved chunkloader upgrade (svitoos) - - Chunkloaders are now allowed in Microcontrollers. -* Misc: Added more unicode glyphs to font (asiekierka) -* Misc: The default Lua EEPROM now uses less RAM -* Fixed: Inventory loss during minecraft server crashes -* Fixed: Crash when placing microcontroller -* Fixed: Allow the robot to swing at anything that would block its movement -* Fixed: `oc_nanomachines` or `oc_nm` command not always working on servers -* Fixed: Item duplication bug involving robots and voodoo magic -* Fixed: Robot `move` commands not always _actually_ returning whether the robot really moved or not -* Fixed: Forcing the use of the LuaJ architecture not forcing the use of the LuaJ architecture -* Fixed: `transferItem` checking the wrong side (cyb0124) -* Fixed: "Unknown error" when transfering fluid to certain machines -* Fixed: Item duplication bug involving drones and Wither voodoo magic -* Fixed: Potential error with IC2 on launch -* Fixed: Robots eating items they shouldn't eat when crafting -* Fixed: Angel Upgrade not doing the one job it had -* Fixed: Robots being really bad at trading with villagers. They were sent to business school so now they are a lot better at it. -* Fixed: Robots forgetting how to move -* Fixed: Item duplication bug involving robots and drones doing shady business with one another -* Fixed: Network floppy disk not installing -* Fixed: Fluid duplication bug involving robots being bad at draining fluids -* Fixed: Drones getting funky after a wake-on-LAN -* Fixed: Weird item update glitches involving robots and certain blocks like AE2 Interfaces -* Fixed: Item duplication bugs involving EEPROMs' desire to behave like quantum particles -* Fixed: Various fixes to AE2 integration - - `slot` parameter in `exportIntoSlot` of the Export Bus is now an optional parameter -* Fixed: Crash with Applied Llamagistics -* Fixed: Crashes when you try to spawn computers by... unconventional means -* Fixed: Setting `enableNanomachinePfx` to `false` in the config not actually doing anything -* Fixed: When a robot gains experience, it now properly triggers modded effects that happen on XP Orb pickup -* Fixed: Confusing Analyzer reports on computers that are shut down -* Fixed: Microcontrollers now properly shutting down internal components -* Fixed: Leash upgrade erroring for addon developers (josephcsible) -* Fixed: World Sensor Card crafting recipe on Minecraft 1.10 and above -* Fixed: Client crash involving cables and chunk loading (thiakil) -* Fixed: Tablet screen freezing on certain events -* Fixed: Terminal servers not properly connecting their Remote Terminals -* Fixed: Lightning issues with ShaderMod (paulhobbel) +* **Misc: when powering on, drones may fly a bit higher** + - will fly a above their starting block to get above nonfull blocks (such as chests) +* Misc: more robot names +* Misc: robot/drone swing respects harvestability of block vs tool +* Fixed: zero sized files (bufferChanges failing to do its job) +* Fixed: client crash when using remote terminal out of range +* Fixed: inventory controllers now honor specified target slot +* Fixed: T1 wireless cards now ignore properly ignore wired messages +* Fixed: waila integration by checking for nulls with relay block +* Fixed: practical logisitics integration by not passing null for EnumFacing +* Fixed: locking items in hotbar when gui is open ## OpenOS fixes/improvements -* Added: `reset` command that clears the screen and resets the resolution to maximum -* Added: rc errors are now being logged to /tmp/event.log -* Added: -f option to cp -* Added: aliases as part of tab complete in shell -* Added: devfs psuedo files can now be zero-size -* Added: Allow processes to handle hard interrupts - - The process metadata now contains a `signal` field that is triggered on hard interrupts -* Added: Support for `\b` and `\r` characters to tty -* Added: Cut and Uncut to `edit` (AntiBlueQuirk) - - Ctrl+K to cut, Ctrl+U to insert a line -* Misc: tty and cursor logic separated, reducing memory cost for custom cursor behavior with term options -* Misc: Improved command substitution, now more like Linux sh -* Misc: `less` is now the program used for `man` -* Fixed: Various vt100 fixes -* Fixed: Processes now close file handles on exit -* Fixed: Autorun on read-only filesystems -* Fixed: Crash in `edit` +* Fixed: fixed event timing issues when pulling smaller timeouts than a current timer +* Added: tty handles '\v' code to move cursor down one line +* Misc: some openos cleanup +* Misc: more memory savings +* Misc: slightly faster boot up times ## List of contributors -payonel, Vexatos, -asiekierka, SquidDev, -kmecpp, BrisingrAerowing, -cyb0124, svitoos, -AntiBlueQuirk, josephcsible, -amesgen, thiakil, paulhobbel +payonel, Wilma456 +Anar Abdullayev, TheCodex6824 diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/mktmp.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/mktmp.lua index abcc1ec18..9fab5d2dc 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/mktmp.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/mktmp.lua @@ -13,17 +13,18 @@ end local args, ops = shell.parse(...) -local function pop(key) - local result = ops[key] - ops[key] = nil +local function pop(...) + local result + for _,key in ipairs({...}) do + result = ops[key] or result + ops[key] = nil + end return result end local directory = pop('d') -local verbose = pop('v') -verbose = pop('verbose') or verbose -local quiet = pop('q') or quiet -quiet = pop('quiet') or quiet +local verbose = pop('v', 'verbose') +local quiet = pop('q', 'quiet') if pop('help') or #args > 1 or next(ops) then print([[Usage: mktmp [OPTION] [PATH] diff --git a/src/main/resources/assets/opencomputers/loot/openos/bin/sh.lua b/src/main/resources/assets/opencomputers/loot/openos/bin/sh.lua index ec28ad8c7..ae33bd3c9 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/bin/sh.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/bin/sh.lua @@ -1,26 +1,24 @@ -local event = require("event") local shell = require("shell") local tty = require("tty") local text = require("text") local sh = require("sh") -local args, options = shell.parse(...) +local args = shell.parse(...) shell.prime() -local needs_profile = io.input().tty -local has_prompt = needs_profile and io.output().tty and not options.c -local input_handler = {hint = sh.hintHandler} if #args == 0 then + local has_profile + local input_handler = {hint = sh.hintHandler} while true do - if has_prompt then - while not tty.isAvailable() do - event.pull(.5, "term_available") - end - if needs_profile then -- first time run AND interactive - needs_profile = nil + if io.stdin.tty and io.stdout.tty then + if not has_profile then -- first time run AND interactive + has_profile = true dofile("/etc/profile.lua") end + if tty.getCursor() > 1 then + io.write("\n") + end io.write(sh.expand(os.getenv("PS1") or "$ ")) end tty.window.cursor = input_handler @@ -31,6 +29,7 @@ if #args == 0 then if command == "exit" then return elseif command ~= "" then + --luacheck: globals _ENV local result, reason = sh.execute(_ENV, command) if not result then io.stderr:write((reason and tostring(reason) or "unknown error") .. "\n") @@ -39,9 +38,6 @@ if #args == 0 then elseif command == nil then -- false only means the input was interrupted return -- eof end - if has_prompt and tty.getCursor() > 1 then - io.write("\n") - end end else -- execute command. diff --git a/src/main/resources/assets/opencomputers/loot/openos/boot/92_keyboard.lua b/src/main/resources/assets/opencomputers/loot/openos/boot/92_keyboard.lua index 3865c45d0..2cce8c1ff 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/boot/92_keyboard.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/boot/92_keyboard.lua @@ -1,40 +1,12 @@ -local component = require("component") local event = require("event") local keyboard = require("keyboard") -local function onKeyDown(_, address, char, code) - if keyboard.pressedChars[address] then - keyboard.pressedChars[address][char] = true - keyboard.pressedCodes[address][code] = true - end +local function onKeyChange(ev, _, char, code) + -- nil might be slightly more mem friendly during runtime + -- and `or nil` appears to only cost 30 bytes + keyboard.pressedChars[char] = ev == "key_down" or nil + keyboard.pressedCodes[code] = ev == "key_down" or nil end -local function onKeyUp(_, address, char, code) - if keyboard.pressedChars[address] then - keyboard.pressedChars[address][char] = nil - keyboard.pressedCodes[address][code] = nil - end -end - -local function onComponentAdded(_, address, componentType) - if componentType == "keyboard" then - keyboard.pressedChars[address] = {} - keyboard.pressedCodes[address] = {} - end -end - -local function onComponentRemoved(_, address, componentType) - if componentType == "keyboard" then - keyboard.pressedChars[address] = nil - keyboard.pressedCodes[address] = nil - end -end - -for address in component.list("keyboard", true) do - onComponentAdded("component_added", address, "keyboard") -end - -event.listen("key_down", onKeyDown) -event.listen("key_up", onKeyUp) -event.listen("component_added", onComponentAdded) -event.listen("component_removed", onComponentRemoved) +event.listen("key_down", onKeyChange) +event.listen("key_up", onKeyChange) diff --git a/src/main/resources/assets/opencomputers/loot/openos/etc/motd b/src/main/resources/assets/opencomputers/loot/openos/etc/motd index da961297b..0c73a8250 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/etc/motd +++ b/src/main/resources/assets/opencomputers/loot/openos/etc/motd @@ -3,10 +3,6 @@ local computer = require("computer") local unicode = require("unicode") local tty = require("tty") -if not component.isAvailable("gpu") then - return -end - local f = io.open("/usr/misc/greetings.txt") local lines = {_OSVERSION .. " (" .. math.floor(computer.totalMemory() / 1024) .. "k RAM)"} local greeting = "" @@ -18,7 +14,7 @@ if f then f:close() greeting = greetings[math.random(1, math.max(#greetings, 1))] or "" end -local width = math.min(#greeting, tty.getViewport() - 5) +local width = math.min(#greeting, (tty.getViewport() or math.huge) - 5) local maxLine = #lines[1] while #greeting > 0 do local si, ei = greeting:sub(1, width):find("%s%S*$") diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/core/boot.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/core/boot.lua index 904b7e905..4e51bf576 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/core/boot.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/core/boot.lua @@ -1,8 +1,9 @@ -- called from /init.lua local raw_loadfile = ... -_G._OSVERSION = "OpenOS 1.7.3" +_G._OSVERSION = "OpenOS 1.7.4" +-- luacheck: globals component computer unicode _OSVERSION local component = component local computer = computer local unicode = unicode @@ -20,28 +21,23 @@ computer.shutdown = function(reboot) shutdown(reboot) end -local screen = component.list('screen', true)() -for address in component.list('screen', true) do - if #component.invoke(address, 'getKeyboards') > 0 then - screen = address - break - end -end - -_G.boot_screen = screen - --- Report boot progress if possible. -local gpu = component.list("gpu", true)() local w, h -if gpu and screen then +local screen = component.list("screen", true)() +local gpu = screen and component.list("gpu", true)() +if gpu then gpu = component.proxy(gpu) - gpu.bind(screen) + if not gpu.getScreen() then + gpu.bind(screen) + end + _G.boot_screen = gpu.getScreen() w, h = gpu.maxResolution() gpu.setResolution(w, h) gpu.setBackground(0x000000) gpu.setForeground(0xFFFFFF) gpu.fill(1, 1, w, h, " ") end + +-- Report boot progress if possible. local y = 1 local uptime = computer.uptime -- we actually want to ref the original pullSignal here because /lib/event intercepts it later @@ -49,7 +45,7 @@ local uptime = computer.uptime local pull = computer.pullSignal local last_sleep = uptime() local function status(msg) - if gpu and screen then + if gpu then gpu.set(1, y, msg) if y == h then gpu.copy(1, 2, w, h - 1, 0, -1) diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_filesystem.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_filesystem.lua index 1a67f1763..fdf55dc79 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_filesystem.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_filesystem.lua @@ -335,6 +335,7 @@ function filesystem.setAutorunEnabled(value) saveConfig() end +-- luacheck: globals os os.remove = filesystem.remove os.rename = filesystem.rename diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/event.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/event.lua index 2c45d2e68..e7c5e6e23 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/event.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/event.lua @@ -30,44 +30,57 @@ end local _pullSignal = computer.pullSignal setmetatable(handlers, {__call=function(_,...)return _pullSignal(...)end}) -computer.pullSignal = function(...) -- dispatch +computer.pullSignal = function(seconds) -- dispatch + checkArg(1, seconds, "number", "nil") + seconds = seconds or math.huge local current_time = computer.uptime() - local interrupting = current_time - lastInterrupt > 1 and keyboard.isControlDown() and keyboard.isKeyDown(keyboard.keys.c) - if interrupting then - lastInterrupt = current_time - if keyboard.isAltDown() then - require("process").info().data.signal("interrupted", 0) - return - end - event.push("interrupted", current_time) - end - local event_data = table.pack(handlers(...)) - local signal = event_data[1] - local copy = {} - for id,handler in pairs(handlers) do - copy[id] = handler - end - for id,handler in pairs(copy) do - -- timers have false keys - -- nil keys match anything - if (handler.key == nil or handler.key == signal) or current_time >= handler.timeout then - handler.times = handler.times - 1 - handler.timeout = current_time + handler.interval - -- we have to remove handlers before making the callback in case of timers that pull - -- and we have to check handlers[id] == handler because callbacks may have unregistered things - if handler.times <= 0 and handlers[id] == handler then - handlers[id] = nil + local deadline = computer.uptime() + seconds + repeat + local interrupting = current_time - lastInterrupt > 1 and keyboard.isControlDown() and keyboard.isKeyDown(keyboard.keys.c) + if interrupting then + lastInterrupt = current_time + if keyboard.isAltDown() then + require("process").info().data.signal("interrupted", 0) + return end - -- call - local result, message = pcall(handler.callback, table.unpack(event_data, 1, event_data.n)) - if not result then - pcall(event.onError, message) - elseif message == false and handlers[id] == handler then - handlers[id] = nil + event.push("interrupted", current_time) + end + + local closest = deadline + for _,handler in pairs(handlers) do + closest = math.min(handler.timeout, closest) + end + + local event_data = table.pack(handlers(closest - computer.uptime())) + local signal = event_data[1] + local copy = {} + for id,handler in pairs(handlers) do + copy[id] = handler + end + for id,handler in pairs(copy) do + -- timers have false keys + -- nil keys match anything + if (handler.key == nil or handler.key == signal) or current_time >= handler.timeout then + handler.times = handler.times - 1 + handler.timeout = current_time + handler.interval + -- we have to remove handlers before making the callback in case of timers that pull + -- and we have to check handlers[id] == handler because callbacks may have unregistered things + if handler.times <= 0 and handlers[id] == handler then + handlers[id] = nil + end + -- call + local result, message = pcall(handler.callback, table.unpack(event_data, 1, event_data.n)) + if not result then + pcall(event.onError, message) + elseif message == false and handlers[id] == handler then + handlers[id] = nil + end end end - end - return table.unpack(event_data, 1, event_data.n) + if signal then + return table.unpack(event_data, 1, event_data.n) + end + until computer.uptime() >= deadline end local function createPlainFilter(name, ...) @@ -116,7 +129,7 @@ end function event.pullFiltered(...) local args = table.pack(...) - local seconds, filter + local seconds, filter = math.huge if type(args[1]) == "function" then filter = args[1] @@ -127,19 +140,14 @@ function event.pullFiltered(...) filter = args[2] end - local deadline = seconds and (computer.uptime() + seconds) or math.huge repeat - local closest = deadline - for _,handler in pairs(handlers) do - closest = math.min(handler.timeout, closest) - end - local signal = table.pack(computer.pullSignal(closest - computer.uptime())) + local signal = table.pack(computer.pullSignal(seconds)) if signal.n > 0 then if not (seconds or filter) or filter == nil or filter(table.unpack(signal, 1, signal.n)) then return table.unpack(signal, 1, signal.n) end end - until computer.uptime() >= deadline + until signal.n == 0 end -- users may expect to find event.push to exist diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/io.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/io.lua index 5d1fe7f4a..1a6f25ce7 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/io.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/io.lua @@ -115,6 +115,8 @@ local dup_mt = {__index = function(dfd, key) if key == "close" or self._closed then self._closed = true return end return fd_value(self.fd, ...) end +end, __newindex = function(dfd, key, value) + dfd.fd[key] = value end} function io.dup(fd) diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/keyboard.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/keyboard.lua index a0a68907d..777d83024 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/keyboard.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/keyboard.lua @@ -33,52 +33,29 @@ keyboard.keys = { ------------------------------------------------------------------------------- -local function getKeyboardAddress(address) - return address or require("tty").keyboard() -end - -local function getPressedCodes(address) - address = getKeyboardAddress(address) - return address and keyboard.pressedCodes[address] or false -end - -local function getPressedChars(address) - address = getKeyboardAddress(address) - return address and keyboard.pressedChars[address] or false -end - -function keyboard.isAltDown(address) - checkArg(1, address, "string", "nil") - local pressedCodes = getPressedCodes(address) - return pressedCodes and (pressedCodes[keyboard.keys.lmenu] or pressedCodes[keyboard.keys.rmenu]) ~= nil +function keyboard.isAltDown() + return keyboard.pressedCodes[keyboard.keys.lmenu] or keyboard.pressedCodes[keyboard.keys.rmenu] end function keyboard.isControl(char) return type(char) == "number" and (char < 0x20 or (char >= 0x7F and char <= 0x9F)) end -function keyboard.isControlDown(address) - checkArg(1, address, "string", "nil") - local pressedCodes = getPressedCodes(address) - return pressedCodes and (pressedCodes[keyboard.keys.lcontrol] or pressedCodes[keyboard.keys.rcontrol]) ~= nil +function keyboard.isControlDown() + return keyboard.pressedCodes[keyboard.keys.lcontrol] or keyboard.pressedCodes[keyboard.keys.rcontrol] end -function keyboard.isKeyDown(charOrCode, address) +function keyboard.isKeyDown(charOrCode) checkArg(1, charOrCode, "string", "number") - checkArg(2, address, "string", "nil") if type(charOrCode) == "string" then - local pressedChars = getPressedChars(address) - return pressedChars and pressedChars[utf8 and utf8.codepoint(charOrCode) or charOrCode:byte()] + return keyboard.pressedChars[utf8 and utf8.codepoint(charOrCode) or charOrCode:byte()] elseif type(charOrCode) == "number" then - local pressedCodes = getPressedCodes(address) - return pressedCodes and pressedCodes[charOrCode] + return keyboard.pressedCodes[charOrCode] end end -function keyboard.isShiftDown(address) - checkArg(1, address, "string", "nil") - local pressedCodes = getPressedCodes(address) - return pressedCodes and (pressedCodes[keyboard.keys.lshift] or pressedCodes[keyboard.keys.rshift]) ~= nil +function keyboard.isShiftDown() + return keyboard.pressedCodes[keyboard.keys.lshift] or keyboard.pressedCodes[keyboard.keys.rshift] end ------------------------------------------------------------------------------- diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/tty.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/tty.lua index 60b694f22..6c5c7cf25 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/tty.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/tty.lua @@ -79,7 +79,9 @@ function tty.stream:write(value) return end local window = tty.window - local cursor = window.cursor or {sy = 0, tails = {}} + local cursor = window.cursor or {} + cursor.sy = cursor.sy or 0 + cursor.tails = cursor.tails or {} local beeped local uptime = computer.uptime local last_sleep = uptime() diff --git a/src/main/scala/li/cil/oc/common/entity/Drone.scala b/src/main/scala/li/cil/oc/common/entity/Drone.scala index ec0318fb9..7e9ee9e71 100644 --- a/src/main/scala/li/cil/oc/common/entity/Drone.scala +++ b/src/main/scala/li/cil/oc/common/entity/Drone.scala @@ -286,7 +286,7 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D def preparePowerUp() { targetX = math.floor(posX).toFloat + 0.5f - targetY = math.floor(posY).toFloat + 0.5f + targetY = math.round(posY).toFloat + 0.5f targetZ = math.floor(posZ).toFloat + 0.5f targetAcceleration = maxAcceleration diff --git a/src/main/scala/li/cil/oc/server/fs/Buffered.scala b/src/main/scala/li/cil/oc/server/fs/Buffered.scala index 97b2ff0b9..0a9443922 100644 --- a/src/main/scala/li/cil/oc/server/fs/Buffered.scala +++ b/src/main/scala/li/cil/oc/server/fs/Buffered.scala @@ -116,6 +116,7 @@ trait Buffered extends OutputStreamFileSystem { } deletions.clear() + val buffer = ByteBuffer.allocateDirect(16 * 1024) def recurse(path: String):Boolean = { val directory = new io.File(fileRoot, path) directory.mkdirs() @@ -133,7 +134,7 @@ trait Buffered extends OutputStreamFileSystem { val out = new io.FileOutputStream(childFile).getChannel val in = openInputChannel(childPath).get - val buffer = ByteBuffer.allocateDirect(16 * 1024) + buffer.clear() while (in.read(buffer) != -1) { buffer.flip() out.write(buffer)