Conflicts:
	src/main/java/li/cil/oc/common/item/ALU.scala
	src/main/java/li/cil/oc/common/item/Alu.scala
	src/main/java/li/cil/oc/server/component/FileSystem.scala
	src/main/java/li/cil/oc/server/component/Filesystem.scala
	src/main/scala/li/cil/oc/common/item/Alu.scala
	src/main/scala/li/cil/oc/server/component/Filesystem.scala
This commit is contained in:
Florian Nücke 2014-02-12 00:24:44 +01:00
commit d2d964bc8b
27 changed files with 323 additions and 72 deletions

View File

@ -16,4 +16,11 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE.
-------------------------------------------------------------------------------
All images / textures and localization strings (resources) are put in the
public domain. More specicially, see CC0 1.0 Universal:
http://creativecommons.org/publicdomain/zero/1.0/

View File

@ -133,7 +133,7 @@ oc:tooltip.Disk=Sehr einfaches Speichermedium, das verwendet werden kann, um Dis
oc:tooltip.DiskDrive.CC=ComputerCraft-Disketten werden §aunterstützt§7.
oc:tooltip.DiskDrive=Erlaubt es, Disketten zu lesen und zu beschreiben.
oc:tooltip.GraphicsCard=Erlaubt es, den angezeigten Inhalt von Bildschirmen zu ändern.[nl] Höchstauflösung: §f%sx%s§7.[nl] Maximale Farbtiefe: §f%s§7.[nl] Operationen/Tick: §f%s§7.
oc:tooltip.InternetCard=Diese Karte erlaubt es, HTTP-Anfragen zu senden und echte TCP und UDP Sockets zu verwenden.
oc:tooltip.InternetCard=Diese Karte erlaubt es, HTTP-Anfragen zu senden und echte TCP Sockets zu verwenden.
oc:tooltip.IronNugget=Ein Nugget, das aus Eisen besteht, darum wird es ja auch Eisennugget genannt, duh...
oc:tooltip.Keyboard=Kann an Bildschirmen befestigt werden, um auf ihnen zu tippen.
oc:tooltip.Memory=Braucht ein jeder Computer, um zu starten. Je mehr vorhanden, desto komplexere Programme können ausgeführt werden.

View File

@ -133,7 +133,7 @@ oc:tooltip.Disk=Primitive medium that can be used to build persistent storage de
oc:tooltip.DiskDrive.CC=ComputerCraft floppies are §asupported§7.
oc:tooltip.DiskDrive=Allows reading and writing floppies.
oc:tooltip.GraphicsCard=Used to change what's displayed on screens.[nl] Maximum resolution: §f%sx%s§7.[nl] Maximum color depth: §f%s§7.[nl] Operations/tick: §f%s§7.
oc:tooltip.InternetCard=This card allows making HTTP requests and using real TCP and UDP sockets.
oc:tooltip.InternetCard=This card allows making HTTP requests and using real TCP sockets.
oc:tooltip.IronNugget=A nugget made of iron, that's why it's called an Iron Nugget, duh...
oc:tooltip.Keyboard=Can be attached to screens to allow typing on them.
oc:tooltip.Memory=Required to get computers to run. The more you have, the more complex the programs you can run.

View File

@ -0,0 +1,170 @@
# Russian localization by YuRaNnNzZZ
# Use UTF-8 for this file.
# Blocks
oc:block.Adapter.name=Адаптер
oc:block.Cable.name=Кабель
oc:block.Capacitor.name=Аккумулятор
oc:block.Case0.name=Системный блок 1-го уровня
oc:block.Case1.name=Системный блок 2-го уровня
oc:block.Case2.name=Системный блок 3-го уровня
oc:block.Charger.name=Зарядное устройство
oc:block.DiskDrive.name=Дисковод
oc:block.Keyboard.name=Клавиатура
oc:block.PowerConverter.name=Преобразователь энергии
oc:block.PowerDistributor.name=Передатчик энергии
oc:block.Redstone.name=Обработчик сигналов красной пыли
oc:block.Robot.name=Робот
oc:block.RobotAfterimage.name=Робот
oc:block.Router.name=Маршрутизатор
oc:block.Screen0.name=Дисплей (Ур. 1)
oc:block.Screen1.name=Дисплей (Ур. 2)
oc:block.Screen2.name=Дисплей (Ур. 3)
oc:block.ServerRack.name=Серверная стойка
# Items
oc:item.AbstractBusCard.name=Плата абстрактной шины
oc:item.Acid.name=Кислота
oc:item.ALU.name=Арифметико-логическое устройство
oc:item.Analyzer.name=Анализатор
oc:item.ArrowKeys.name=Клавиши со стрелками
oc:item.ButtonGroup.name=Группа клавиш
oc:item.CardBase.name=Основа для карт
oc:item.CircuitBoard.name=Печатная плата
oc:item.ControlUnit.name=Блок управления
oc:item.CPU0.name=Центральный процессор (Ур. 1)
oc:item.CPU1.name=Центральный процессор (Ур. 2)
oc:item.CPU2.name=Центральный процессор (Ур. 3)
oc:item.CuttingWire.name=Проволока
oc:item.Disk.name=Металлический диск
oc:item.FloppyDisk.name=Дискета
oc:item.GraphicsCard0.name=Видеокарта (Ур. 1)
oc:item.GraphicsCard1.name=Видеокарта (Ур. 2)
oc:item.GraphicsCard2.name=Видеокарта (Ур. 3)
oc:item.HardDiskDrive0.name=Жёсткий диск (Ур. 1)
oc:item.HardDiskDrive1.name=Жёсткий диск (Ур. 2)
oc:item.HardDiskDrive2.name=Жёсткий диск (Ур. 3)
oc:item.InternetCard.name=Интернет-адаптер
oc:item.IronNugget.name=Железный самородок
oc:item.Memory0.name=ОЗУ (Ур. 1)
oc:item.Memory1.name=ОЗУ (Ур. 2)
oc:item.Memory2.name=ОЗУ (Ур. 2.5)
oc:item.Memory3.name=ОЗУ (Ур. 3)
oc:item.Memory4.name=ОЗУ (Ур. 3.5)
oc:item.Microchip0.name=Микросхема (Ур. 1)
oc:item.Microchip1.name=Микросхема (Ур. 2)
oc:item.Microchip2.name=Микросхема (Ур. 3)
oc:item.NetworkCard.name=Сетевой адаптер
oc:item.NumPad.name=Цифровые клавиши
oc:item.PrintedCircuitBoard.name=Печатная плата
oc:item.RawCircuitBoard.name=Основа для печатной платы
oc:item.RedstoneCard.name=Плата-обработчик сигналов красной пыли
oc:item.Server0.name=Сервер (Ур. 1)
oc:item.Server1.name=Сервер (Ур. 2)
oc:item.Server2.name=Сервер (Ур. 3)
oc:item.Terminal.name=Беспроводной терминал
oc:item.Transistor.name=Транзистор
oc:item.UpgradeCrafting.name=Верстак (Улучшение)
oc:item.UpgradeGenerator.name=Топливный генератор (Улучшение)
oc:item.UpgradeNavigation.name=Навигатор (Улучшение)
oc:item.UpgradeSign.name=Работа с табличками (Улучшение)
oc:item.UpgradeSolarGenerator.name=Солнечная панель (Улучшение)
oc:item.WirelessNetworkCard.name=Адаптер беспроводной сети
# GUI
oc:gui.Analyzer.Address=§6Адрес§f: %s
oc:gui.Analyzer.AddressCopied=Адрес скопирован в буфер обмена.
oc:gui.Analyzer.ChargerSpeed=§6Скорость зарядки§f: %s
oc:gui.Analyzer.ComponentName=§6Компонент§f: %s
oc:gui.Analyzer.Components=§6Кол-во подключенных компонентов§f: %s
oc:gui.Analyzer.LastError=§6Последняя ошибка§f: %s
oc:gui.Analyzer.RobotName=§6Имя робота§f: %s
oc:gui.Analyzer.RobotOwner=§6Владелец робота§f: %s
oc:gui.Analyzer.RobotXp=§6Опыт робрта§f: %s (%s уровень)
oc:gui.Analyzer.StoredEnergy=§6Накоплено энергии§f: %s
oc:gui.Analyzer.TotalEnergy=§6Всего накоплено энергии§f: %s
oc:gui.Analyzer.Users=§6Пользователи§f: %s
oc:gui.Chat.WarningLuaFallback=Родные библиотеки Lua не доступны, компьютеры не смогут сохранять своё состояние. Они перезагрузятся после выгрузки чанка.
oc:gui.Chat.WarningPower=Universal Electricity 3 недоступен. Компьютеры, дисплеи и другие компоненты §lне§f используют энергю. Заметьте, что UE3 используется для поддержки BuildCraft, IndustrialCraft2 и Thermal Expansion.
oc:gui.Chat.WarningProjectRed=Вы используете версию Project: Red, несовместимую с OpenComputers. Попробуйте обновить Project: Red.
oc:gui.Error.ComponentOverflow=Слишком много компонентов подключено к компьютеру.
oc:gui.Error.DaylightCycle=Пожалуйста, включите doDaylightCycle для работы компьютеров.
oc:gui.Error.InternalError=Внутренняя ошибка, пожалуйста посмотрите лог-файл. Возможно это баг.
oc:gui.Error.NoCPU=Не установлен центральный процессор.
oc:gui.Error.NoEnergy=Недостаточно энергии.
oc:gui.Error.NoRAM=Не установлена ОЗУ.
oc:gui.Error.OutOfMemory=Недостаточно памяти.
oc:gui.Robot.Power=Энергия
oc:gui.Robot.TurnOff=Выключить робота
oc:gui.Robot.TurnOn=Включить робота
oc:gui.ServerRack.None=Нет
oc:gui.ServerRack.Back=Сзади
oc:gui.ServerRack.Bottom=Снизу
oc:gui.ServerRack.Left=Слева
oc:gui.ServerRack.Right=Справа
oc:gui.ServerRack.Top=Сверху
oc:gui.ServerRack.WirelessRange=Радиус беспроводной сети
oc:gui.Terminal.InvalidKey=Неверный ключ, возможно к серверу уже подключен другой терминал.
oc:gui.Terminal.OutOfRange=Нет сигнала от сервера.
# Containers
oc:container.Case=Системный блок
oc:container.DiskDrive=Дисковод
oc:container.Rack=Серверная стойка
oc:container.Server=Сервер
# Item / Block Tooltips
oc:tooltip.AbstractBusCard=Позволяет использовать отправлять и принимать LIP-пакеты через абстрактную шину из мода §fStargateTech 2§7.
oc:tooltip.Acid=Высокотоксичная псевдо-жидкость, как правило, употребляемая некоторыми пиратами. Благодаря своей агрессивной природе она идеально подходит для травления печатных плат.
oc:tooltip.Adapter=Используется для контроля некомпонентных блоков, например блоков из других модов.
oc:tooltip.ALU=Выполняет арифметические вычисления, так что вам не придётся возиться с ними.
oc:tooltip.Analyzer=Используется для отображения информации о компонентах, например их §fадрес§7 или §fимя§7.[nl] Также отображает ошибку, вызвавшую сбой компонента.
oc:tooltip.Cable=Лёгкий и дешёвый способ соединить компоненты между собой.
oc:tooltip.Capacitor=Накапливает энергию для дальнейшего использования. Может быть очень быстро заполнен и опустошён.
oc:tooltip.CardBase=Можно понять по названию, что это основа для всех карт расширения.
oc:tooltip.Case=Системный блок - основа компьютера и может быть улучшен §fкартами расширения§7, §fОЗУ§7 и §fжёсткими дисками§7.[nl] Слоты: §f%s§7.
oc:tooltip.Charger=Передаёт энергию из аккумуляторов роботам. Скорость зарядки зависит от §fсилы сигнала красной пыли§7, где отсутствие сигнала означает не заряжать, а полный сигнал - заряжать на полной скорости.
oc:tooltip.CircuitBoard=Мы уже очень близки. Может быть вытравлена, чтобы получить печатную плату.
oc:tooltip.ControlUnit=Это штука, которая... контролирует... что-то. Она необходима, чтобы создать центральный процессор. Да, она очень важна.
oc:tooltip.CPU=Является важным компонентом в компьютере. Тактовая частота немного нестабильна, но что вы ожидали, когда он работает даже на карманных солнечных часах?
oc:tooltip.CuttingWire=Используется для нарезки глиняных блоков в пластины. Рвётся после использования, что делает её очень неэффективным инструментом.
oc:tooltip.Disk=Примитивный носитель, который может быть использован для создания постоянных запоминающих устройств.
oc:tooltip.DiskDrive.CC=§aПоддерживаются§7 дискеты из ComputerCraft.
oc:tooltip.DiskDrive=Позволяет читать и записывать дискеты.
oc:tooltip.GraphicsCard=Передаёт изображение на дисплей.[nl] Максимальное разрешение: §f%sx%s§7.[nl] Максимальная г лубина цвета:§f%s§7.[nl] Операций/тик: §f%s§7.
oc:tooltip.InternetCard=Эта карта позволяет создавать HTTP-запросы и использует реальные TCP сокеты.
oc:tooltip.IronNugget=Самородок, созданный из железа. Может именно поэтому он и назван железным самородком, нет?
oc:tooltip.Keyboard=Может быть прикреплена к дисплеям, позволяя вводить информацию.
oc:tooltip.Memory=Необходима для запуска компьютера. Чем больше ОЗУ, тем более требовательные программы вы можете запустить.
oc:tooltip.Microchip=Схема, ранее известная как интегральная. Понятия не имею, как она работает с красной пылью, но она работает.
oc:tooltip.NetworkCard=Позволяет соединить компьютеры, удалённые друг от друга, в сеть для отправки сообщений между ними.
oc:tooltip.PowerConverter.BC=§fBuildCraft MJ§7: §a%s:%s§7.
oc:tooltip.PowerConverter.IC2=§fIndustrialCraft² EU§7: §a%s:%s§7.
oc:tooltip.PowerConverter.TE=§fThermal Expansion RF§7: §a%s:%s§7.
oc:tooltip.PowerConverter.UE=§fUniversal Electricity Joules§7: §a%s:%s§7.
oc:tooltip.PowerConverter=Конвертирует энергию из других модов для питания компонентов.[nl] Соотношения энергии:
oc:tooltip.PowerDistributor=Передаёт энергию между различными сетями. Это полезно, чтобы запитать несколько сетей, которые должны оставаться раздельными друг от друга.
oc:tooltip.PrintedCircuitBoard=Основа для плат, ОЗУ и прочего.
oc:tooltip.RawCircuitBoard=Может быть закалена в печи для получения печатной платы.
oc:tooltip.Redstone=Позволяет принимать и излучать сигналы красной пыли вокруг компонента. Контролируется любым подключенным компьютером.
oc:tooltip.RedstoneCard.RedLogic=§aПоддерживаются§7 провода из §fRedLogic§7.
oc:tooltip.RedstoneCard.RedNet=§aПоддерживается§7 провода из §fRedNet§7.
oc:tooltip.RedstoneCard=Позволяет принимать и излучать сигналы красной пыли вокруг компьютера или робота.
oc:tooltip.Robot=В отличие от компьютеров, роботы могут передвигаться и взаимодействовать с миром как игрок. Но они не могут §oвзаимодействовать§r§7 с остальными компонентами.
# The underscore makes sure this isn't hidden with the rest of the tooltip.
oc:tooltip.Robot_Level=§fОпыт робота§7: §a%s§7.
oc:tooltip.Robot_StoredEnergy=§fНакопленная энергия§7: §a%s§7.
oc:tooltip.Router=Позволяет соединять различные сети между собой. Передаются только сообщения, компоненты между сетями недоступны. Используйте его для разделения сетей с возможностью пересылать сообщения между ними.
oc:tooltip.Screen=Отображает текст, передаваемый видеокартой.[nl] Максимальное разрешение экрана: §f%sx%s§7.[nl] Максимальная глубина цвета: §f%s§7.
oc:tooltip.Server=Это сервер, который может быть улучшен компонентами, как системный блок. Может быть включен, будучи вставленным в стойку.[nl] Количество поддерживаемых терминалов: §f%s§7.
oc:tooltip.Server.Components=Установленные компоненты:
oc:tooltip.ServerRack=Обеспечивает работу до четырёх серверов. Предоставляет виртуальную клавиатуру и дисплей для подключения беспроводного терминала.
oc:tooltip.Terminal=Позволяет дистанционно управлять сервером, пока вы в радиусе его действия. Действует как портативный дисплей с клавиатурой.[nl] Shift+ПКМ на сервер в стойке для привязки терминала.
oc:tooltip.TooLong=Удерживайте Shift для расширенного описания.
oc:tooltip.Transistor=Базовый элемент в других частях компьютера. Он немного деформирован, но отлично выполняет свою работу.
oc:tooltip.UpgradeCrafting=Позволяет роботам использовать верхнюю левую часть инвентаря для создания вещей. Вещи должны быть расположены в том порядке, что и в верстаке.
oc:tooltip.UpgradeGenerator=Позволяет роботам генерировать энергию из сжигаемого топлива прямо на ходу.[nl] §fЭффективность§7: §a%s%%§7
oc:tooltip.UpgradeNavigation=Позволяет определять положение и ориентацию робота. Положение определяется относительно центра карты.
oc:tooltip.UpgradeSign=Позволяет читать и писать текст на табличках.
oc:tooltip.UpgradeSolarGenerator=Позволяет роботам генерировать энергию из солнечного света прямо на ходу. Требует линию прямой видимости неба над роботом. Генерирует энергию на скорости %s%% от топливного генератора.
oc:tooltip.WirelessNetworkCard=Позволяет передавать сетевые сообщения по беспроводному каналу. Не забудьте выставить §fсилу сигнала красной пыли§7, или сообщения отправлены не будут!

View File

@ -259,7 +259,17 @@ sandbox._G = sandbox
-------------------------------------------------------------------------------
-- Start of non-standard stuff made available via package.preload.
local libcomponent = {
local libcomponent
libcomponent = {
doc = function(address, method)
checkArg(1, address, "string")
checkArg(2, method, "string")
local result, reason = component.doc(address, method)
if not result and reason then
error(reason, 2)
end
return result
end,
invoke = function(address, method, ...)
checkArg(1, address, "string")
checkArg(2, method, "string")
@ -288,9 +298,14 @@ local libcomponent = {
return nil, reason
end
for method, direct in pairs(methods) do
proxy[method] = function(...)
return invoke(direct, address, method, ...)
end
proxy[method] = setmetatable({}, {
__call = function(_, ...)
return invoke(direct, address, method, ...)
end,
__tostring = function()
return libcomponent.doc(address, method) or "function"
end
})
end
return proxy
end,

View File

@ -95,7 +95,7 @@ function text.serialize(value, pretty)
["until"]=true, ["while"]=true}
local id = "^[%a_][%w_]*$"
local ts = {}
local function s(v)
local function s(v, l)
local t = type(v)
if t == "nil" then
return "nil"
@ -113,6 +113,8 @@ function text.serialize(value, pretty)
end
elseif t == "string" then
return string.format("%q", v)
elseif t == "table" and pretty and getmetatable(v) and getmetatable(v).__tostring then
return tostring(v)
elseif t == "table" then
if ts[v] then
if pretty then
@ -122,24 +124,36 @@ function text.serialize(value, pretty)
end
end
ts[v] = true
local i, r = 1, nil
for k, v in pairs(v) do
local f, i, r = 1, nil
if pretty then
local ks = {}
for k in pairs(v) do table.insert(ks, k) end
table.sort(ks)
local k = 0
f = function()
k = k + 1
return ks[k], ks[k] and v[ks[k]] or nil
end
else
f = pairs(v)
end
for k, v in f do
if r then
r = r .. ","
r = r .. "," .. (pretty and ("\n" .. string.rep(" ", l)) or "")
else
r = "{"
end
local tk = type(k)
if tk == "number" and k == i then
i = i + 1
r = r .. s(v)
r = r .. s(v, l + 1)
else
if tk == "string" and not kw[k] and string.match(k, id) then
r = r .. k
else
r = r .. "[" .. s(k) .. "]"
r = r .. "[" .. s(k, l + 1) .. "]"
end
r = r .. "=" .. s(v)
r = r .. "=" .. s(v, l + 1)
end
end
ts[v] = nil -- allow writing same table more than once
@ -152,7 +166,7 @@ function text.serialize(value, pretty)
end
end
end
local result = s(value)
local result = s(value, 1)
local limit = type(pretty) == "number" and pretty or 1000
if pretty and unicode.len(result) > limit then
return result:sub(1, limit) .. "..."

View File

@ -86,7 +86,7 @@ opencomputers {
activeGC: true
# The sizes of the three tiers of RAM, in kilobytes. This list must
# contain exactly three entries, or it will be ignored.
# contain exactly five entries, or it will be ignored.
ramSizes: [
64
128

View File

@ -23,6 +23,10 @@ class Case(playerInventory: InventoryPlayer, computer: tileentity.Case) extends
addSlotToContainer(120, 16, api.driver.Slot.Processor, computer.tier)
if (computer.tier == 0) {
addSlotToContainer(120, 16 + 2 * slotSize, api.driver.Slot.Memory, computer.maxComponentTierForSlot(getInventory.size))
}
// Show the player's inventory.
addPlayerInventorySlots(8, 84)

View File

@ -62,7 +62,7 @@ class Case(var tier: Int, isRemote: Boolean) extends Computer(isRemote) {
override def getInventoryName = Settings.namespace + "container.Case"
override def getSizeInventory = tier match {
case 0 => 5
case 0 => 6
case 1 => 7
case 2 => 9
case _ => 0
@ -79,7 +79,7 @@ class Case(var tier: Int, isRemote: Boolean) extends Computer(isRemote) {
case 0 => (slot, Registry.itemDriverFor(stack)) match {
case (_, None) => false // Invalid item.
case (0 | 1, Some(driver)) => driver.slot(stack) == Slot.Card && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (2, Some(driver)) => driver.slot(stack) == Slot.Memory && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (2 | 5, Some(driver)) => driver.slot(stack) == Slot.Memory && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (3, Some(driver)) => driver.slot(stack) == Slot.HardDiskDrive && driver.tier(stack) <= maxComponentTierForSlot(slot)
case (4, Some(driver)) => driver.slot(stack) == Slot.Processor && driver.tier(stack) <= maxComponentTierForSlot(slot)
case _ => false // Invalid slot.
@ -105,7 +105,7 @@ class Case(var tier: Int, isRemote: Boolean) extends Computer(isRemote) {
}
def maxComponentTierForSlot(slot: Int) = tier match {
case 0 => 0
case 0 if slot >= 0 && slot < getSizeInventory => 0
case 1 => slot match {
case 0 => 1
case 1 => 0

View File

@ -46,15 +46,15 @@ class RobotProxy(val robot: Robot) extends Computer(robot.isClient) with ISidedI
// ----------------------------------------------------------------------- //
@Callback
@Callback(doc = """function():boolean -- Starts the robot. Returns true if the state changed.""")
def start(context: Context, args: Arguments): Array[AnyRef] =
result(!computer.isPaused && computer.start())
@Callback
@Callback(doc = """function():boolean -- Stops the robot. Returns true if the state changed.""")
def stop(context: Context, args: Arguments): Array[AnyRef] =
result(computer.stop())
@Callback(direct = true)
@Callback(direct = true, doc = """function():boolean -- Returns whether the robot is running.""")
def isRunning(context: Context, args: Arguments): Array[AnyRef] =
result(computer.isRunning)

View File

@ -25,10 +25,10 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
// ----------------------------------------------------------------------- //
override protected val _buffer = new component.Buffer(this) {
@Callback
@Callback(doc = """function():boolean -- Returns whether the screen is currently on.""")
def isOn(computer: Context, args: Arguments): Array[AnyRef] = result(origin.isOn)
@Callback
@Callback(doc = """function():boolean -- Turns off the screen. Returns true if it was on.""")
def turnOn(computer: Context, args: Arguments): Array[AnyRef] = {
if (!origin.isOn) {
origin.turnOn()
@ -37,7 +37,7 @@ class Screen(var tier: Int) extends Buffer with SidedEnvironment with Rotatable
else result(false, origin.isOn)
}
@Callback
@Callback(doc = """function():boolean -- Turns the screen on. Returns true if it was off.""")
def turnOff(computer: Context, args: Arguments): Array[AnyRef] = {
if (origin.isOn) {
origin.turnOff()

View File

@ -54,25 +54,25 @@ class AbstractBus(val device: IBusDevice) extends ManagedComponent with IBusDriv
// ----------------------------------------------------------------------- //
@Callback
@Callback(doc = """function():boolean -- Whether the local bus interface is enabled.""")
def getEnabled(context: Context, args: Arguments): Array[AnyRef] = result(isEnabled)
@Callback
@Callback(doc = """function(enabled:boolean):boolean -- Sets whether the local bus interface should be enabled.""")
def setEnabled(context: Context, args: Arguments): Array[AnyRef] = {
isEnabled = args.checkBoolean(0)
result(isEnabled)
}
@Callback
@Callback(doc = """function():number -- Get the local interface address.""")
def getAddress(context: Context, args: Arguments): Array[AnyRef] = result(address)
@Callback
@Callback(doc = """function(address:number):number -- Sets the local interface address.""")
def setAddress(context: Context, args: Arguments): Array[AnyRef] = {
address = args.checkInteger(0) & 0xFFFF
result(address)
}
@Callback
@Callback(doc = """function(address:number, data:table):boolean -- Sends data across the abstract bus.""")
def send(context: Context, args: Arguments): Array[AnyRef] = {
val target = args.checkInteger(0) & 0xFFFF
val data = args.checkTable(1)
@ -84,7 +84,7 @@ class AbstractBus(val device: IBusDevice) extends ManagedComponent with IBusDriv
else result(false, "not enough energy")
}
@Callback(direct = true)
@Callback(direct = true, doc = """function():number -- The maximum packet size that can be sent over the bus.""")
def maxPacketSize(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.maxNetworkPacketSize)
// ----------------------------------------------------------------------- //

View File

@ -5,21 +5,21 @@ import li.cil.oc.common.tileentity.BundledRedstoneAware
class BundledRedstone(override val owner: BundledRedstoneAware) extends Redstone(owner) {
@Callback(direct = true)
@Callback(direct = true, doc = """function(side:number, color:number):number -- Get the bundled redstone input on the specified side and with the specified color.""")
def getBundledInput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
val color = checkColor(args, 1)
result(owner.bundledInput(side, color))
}
@Callback(direct = true)
@Callback(direct = true, doc = """function(side:number, color:number):number -- Get the bundled redstone output on the specified side and with the specified color.""")
def getBundledOutput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
val color = checkColor(args, 1)
result(owner.bundledOutput(side, color))
}
@Callback
@Callback(doc = """function(side:number, color:number, value:number):number -- Set the bundled redstone output on the specified side and with the specified color.""")
def setBundledOutput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
val color = checkColor(args, 1)

View File

@ -44,10 +44,10 @@ class InternetCard extends ManagedComponent {
// ----------------------------------------------------------------------- //
@Callback(direct = true)
@Callback(direct = true, doc = """function():boolean -- Returns whether HTTP requests can be made (config setting).""")
def isHttpEnabled(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.httpEnabled)
@Callback
@Callback(doc = """function():boolean -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals.""")
def request(context: Context, args: Arguments): Array[AnyRef] = {
if (owner.isEmpty || context.node.address != owner.get.node.address) {
throw new IllegalArgumentException("can only be used by the owning computer")
@ -130,10 +130,10 @@ class InternetCard extends ManagedComponent {
})
}
@Callback(direct = true)
@Callback(direct = true, doc = """function():boolean -- Returns whether TCP connections can be made (config setting).""")
def isTcpEnabled(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.httpEnabled)
@Callback
@Callback(doc = """function(address:string[, port:number]):number -- Opens a new TCP connection. Returns the handle of the connection.""")
def connect(context: Context, args: Arguments): Array[AnyRef] = {
val address = args.checkString(0)
val port = if (args.count > 1) args.checkInteger(1) else -1
@ -151,7 +151,7 @@ class InternetCard extends ManagedComponent {
result(handle)
}
@Callback
@Callback(doc = """function(handle:number) -- Closes an open socket stream.""")
def close(context: Context, args: Arguments): Array[AnyRef] = {
val handle = args.checkInteger(0)
connections.remove(handle) match {
@ -161,7 +161,7 @@ class InternetCard extends ManagedComponent {
null
}
@Callback
@Callback(doc = """function(handle:number, data:string):number -- Tries to write data to the socket stream. Returns the number of bytes written.""")
def write(context: Context, args: Arguments): Array[AnyRef] = {
val handle = args.checkInteger(0)
val value = args.checkByteArray(1)
@ -173,7 +173,7 @@ class InternetCard extends ManagedComponent {
}
}
@Callback
@Callback(doc = """function(handle:number, n:number):string -- Tries to read data from the socket stream. Returns the read byte array.""")
def read(context: Context, args: Arguments): Array[AnyRef] = {
val handle = args.checkInteger(0)
val n = math.min(Settings.get.maxReadBuffer, math.max(0, args.checkInteger(1)))

View File

@ -16,17 +16,18 @@ class NetworkCard extends ManagedComponent {
// ----------------------------------------------------------------------- //
@Callback
@Callback(doc = """function(port:number):boolean -- Opens the specified port. Returns true if the port was opened.""")
def open(context: Context, args: Arguments): Array[AnyRef] = {
val port = checkPort(args.checkInteger(0))
result(openPorts.add(port))
}
@Callback
@Callback(doc = """function([port:number]):boolean -- Closes the specified port (default: all ports). Returns true if ports were closed.""")
def close(context: Context, args: Arguments): Array[AnyRef] = {
if (args.count == 0) {
val closed = openPorts.size > 0
openPorts.clear()
result(true)
result(closed)
}
else {
val port = checkPort(args.checkInteger(0))
@ -34,16 +35,16 @@ class NetworkCard extends ManagedComponent {
}
}
@Callback(direct = true)
@Callback(direct = true, doc = """function(port:number):boolean -- Whether the specified port is open.""")
def isOpen(context: Context, args: Arguments): Array[AnyRef] = {
val port = checkPort(args.checkInteger(0))
result(openPorts.contains(port))
}
@Callback(direct = true)
@Callback(direct = true, doc = """function():boolean -- Whether this is a wireless network card.""")
def isWireless(context: Context, args: Arguments): Array[AnyRef] = result(false)
@Callback
@Callback(doc = """function(address:string, port:number, data...) -- Sends the specified data to the specified target.""")
def send(context: Context, args: Arguments): Array[AnyRef] = {
val address = args.checkString(0)
val port = checkPort(args.checkInteger(1))
@ -52,7 +53,7 @@ class NetworkCard extends ManagedComponent {
result(true)
}
@Callback
@Callback(doc = """function(port:number, data...) -- Broadcasts the specified data on the specified port.""")
def broadcast(context: Context, args: Arguments): Array[AnyRef] = {
val port = checkPort(args.checkInteger(0))
checkPacketSize(args.drop(1))
@ -60,7 +61,7 @@ class NetworkCard extends ManagedComponent {
result(true)
}
@Callback(direct = true)
@Callback(direct = true, doc = """function():number -- Gets the maximum packet size (config setting).""")
def maxPacketSize(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.maxNetworkPacketSize)
// ----------------------------------------------------------------------- //

View File

@ -12,19 +12,19 @@ class Redstone(val owner: RedstoneAware) extends ManagedComponent {
// ----------------------------------------------------------------------- //
@Callback(direct = true)
@Callback(direct = true, doc = """function(side:number):number -- Get the redstone input on the specified side.""")
def getInput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
result(owner.input(side))
}
@Callback(direct = true)
@Callback(direct = true, doc = """function(side:number):number -- Get the redstone output on the specified side.""")
def getOutput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
result(owner.output(side))
}
@Callback()
@Callback(doc = """function(side:number, value:number):number -- Set the redstone output on the specified side.""")
def setOutput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
val value = args.checkInteger(1)

View File

@ -17,7 +17,7 @@ class UpgradeCrafting(val owner: MCTileEntity) extends ManagedComponent {
withComponent("crafting").
create()
@Callback
@Callback(doc = """function([count:number]):number -- Tries to craft the specified number of items in the top left area of the inventory.""")
def craft(context: RobotContext, args: Arguments): Array[AnyRef] = {
val count = if (args.count > 0) args.checkInteger(0) else Int.MaxValue
result(CraftingInventory.craft(context, count))

View File

@ -21,7 +21,7 @@ class UpgradeGenerator(val owner: TileEntity) extends ManagedComponent {
// ----------------------------------------------------------------------- //
@Callback
@Callback(doc = """function([count:number]):boolean -- Tries to insert fuel from the selected slot into the generator's queue.""")
def insert(context: RobotContext, args: Arguments): Array[AnyRef] = {
val count = if (args.count > 0) args.checkInteger(0) else 64
val player = context.player
@ -48,7 +48,7 @@ class UpgradeGenerator(val owner: TileEntity) extends ManagedComponent {
result(true)
}
@Callback
@Callback(doc = """function():number -- Get the size of the item stack in the generator's queue.""")
def count(context: Context, args: Arguments): Array[AnyRef] = {
inventory match {
case Some(stack) => result(stack.stackSize)
@ -56,7 +56,7 @@ class UpgradeGenerator(val owner: TileEntity) extends ManagedComponent {
}
}
@Callback
@Callback(doc = """function([count:number]):boolean -- Tries to remove items from the generator's queue.""")
def remove(context: RobotContext, args: Arguments): Array[AnyRef] = {
val count = if (args.count > 0) args.checkInteger(0) else Int.MaxValue
inventory match {

View File

@ -11,7 +11,7 @@ class UpgradeNavigation(val owner: TileEntity, val xCenter: Int, val zCenter: In
// ----------------------------------------------------------------------- //
@Callback
@Callback(doc = """function():number, number, number -- Get the current relative position of the robot.""")
def getPosition(context: Context, args: Arguments): Array[AnyRef] = {
val x = owner.xCoord
val y = owner.yCoord
@ -25,7 +25,7 @@ class UpgradeNavigation(val owner: TileEntity, val xCenter: Int, val zCenter: In
result(Unit, "out of range")
}
@Callback
@Callback(doc = """function():number -- Get the current orientation of the robot.""")
def getFacing(context: Context, args: Arguments): Array[AnyRef] = {
owner match {
case rotatable: Rotatable => result(rotatable.facing.ordinal)
@ -33,7 +33,7 @@ class UpgradeNavigation(val owner: TileEntity, val xCenter: Int, val zCenter: In
}
}
@Callback
@Callback(doc = """function():number -- Get the operational range of the navigation upgrade.""")
def getRange(context: Context, args: Arguments): Array[AnyRef] = {
result(size / 2)
}

View File

@ -12,7 +12,7 @@ class UpgradeSign(val owner: TileEntity) extends ManagedComponent {
// ----------------------------------------------------------------------- //
@Callback
@Callback(doc = """function():string -- Get the text on the sign in front of the robot.""")
def getValue(context: Context, args: Arguments): Array[AnyRef] = {
val facing = owner match {
case rotatable: Rotatable => rotatable.facing
@ -24,7 +24,7 @@ class UpgradeSign(val owner: TileEntity) extends ManagedComponent {
}
}
@Callback
@Callback(doc = """function(value:string):string -- Set the text on the sign in front of the robot.""")
def setValue(context: Context, args: Arguments): Array[AnyRef] = {
val text = args.checkString(0).lines.padTo(4, "").map(line => if (line.length > 15) line.substring(0, 15) else line)
val facing = owner match {

View File

@ -20,10 +20,10 @@ class WirelessNetworkCard(val owner: TileEntity) extends NetworkCard {
// ----------------------------------------------------------------------- //
@Callback(direct = true)
@Callback(direct = true, doc = """function():number -- Get the signal strength (range) used when sending messages.""")
def getStrength(context: Context, args: Arguments): Array[AnyRef] = result(strength)
@Callback
@Callback(doc = """function(strength:number):number -- Set the signal strength (range) used when sending messages.""")
def setStrength(context: Context, args: Arguments): Array[AnyRef] = {
strength = math.max(args.checkDouble(0), math.min(0, Settings.get.maxWirelessRange))
result(strength)

View File

@ -220,9 +220,14 @@ class Machine(val owner: Machine.Owner) extends ManagedComponent with Context wi
counts(method) += 1
}
component.invoke(method, this, args: _*)
case _ => throw new Exception("no such component")
case _ => throw new IllegalArgumentException("no such component")
}
private[component] def doc(address: String, method: String) = Option(node.network.node(address)) match {
case Some(component: server.network.Component) if component.canBeSeenFrom(node) || component == node => component.doc(method)
case _ => throw new IllegalArgumentException("no such component")
}
private[component] def addUser(name: String) {
if (_users.size >= Settings.get.maxUsers)
throw new Exception("too many users")
@ -250,15 +255,15 @@ class Machine(val owner: Machine.Owner) extends ManagedComponent with Context wi
// ----------------------------------------------------------------------- //
@Callback
@Callback(doc = """function():boolean -- Starts the computer. Returns true if the state changed.""")
def start(context: Context, args: Arguments): Array[AnyRef] =
result(!isPaused && start())
@Callback
@Callback(doc = """function():boolean -- Stops the computer. Returns true if the state changed.""")
def stop(context: Context, args: Arguments): Array[AnyRef] =
result(stop())
@Callback(direct = true)
@Callback(direct = true, doc = """function():boolean -- Returns whether the computer is running.""")
def isRunning(context: Context, args: Arguments): Array[AnyRef] =
result(isRunning)

View File

@ -1,5 +1,6 @@
package li.cil.oc.server.component.machine
import com.google.common.base.Strings
import com.naef.jnlua._
import java.io.{IOException, FileNotFoundException}
import java.util.logging.Level
@ -528,6 +529,29 @@ class NativeLuaArchitecture(val machine: Machine) extends Architecture {
})
lua.setField(-2, "invoke")
lua.pushScalaFunction(lua => {
val address = lua.checkString(1)
val method = lua.checkString(2)
try {
val doc = machine.doc(address, method)
if (Strings.isNullOrEmpty(doc))
lua.pushNil()
else
lua.pushString(doc)
1
} catch {
case e: NoSuchMethodException =>
lua.pushNil()
lua.pushString("no such method")
2
case t: Throwable =>
lua.pushNil()
lua.pushString(if (t.getMessage != null) t.getMessage else t.toString)
2
}
})
lua.setField(-2, "doc")
lua.setGlobal("component")
initPerms()

View File

@ -55,7 +55,10 @@ trait Buffered extends OutputStreamFileSystem {
}
setLastModified(path, directory.lastModified())
}
recurse("", fileRoot)
if (fileRoot.list() == null || fileRoot.list().length == 0) {
fileRoot.delete()
}
else recurse("", fileRoot)
super.load(nbt)
}
@ -94,6 +97,9 @@ trait Buffered extends OutputStreamFileSystem {
}
directory.setLastModified(lastModified(path))
}
recurse("")
if (list("") == null || list("").length == 0) {
fileRoot.delete()
}
else recurse("")
}
}

View File

@ -99,6 +99,11 @@ trait Component extends network.Component with Node {
def methods = callbacks.keySet
def doc(name: String) = callbacks.get(name) match {
case Some(callback) => callback.doc
case _ => throw new NoSuchMethodException()
}
def invoke(method: String, context: Context, arguments: AnyRef*) =
callbacks.get(method) match {
case Some(callback) => hosts(method) match {
@ -173,7 +178,7 @@ object Component {
val a = m.getAnnotation[network.Callback](classOf[network.Callback])
val name = if (a.value != null && a.value.trim != "") a.value else m.getName
if (!callbacks.contains(name)) {
callbacks += name -> new ComponentCallback(m, a.direct, a.limit)
callbacks += name -> new ComponentCallback(m, a.direct, a.limit, a.doc)
}
}
)
@ -201,11 +206,11 @@ object Component {
// ----------------------------------------------------------------------- //
abstract class Callback(val direct: Boolean, val limit: Int) {
abstract class Callback(val direct: Boolean, val limit: Int, val doc: String = "") {
def apply(instance: Environment, context: Context, args: Arguments): Array[AnyRef]
}
class ComponentCallback(val method: Method, direct: Boolean, limit: Int) extends Callback(direct, limit) {
class ComponentCallback(val method: Method, direct: Boolean, limit: Int, doc: String) extends Callback(direct, limit, doc) {
override def apply(instance: Environment, context: Context, args: Arguments) = try {
method.invoke(instance, context, args).asInstanceOf[Array[AnyRef]]
} catch {