mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-27 15:06:41 -04:00
Merge branch 'master-MC1.8' of github.com:MightyPirates/OpenComputers into OC1.5-MC1.8
Conflicts: build.properties
This commit is contained in:
commit
fa720be2a4
Binary file not shown.
@ -45,12 +45,13 @@ def getGitRef() {
|
||||
|
||||
if (System.getenv("BUILD_NUMBER") != null)
|
||||
version += ".${System.getenv("BUILD_NUMBER")}"
|
||||
else
|
||||
version += "-" + getGitRef()
|
||||
|
||||
if (config.oc.subversion != null && config.oc.subversion != "")
|
||||
version += "-${config.oc.subversion}"
|
||||
|
||||
if (System.getenv("BUILD_NUMBER") == null)
|
||||
version += "+" + getGitRef()
|
||||
|
||||
ext.simpleVersion = version
|
||||
version = "MC${config.minecraft.version}-${project.version}"
|
||||
|
||||
@ -238,6 +239,7 @@ idea.module.scopes.PROVIDED.plus += [configurations.provided]
|
||||
sourceSets {
|
||||
main {
|
||||
scala {
|
||||
exclude 'li/cil/oc/integration/agricraft/**'
|
||||
exclude 'li/cil/oc/integration/appeng/**'
|
||||
exclude 'li/cil/oc/integration/bloodmagic/**'
|
||||
exclude 'li/cil/oc/integration/bluepower/**'
|
||||
|
@ -1,7 +1,7 @@
|
||||
minecraft.version=1.8
|
||||
forge.version=11.14.3.1450
|
||||
|
||||
oc.version=1.5.15
|
||||
oc.version=1.5.16
|
||||
oc.subversion=
|
||||
|
||||
ae2.version=rv2-beta-26
|
||||
|
@ -12,7 +12,7 @@ import li.cil.oc.api.detail.*;
|
||||
*/
|
||||
public class API {
|
||||
public static final String ID_OWNER = "OpenComputers|Core";
|
||||
public static final String VERSION = "5.5.3";
|
||||
public static final String VERSION = "5.5.4";
|
||||
|
||||
public static DriverAPI driver = null;
|
||||
public static FileSystemAPI fileSystem = null;
|
||||
|
@ -0,0 +1,27 @@
|
||||
package li.cil.oc.api.driver.item;
|
||||
|
||||
import li.cil.oc.api.machine.Architecture;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* May be implemented in processor drivers of processors that can be reconfigured.
|
||||
* <p/>
|
||||
* This is the case for OC's built-in CPUs, for example, which can be reconfigured
|
||||
* to any registered architecture. It a CPU has such a driver, it may also be
|
||||
* reconfigured by the machine it is running in (e.g. in the Lua case via
|
||||
* <tt>computer.setArchitecture</tt>).
|
||||
*/
|
||||
public interface MutableProcessor extends Processor {
|
||||
/**
|
||||
* Get a list of all architectures supported by this processor.
|
||||
*/
|
||||
java.util.Collection<Class<? extends Architecture>> allArchitectures();
|
||||
|
||||
/**
|
||||
* Set the architecture to use for the specified processor.
|
||||
*
|
||||
* @param stack the processor to set the architecture for.
|
||||
* @param architecture the architecture to use on the processor.
|
||||
*/
|
||||
void setArchitecture(ItemStack stack, Class<? extends Architecture> architecture);
|
||||
}
|
@ -126,10 +126,10 @@ opencomputers {
|
||||
# happen.
|
||||
startupDelay: 0.25
|
||||
|
||||
# The maximum size of the byte array that can be stored on EEPROMs.
|
||||
# The maximum size of the byte array that can be stored on EEPROMs as executable data..
|
||||
eepromSize: 4096
|
||||
|
||||
# The maximum size of the byte array that can be stored on EEPROMs.
|
||||
# The maximum size of the byte array that can be stored on EEPROMs as configuration data.
|
||||
eepromDataSize: 256
|
||||
|
||||
# The number of components the different CPU tiers support. This list
|
||||
@ -767,6 +767,10 @@ opencomputers {
|
||||
# Per-byte cost for ECDSA operation is controlled by `complex` value,
|
||||
# because data is hashed with SHA256 before signing/verifying
|
||||
dataCardAsymmetric: 10.0
|
||||
|
||||
# Energy required for one transposer operation (regardless of the number
|
||||
# of items / fluid volume moved).
|
||||
transposer: 1
|
||||
}
|
||||
|
||||
# The rate at which different blocks accept external power. All of these
|
||||
@ -1191,6 +1195,11 @@ opencomputers {
|
||||
# properties, i.e. througput, frequency and buffer size.
|
||||
# Valid values are: 0 = none, 1 = tier 1, 2 = tier 2, 3 = tier 3.
|
||||
serverRackSwitchTier: 1
|
||||
|
||||
# Enforced delay when changing a redstone emitting component's output,
|
||||
# such as the redstone card and redstone I/O block. Lowering this can
|
||||
# have very negative impact on server TPS, so beware.
|
||||
redstoneDelay: 0.1
|
||||
}
|
||||
|
||||
# Settings for mod integration (the mod previously known as OpenComponents).
|
||||
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"normal": { "model": "opencomputers:relay" }
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"variants": {
|
||||
"normal": { "model": "opencomputers:transposer" }
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||

|
||||
|
||||
*This block is deprecated and will be removed in a future version.* Craft it into a [relay](relay.md) to avoid losing it.
|
||||
|
||||
The access point is the wireless version of the [switch](switch.md). It can be used to separate subnetworks so that machines in them will not see [components](../general/computer.md) in other networks, while still allowing to send network messages to the machines in other networks.
|
||||
|
||||
In addition to that, this block can act as a repeater: it can re-send wired messages as wired messages to other devices; or wireless messages as wired or wireless messages.
|
||||
|
@ -36,10 +36,9 @@ Keep in mind that some of these may not be available, depending on the recipe se
|
||||
* [Disassembler](disassembler.md)
|
||||
|
||||
## Networking
|
||||
* [Access Point](accessPoint.md)
|
||||
* [Cable](cable.md)
|
||||
* [Net Splitter](netSplitter.md)
|
||||
* [Switch](switch.md)
|
||||
* [Relay](relay.md)
|
||||
|
||||
## Power management
|
||||
* [Capacitor](capacitor.md)
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||

|
||||
|
||||
The net splitter is a device that allows controlling connectivity between subnetworks. Unlike the [switch](switch.md) or [power converter](powerConverter.md) it directly connects adjacent subnetworks, i.e. components can be accessed. Each side's connectivity can be toggled using a wrench (e.g. the [scrench](../item/wrench.md)). When a redstone signal is applied to the net splitter, all sides' connectivity is inverted.
|
||||
The net splitter is a device that allows controlling connectivity between subnetworks. Unlike the [relay](relay.md) or [power converter](powerConverter.md) it directly connects adjacent subnetworks, i.e. components can be accessed. Each side's connectivity can be toggled using a wrench (e.g. the [scrench](../item/wrench.md)). When a redstone signal is applied to the net splitter, all sides' connectivity is inverted.
|
||||
|
||||
This block can therefore be used to toggle connectivity to certain parts of a component network. Use a [redstone I/O block](redstone.md) or [redstone cards](../item/redstoneCard1.md) to automate the net splitter.
|
||||
|
@ -0,0 +1,13 @@
|
||||
# Relay
|
||||
|
||||

|
||||
|
||||
The relay can be used to allow different subnetworks to send network messages to each other, without exposing components to [computers](../general/computer.md) in other networks. Keeping components local is usually a good idea, to avoid [computers](../general/computer.md) using the wrong [screen](screen1.md) or to avoid component overflows to happen (causing [computers](../general/computer.md) to crash and refuse to boot up).
|
||||
|
||||
The relay can be upgraded by inserting a [wireless network card](../item/wlanCard.md) to also relay messages wirelessly. Wireless messages can be received and relayed by other relays with a wireless network card, or by [computers](../general/computer.md) with a wireless network card.
|
||||
|
||||
Alternatively the relay can be upgraded using [linked cards](../item/linkedCard.md). In this case it will forward messages through the tunnel provided by the linked card, too; at the usual cost, so make sure the relay is sufficiently powered.
|
||||
|
||||
Relays do *not* keep track of which packets they forwarded recently, so avoid cycles in your network or you may receive the same packet multiple times. Due to the limited buffer size of relays, sending messages too frequently will result in packet loss. You can upgrade your relays to increase the speed with which they relay messages, as well as their internal message queue size.
|
||||
|
||||
Packets are only re-sent a certain number of times, so chaining an arbitrary number of relays is not possible. By default, a packet will be re-sent up to five times.
|
@ -6,4 +6,4 @@ A server rack houses up to four [servers](../item/server1.md). A [server](../ite
|
||||
|
||||
Each [server](../item/server1.md) in a server rack can only communicate with one "face" of the server rack at a time - or none at all. Which side each [server](../item/server1.md) is connected to can be configured in the server rack's GUI. Beware that the sides are from the point of view of the server rack, i.e. if you are looking at the front of the server rack, `sides.right` will be to your left and vice versa.
|
||||
|
||||
Server racks act as [switch](switch.md) and [power distributor](powerDistributor.md) in one. The switch mode of the server rack can be configured in its GUI, with the two options being internal and external. In external mode the server rack will behave like a normal [switch](switch.md). In internal mode, messages are only passed to the [servers](../item/server1.md) in the rack, and will not be automatically relayed to the other faces of the rack. [Servers](../item/server1.md) will still be able to send messages to each other. This allows using server racks as advanced [switches](switch.md) that can perform filter and mapping operations, for example.
|
||||
Server racks act as [relay](relay.md) and [power distributor](powerDistributor.md) in one. The switch mode of the server rack can be configured in its GUI, with the two options being internal and external. In external mode the server rack will behave like a normal [relay](relay.md). In internal mode, messages are only passed to the [servers](../item/server1.md) in the rack, and will not be automatically relayed to the other faces of the rack. [Servers](../item/server1.md) will still be able to send messages to each other. This allows using server racks as advanced [relays](relay.md) that can perform filter and mapping operations, for example.
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||

|
||||
|
||||
*This block is deprecated and will be removed in a future version.* Craft it into a [relay](relay.md) to avoid losing it.
|
||||
|
||||
The switch can be used to allow different subnetworks to send network messages to each other, without exposing components to [computers](../general/computer.md) in other networks. Keeping components local is usually a good idea, to avoid [computers](../general/computer.md) using the wrong [screen](screen1.md) or to avoid component overflows to happen (causing [computers](../general/computer.md) to crash and refuse to boot up).
|
||||
|
||||
There is also a wireless variation of this block, called the [access point](accessPoint.md), which will also relay messages wirelessly. Wireless messages can be received and relayed by other [access points](accessPoint.md), or by [computers](../general/computer.md) with a [wireless network card](../item/wlanCard.md).
|
||||
|
@ -0,0 +1,9 @@
|
||||
# Transposer
|
||||
|
||||

|
||||
|
||||
The transposer bridges the gap between redstone controlled hoppers and [robots](robot.md), allowing [computer](../general/computer.md)-controlled transferral of items and fluids between adjacent blocks.
|
||||
|
||||
*Note that this block has no internal inventory.*
|
||||
|
||||
Besides moving things around, it can also be used to inspect the contents of the adjacent inventories, like an [adapter](adapter.md) with an [inventory controller upgrade](../item/inventoryControllerUpgrade.md) could, and the contents of adjacent tanks, like and adapter with a [tank controller upgrade](../item/tankControllerUpgrade.md) could.
|
@ -2,4 +2,4 @@
|
||||
|
||||

|
||||
|
||||
The network card allows [computers](../general/computer.md) to send and receive network messages. Messages (or packets) can be broadcasted to all receiving nodes in a subnetwork, or sent to a specific node with a specified address. [Switches](../block/switch.md) and [access points](../block/accessPoint.md) can be used to bridge multiple subnetworks by relaying messages between the subnetworks they are connected to. It is also possible to send a targeted message if the receiver is in another subnetwork, if the networks are connected via one or more [switches](../block/switch.md).
|
||||
The network card allows [computers](../general/computer.md) to send and receive network messages. Messages (or packets) can be broadcasted to all receiving nodes in a subnetwork, or sent to a specific node with a specified address. [Relays](../block/relay.md) can be used to bridge multiple subnetworks by relaying messages between the subnetworks they are connected to. It is also possible to send a targeted message if the receiver is in another subnetwork, if the networks are connected via one or more [relays](../block/relay.md).
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||

|
||||
|
||||
*Этот блок устарел и будет удален в следующих версиях.* Замените его на [ретранслятор](relay.md).
|
||||
|
||||
Точки доступа, это беспроводные версии [коммутаторов](switch.md). Они могут быть использованы, когда требуется разделить подсети, чтобы устройства не видели [компоненты](../general/computer.md) в других сетях, однако сохраняя при этом возможность передачи сообщений между подсетями.
|
||||
|
||||
В дополнение к этому, точки доступа могут использоваться как повторители: они могут перенаправлять сообщения из проводной линии другим устройствам; или беспроводные сообщения как проводные, так и беспроводные.
|
||||
|
@ -39,6 +39,7 @@
|
||||
* [Точка доступа](accessPoint.md)
|
||||
* [Кабель](cable.md)
|
||||
* [Сетевой переключатель](netSplitter.md)
|
||||
* [Ретранслятор](relay.md)
|
||||
* [Коммутатор](switch.md)
|
||||
|
||||
## Управление питанием
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||

|
||||
|
||||
Сетевой переключатель позволяет контролировать соединение между подсетями. В отличие от [коммутатора](switch.md) или [конвертера энергии](powerConverter.md) позволяет непосредственно соединить подсети, делая при этом доступными все компоненты. Соединение каждой стороны переключается [ключем](../item/wrench.md). При подаче редстоун-сигнала все соединения инвертируются.
|
||||
Сетевой переключатель позволяет контролировать соединение между подсетями. В отличие от [ретранслятора](relay.md) или [конвертера энергии](powerConverter.md) позволяет непосредственно соединить подсети, делая при этом доступными все компоненты. Соединение каждой стороны переключается [ключем](../item/wrench.md). При подаче редстоун-сигнала все соединения инвертируются.
|
||||
|
||||
Таким образом, этот блок может быть использован для переключения соединения определенных компонентов сети. Используйте [редстоун-I/O](redstone.md) или [редстоун карты](../item/redstoneCard1.md) для автоматизации сетевого переключателя.
|
@ -0,0 +1,13 @@
|
||||
# Ретранслятор
|
||||
|
||||

|
||||
|
||||
Ретранслятор используется для передачи сообщений между несколькими подсетями, изолируя компоненты [компьютеров](../general/computer.md) в других сетях. Сохранение компонентов, как правило, хорошая идея, что не позволяет [компьютерам](../general/computer.md) использовать неверный [монитор](screen1.md) или не позволяет перенагружать их (в результате чего [компьютеры](../general/computer.md) выключатся и отказываются загружаться).
|
||||
|
||||
Может быть улучшен добавлением [беспроводной сетевой карты](../item/wlanCard.md), что позволит ретранслировать беспроводные сообщения. Сообщения, переданные по беспроводной линии могут быть получены или перенаправлены другими ретрансляторами или [компьютерами](../general/computer.md) с [беспроводной сетевой картой](../item/wlanCard.md).
|
||||
|
||||
Также ретранслятор может быть улучшен с помощью [соединенной карты](../item/linkedCard.md). Это позволит передавать сообщения внутри туннеля, предоставленного картой, также; с обычными затратами энергии, поэтому убедитесь, что на ретранслятор поступает нужное количество энергии.
|
||||
|
||||
Ретрансляторы *не* отслеживают, какие пакеты и куда они передали, поэтому для в сети могут образовываться петли или вы можете получать одно сообщение несколько раз. Из-за ограниченного буфера сообщений коммутатора, частое отправление сообщений приводит к их потере. Вы можете улучшить ретранслятор для увеличения скорости обработки сообщений, а также увеличения размера сообщений.
|
||||
|
||||
Сообщения, могут перенаправлены всего несколько раз, поэтому цепочки с произвольным количеством ретрансляторов невозможны. По умолчанию, сообщение может быть перенаправлено пять раз.
|
@ -6,4 +6,4 @@
|
||||
|
||||
Каждый [сервер](../item/server1.md) в серверной стойке может взаимодействовать только с одной "стороной" стойки или ни с какой. К какой стороне, какой [сервер](../item/server1.md) подключен, настраивается в интерфейсе стойки. Будьте внимательны, стороны считаются относительно самой стойки, например, если вы смотрите на стойку спереди, то `правая сторона` стойки для вас будет слева.
|
||||
|
||||
Серверные стойки взаимодействуют с [коммутаторами](switch.md) и [распределителями энергии](powerDistributor.md). Переключатель режимов работы стойки, может быть настроен в интерфейсе самой стойки, он имеет 2 режима: внешний и внутренний. Во внешнем режиме сервер будет работать как обычный [коммутатор](switch.md). Во внутреннем режиме, сообщения будут передаваться только к [серверам](../item/server1.md) в стойке и не будут автоматически связаны со сторонами стойки. [Серверы](../item/server1.md) все также будут иметь возможность передачи сообщений друг другу. Это позволяет использовать серверные стойки как продвинутые [коммутаторы](switch.md) для операций фильтрации и направления данных, например.
|
||||
Серверные стойки взаимодействуют с [ретрансляторами](relay.md) и [распределителями энергии](powerDistributor.md). Переключатель режимов работы стойки, может быть настроен в интерфейсе самой стойки, он имеет 2 режима: внешний и внутренний. Во внешнем режиме сервер будет работать как обычный [ретранслятор](relay.md). Во внутреннем режиме, сообщения будут передаваться только к [серверам](../item/server1.md) в стойке и не будут автоматически связаны со сторонами стойки. [Серверы](../item/server1.md) все также будут иметь возможность передачи сообщений друг другу. Это позволяет использовать серверные стойки как продвинутые [ретрансляторы](relay.md) для операций фильтрации и направления данных, например.
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||

|
||||
|
||||
*Этот блок устарел и будет удален в следующих версиях.* Замените его на [ретранслятор](relay.md).
|
||||
|
||||
Коммутатор используется для передачи сообщений между несколькими подсетями, не используя компоненты [компьютеров](../general/computer.md) в других сетях. Сохранение компонентов, как правило, хорошая идея, что не позволяет [компьютерам](../general/computer.md) использовать неверный [монитор](screen1.md) или не позволяет перенагружать их (в результате чего [компьютеры](../general/computer.md) выключатся и отказываются загружаться).
|
||||
|
||||
Также есть беспроводная версия коммутатора, называемая [точка доступа](accessPoint.md), с ее помощью сообщения передаются по беспроводной линии. Сообщения, переданные по беспроводной линии могут быть получены или перенаправлены другими [точками доступа](accessPoint.md) или [компьютерами](../general/computer.md) с [беспроводной сетевой картой](../item/wlanCard.md).
|
||||
|
@ -0,0 +1,9 @@
|
||||
# Транспозер
|
||||
|
||||

|
||||
|
||||
Транспозер заполняет пробел между воронками, контролируемыми редстоун-сигналом и [роботами](robot.md), позволяя [компьютерам](../general/computer.md) контролировать перемещение предметов и жидкостей между соседними блоками.
|
||||
|
||||
*Данный блок не имеет внутреннего инвентаря.*
|
||||
|
||||
Кроме перемещения блоков, он также может быть использован для проверки содержимого соседних инвентарей, подобно [адаптеру](adapter.md) с [контроллером инвентаря](../item/inventoryControllerUpgrade.md), и содержимого соседних хранилищ жидкости, подобно адаптеру с [контроллером жидкости](../item/tankControllerUpgrade.md).
|
@ -2,4 +2,4 @@
|
||||
|
||||

|
||||
|
||||
Сетевая карта позволяет [компьютерам](../general/computer.md) отправлять и получать сетевые сообщения. Сообщения (или пакеты) будут отправлены всем принимающим устройствам в подсети или конкретной сетевой карте (после указания ее адреса). [Коммутаторы](../block/switch.md) и [точки доступа](../block/accessPoint.md) могут быть использованы для связи нескольких подсетей друг с другом, для передачи сообщений в них. Также возможно отправить письмо получателю, даже если он находится в другой подсети, если сеть подключена к одному или нескольким [коммутаторам](../block/switch.md).
|
||||
Сетевая карта позволяет [компьютерам](../general/computer.md) отправлять и получать сетевые сообщения. Сообщения (или пакеты) будут отправлены всем принимающим устройствам в подсети или конкретной сетевой карте (при указании её адреса). [Ретрансляторы](../block/relay.md) могут быть использованы для связи нескольких подсетей друг с другом и передачи сообщений. Также возможно отправить письмо получателю, даже если он находится в другой подсети, если сеть подключена к одному или нескольким [ретрасляторами](../block/relay.md).
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Use [nl] to for a line break.
|
||||
|
||||
# Blocks
|
||||
tile.oc.accessPoint.name=Access Point
|
||||
tile.oc.accessPoint.name=§cAccess Point§7
|
||||
tile.oc.adapter.name=Adapter
|
||||
tile.oc.assembler.name=Electronics Assembler
|
||||
tile.oc.cable.name=Cable
|
||||
@ -23,20 +23,22 @@ tile.oc.hologram2.name=Hologram Projector (Tier 2)
|
||||
tile.oc.keyboard.name=Keyboard
|
||||
tile.oc.microcontroller.name=Microcontroller
|
||||
tile.oc.motionSensor.name=Motion Sensor
|
||||
tile.oc.netSplitter.name=Net Splitter
|
||||
tile.oc.powerConverter.name=Power Converter
|
||||
tile.oc.powerDistributor.name=Power Distributor
|
||||
tile.oc.print.name=3D Print
|
||||
tile.oc.printer.name=3D Printer
|
||||
tile.oc.raid.name=Raid
|
||||
tile.oc.redstone.name=Redstone I/O
|
||||
tile.oc.relay.name=Relay
|
||||
tile.oc.robot.name=Robot
|
||||
tile.oc.robotAfterimage.name=Robot
|
||||
tile.oc.screen1.name=Screen (Tier 1)
|
||||
tile.oc.screen2.name=Screen (Tier 2)
|
||||
tile.oc.screen3.name=Screen (Tier 3)
|
||||
tile.oc.serverRack.name=Server Rack
|
||||
tile.oc.switch.name=Switch
|
||||
tile.oc.netSplitter.name=Net Splitter
|
||||
tile.oc.switch.name=§cSwitch§7
|
||||
tile.oc.transposer.name=Transposer
|
||||
tile.oc.waypoint.name=Waypoint
|
||||
|
||||
# Items
|
||||
@ -235,6 +237,7 @@ oc:container.Disassembler=Disassembler
|
||||
oc:container.DiskDrive=Disk Drive
|
||||
oc:container.Printer=Printer
|
||||
oc:container.Raid=Raid
|
||||
oc:container.Relay=Relay
|
||||
oc:container.Server=Server
|
||||
oc:container.ServerRack=Server Rack
|
||||
oc:container.Switch=Switch
|
||||
@ -328,6 +331,7 @@ oc:tooltip.RedstoneCard.RedNet=§fRedNet§7 is §asupported§7.
|
||||
oc:tooltip.RedstoneCard.WirelessCBE=§fWireless Redstone (ChickenBones)§7 is §asupported§7.
|
||||
oc:tooltip.RedstoneCard.WirelessSV=§fWireless Redstone (SlimeVoid)§7 is §asupported§7.
|
||||
oc:tooltip.RedstoneCard=Allows reading and emitting redstone signals around the computer or robot.
|
||||
oc:tooltip.Relay=Allows connecting different networks to each other. Only network messages will be passed along, components will not be visible through this. Use this to separate networks while still allowing communication using Network Cards, for example.
|
||||
oc:tooltip.Robot=Unlike computers, robots can move around and interact with the world much like a player can.[nl] §cCan not connect to external components.§7
|
||||
# The underscore makes sure this isn't hidden with the rest of the tooltip.
|
||||
oc:tooltip.Robot_Level=§fLevel§7: §a%s§7
|
||||
@ -345,6 +349,7 @@ oc:tooltip.Tier=§8Tier %s
|
||||
oc:tooltip.NetSplitter=Acts as a dynamic connector. Connectivity of each side can be toggled by hitting it with a wrench. Connectivity of all sides can be inverted by applying a redstone signal.
|
||||
oc:tooltip.TooLong=Hold [§f%s§7] for a detailed tooltip.
|
||||
oc:tooltip.Transistor=A basic element in most other computer parts. It's a bit twisted, but it does the job.
|
||||
oc:tooltip.Transposer=Allows automated transferral of items and fluids between adjacent inventories and fluid containers.
|
||||
oc:tooltip.UpgradeAngel=Allows robots to place blocks in thin air, even if there is no point of reference.
|
||||
oc:tooltip.UpgradeBattery=Increase the amount of energy a device can store, allowing it work longer without having to be recharged. [nl] Capacity: §f%s§7
|
||||
oc:tooltip.UpgradeChunkloader=If a robot moves in a forest and no one is around to see it, does it really move? This upgrades makes sure it does. It keeps the chunk a device is in loaded, but continually consumes energy while active.
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Use [nl] to for a line break.
|
||||
|
||||
# Blocks
|
||||
tile.oc.accessPoint.name=Точка доступа
|
||||
tile.oc.accessPoint.name=§cТочка доступа§7
|
||||
tile.oc.adapter.name=Адаптер
|
||||
tile.oc.assembler.name=Сборщик роботов
|
||||
tile.oc.cable.name=Кабель
|
||||
@ -23,6 +23,7 @@ tile.oc.hologram2.name=Голографический проектор (2-ой
|
||||
tile.oc.keyboard.name=Клавиатура
|
||||
tile.oc.microcontroller.name=Микроконтроллер
|
||||
tile.oc.motionSensor.name=Датчик движения
|
||||
tile.oc.netSplitter.name=Сетевой переключатель
|
||||
tile.oc.powerConverter.name=Преобразователь энергии
|
||||
tile.oc.powerDistributor.name=Распределитель энергии
|
||||
tile.oc.print.name=3D модель
|
||||
@ -35,8 +36,8 @@ tile.oc.screen1.name=Монитор (1-ый уровень)
|
||||
tile.oc.screen2.name=Монитор (2-ой уровень)
|
||||
tile.oc.screen3.name=Монитор (3-ий уровень)
|
||||
tile.oc.serverRack.name=Серверная стойка
|
||||
tile.oc.switch.name=Коммутатор
|
||||
tile.oc.netSplitter.name=Сетевой переключатель
|
||||
tile.oc.switch.name=§cКоммутатор§7
|
||||
tile.oc.transposer.name=Транспозер
|
||||
tile.oc.waypoint.name=Путевая точка
|
||||
|
||||
# Items
|
||||
@ -232,6 +233,7 @@ oc:container.Disassembler=Разборщик
|
||||
oc:container.DiskDrive=Дисковод
|
||||
oc:container.Printer=Принтер
|
||||
oc:container.Raid=RAID
|
||||
oc:container.Relay=Ретранслятор
|
||||
oc:container.Server=Сервер
|
||||
oc:container.ServerRack=Серверная стойка
|
||||
oc:container.Switch=Коммутатор
|
||||
@ -325,6 +327,7 @@ oc:tooltip.RedstoneCard.RedNet=Мод §fRedNet§7 §aподдерживаетс
|
||||
oc:tooltip.RedstoneCard.WirelessCBE=Мод §fWireless Redstone (ChickenBones)§7 §aподдерживается§7.
|
||||
oc:tooltip.RedstoneCard.WirelessSV=Мод §fWireless Redstone (SlimeVoid)§7 §aподдерживается§7.
|
||||
oc:tooltip.RedstoneCard=Позволяет принимать и излучать сигналы красного камня вокруг компьютера или робота.
|
||||
oc:tooltip.Relay=Позволяет соединять различные сети между собой. Передаются только сообщения, компоненты между сетями недоступны. Используйте его для разделения сетей с возможностью пересылать сообщения между ними.
|
||||
oc:tooltip.Robot=В отличие от компьютеров, роботы могут передвигаться и взаимодействовать с миром, как игрок.[nl] §cНе могут взаимодействовать с внешними компонентами.§7
|
||||
# The underscore makes sure this isn't hidden with the rest of the tooltip.
|
||||
oc:tooltip.Robot_Level=§fУровень§7: §a%s§7.
|
||||
@ -342,6 +345,7 @@ oc:tooltip.Tier=§8Уровень %s
|
||||
oc:tooltip.NetSplitter=Работает как переключатель. Соединение каждой стороны переключается ключем. При подаче сигнала красного камня все соединения инвертируются.
|
||||
oc:tooltip.TooLong=Удерживайте [§f%s§7], чтобы отобразить описание.
|
||||
oc:tooltip.Transistor=Базовый элемент для других частей компьютера. Он немного деформирован, но отлично выполняет свою работу.
|
||||
oc:tooltip.Transposer=Позволяет автоматизировать перемещение блоков и жидкостей между соседними инвентарями и хранилищами жидкости.
|
||||
oc:tooltip.UpgradeAngel=Позволяет роботам размещать блоки в воздухе, даже если отсутствует точка опоры.
|
||||
oc:tooltip.UpgradeBattery=Увеличивает количество энергии, которую робот может хранить, это позволяет ему работать дольше без перезарядки.
|
||||
oc:tooltip.UpgradeChunkloader=Если робот движется в лесу и никто его не видит, действительно ли он движется? Это улучшение гарантирует, что движется. Оно держит чанк, на котором находится робот, загруженным, но постоянно потребляет энергию.
|
||||
|
@ -31,6 +31,16 @@ function term.clear()
|
||||
cursorX, cursorY = 1, 1
|
||||
end
|
||||
|
||||
function term.reset()
|
||||
if term.isAvailable() then
|
||||
local maxw, maxh = component.gpu.maxResolution()
|
||||
component.gpu.setResolution(maxw, maxh)
|
||||
component.gpu.setBackground(0x000000)
|
||||
component.gpu.setForeground(0xFFFFFF)
|
||||
term.clear()
|
||||
end
|
||||
end
|
||||
|
||||
function term.clearLine()
|
||||
if term.isAvailable() then
|
||||
local w = component.gpu.getResolution()
|
||||
|
@ -12,7 +12,7 @@ Most programs can be interrupted by pressing Ctrl+Alt+C.
|
||||
Paste the contents of the clipboard using the middle mouse button or a configurable key (default: insert).
|
||||
Computers will consume less power while idling - i.e. when os.sleep(n > 0.05) is called.
|
||||
Screens will consume more power the more lit characters they display.
|
||||
Most blocks act as 'cables' - use switches and power distributers to create separate networks.
|
||||
Most blocks act as 'cables' - use relays and power distributors to create separate networks.
|
||||
Welcome to the dark side - here, have some cookies.
|
||||
Screens can display Unicode - paste the special chars or use unicode.char.
|
||||
Run `help` or `man programname` for ingame help on programs shipped with OpenOS - start with `man man`.
|
||||
@ -25,4 +25,4 @@ Have you tried turning it off and on again?
|
||||
To disable this greeting, install OpenOS to a writeable medium and delete `/etc/motd`.
|
||||
Did you know OpenComputers has a forum? No? Well, it's at http://oc.cil.li/.
|
||||
Please report bugs on the Github issue tracker, thank you!
|
||||
Beware of cycles when building networks, or you may get duplicate messages!
|
||||
Beware of cycles when building networks, or you may get duplicate messages!
|
||||
|
@ -8,7 +8,7 @@ if #args == 0 then
|
||||
until not read
|
||||
else
|
||||
for i = 1, #args do
|
||||
local file, reason = io.open(args[i])
|
||||
local file, reason = io.open(args[i],"rb")--TODO: make b an option
|
||||
if not file then
|
||||
io.stderr:write(reason .. "\n")
|
||||
return
|
||||
|
@ -67,6 +67,8 @@ for n = 1, options.count do
|
||||
end
|
||||
if options.wait then
|
||||
os.sleep(tonumber(options.wait))
|
||||
else
|
||||
os.sleep(0)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -5,7 +5,8 @@ local text = require("text")
|
||||
local args, options = shell.parse(...)
|
||||
|
||||
local function formatSize(size)
|
||||
if not options.h then
|
||||
size = tonumber(size) or size
|
||||
if not options.h or type(size) ~= "number" then
|
||||
return tostring(size)
|
||||
end
|
||||
local sizes = {"", "K", "M", "G"}
|
||||
|
@ -73,6 +73,7 @@ local code = ""
|
||||
codeHandler = function(char)
|
||||
if char == "[" then code = code .. char
|
||||
elseif char == "0" then code = code .. char
|
||||
elseif char == "3" then code = code .. char
|
||||
elseif code == "[" and char == "A" then
|
||||
charHandler = baseHandler
|
||||
if y - 1 < 1 then return end
|
||||
@ -139,6 +140,16 @@ codeHandler = function(char)
|
||||
out:write(text)
|
||||
out:close()
|
||||
end
|
||||
elseif code == "[3" and char == "~" then
|
||||
charHandler = baseHandler
|
||||
if x > unicode.len(lines[y]) then
|
||||
lines[y] = lines[y] .. (lines[y + 1] or "")
|
||||
table.remove(lines, y + 1)
|
||||
render(y, atline + edith - y)
|
||||
return
|
||||
end
|
||||
lines[y] = lines[y]:sub(1, x-1) .. lines[y]:sub(x+1)
|
||||
render(y, 1)
|
||||
else
|
||||
charHandler = baseHandler
|
||||
end
|
||||
@ -149,7 +160,7 @@ baseHandler = function(char)
|
||||
code = ""
|
||||
charHandler = codeHandler
|
||||
elseif char == "\n" then
|
||||
line = lines[y]
|
||||
local line = lines[y]
|
||||
lines[y] = unicode.sub(line or "", 1, x - 1)
|
||||
table.insert(lines, y + 1, unicode.sub(line or "", x))
|
||||
x = 1
|
||||
|
@ -199,6 +199,8 @@ local commandList = {}
|
||||
-- \x1b9[Row];[Col];[Height];[Width]F -- fill
|
||||
-- \x1b9[Row];[Col];[Height];[Width];[Dest Row];[Dest Col]c -- copy
|
||||
|
||||
--Add fake gpu component for compat(?)
|
||||
|
||||
function charHandlers.control(char)
|
||||
if char == "\x1b" then
|
||||
commandList = {}
|
||||
|
@ -2,6 +2,21 @@ local network = require "network"
|
||||
local computer = require "computer"
|
||||
local args = {...}
|
||||
|
||||
local function formatSize(size)
|
||||
size = tonumber(size) or size
|
||||
if type(size) ~= "number" then
|
||||
return tostring(size)
|
||||
end
|
||||
local sizes = {"", "K", "M", "G"}
|
||||
local unit = 1
|
||||
local power = 1024
|
||||
while size > power and unit < #sizes do
|
||||
unit = unit + 1
|
||||
size = size / power
|
||||
end
|
||||
return math.floor(size * 10) / 10 .. sizes[unit]
|
||||
end
|
||||
|
||||
local function align(txt)return txt .. (" "):sub(#txt+1)end
|
||||
|
||||
if #args < 1 then
|
||||
@ -14,7 +29,7 @@ if #args < 1 then
|
||||
local pktIn, pktOut, bytesIn, bytesOut = network.info.getInterfaceInfo(node)
|
||||
print(" RX packets:"..tostring(pktIn))
|
||||
print(" TX packets:"..tostring(pktOut))
|
||||
print(" RX bytes:"..tostring(bytesIn).." TX bytes:"..tostring(bytesOut))
|
||||
print(" RX bytes: ".. tostring(bytesIn) .. " (" ..formatSize(bytesIn).. ") TX bytes: " ..tostring(bytesOut) .. " (".. formatSize(bytesOut) .. ")")
|
||||
end
|
||||
elseif args[1] == "bind" and args[2] then
|
||||
print("Address attached")
|
||||
|
@ -1,13 +1,28 @@
|
||||
--Plan9k userspace init for pipes kernel
|
||||
|
||||
--TODO: pcall all + emergency shell(or do it higher, in pipes)
|
||||
|
||||
local pipes = require("pipes")
|
||||
local component = require("component")
|
||||
local filesystem = require("filesystem")
|
||||
local component = require("component")
|
||||
|
||||
os.setenv("LIBPATH", "/lib/?.lua;/usr/lib/?.lua;/home/lib/?.lua;./?.lua;/lib/?/init.lua;/usr/lib/?/init.lua;/home/lib/?/init.lua;./?/init.lua")
|
||||
os.setenv("PATH", "/usr/local/bin:/usr/bin:/bin:.")
|
||||
os.setenv("PWD", "/")
|
||||
os.setenv("PS1", "\x1b[33m$PWD\x1b[31m#\x1b[39m ")
|
||||
|
||||
pipes.log("INIT: Mounting filesystems")
|
||||
|
||||
if filesystem.exists("/etc/fstab") then
|
||||
for entry in io.lines("/etc/fstab") do
|
||||
if entry:sub(1,1) ~= "#" then
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pipes.log("INIT: Starting terminals")
|
||||
|
||||
if not filesystem.exists("/root") then
|
||||
filesystem.makeDirectory("/root")
|
||||
end
|
||||
@ -37,7 +52,6 @@ end
|
||||
|
||||
local sin, sout
|
||||
|
||||
|
||||
local screens = component.list("screen")
|
||||
for gpu in component.list("gpu") do
|
||||
local screen = screens()
|
||||
@ -85,7 +99,11 @@ end
|
||||
pcall(services)
|
||||
|
||||
local kout = io.popen(function()
|
||||
pipes.setThreadName("/bin/tee.lua")
|
||||
if filesystem.exists("/kern.log") then
|
||||
filesystem.remove("/kern.log.old")
|
||||
filesystem.rename("/kern.log", "/kern.log.old")
|
||||
end
|
||||
pipes.setThreadName("[init]/logd")
|
||||
io.output(sout)
|
||||
loadfile("/bin/tee.lua", nil, _G)("/kern.log")
|
||||
end, "w")
|
||||
|
@ -1,5 +1,8 @@
|
||||
local serialization = require("serialization")
|
||||
local term = require("term")
|
||||
local fs = require("filesystem")
|
||||
|
||||
local args = {...}
|
||||
|
||||
local env = setmetatable({}, {__index = _ENV})
|
||||
|
||||
@ -10,6 +13,13 @@ local function optrequire(...)
|
||||
end
|
||||
end
|
||||
|
||||
if args[1] and fs.exists(args[1]) then --non standard, require -i !!!
|
||||
local f = io.open(args[1])
|
||||
local code = load(f:read("*all"), "="..args[1], "t", env)
|
||||
f:close()
|
||||
xpcall(code, debug.traceback)
|
||||
end
|
||||
|
||||
local hist = {}
|
||||
while true do
|
||||
io.write(tostring(env._PROMPT or "lua> "))
|
||||
|
@ -0,0 +1,44 @@
|
||||
local term = require("term")
|
||||
|
||||
function usage()
|
||||
print(
|
||||
[[Usage:
|
||||
more [options] ...
|
||||
|
||||
A file perusal filter for CRT viewing.]])
|
||||
end
|
||||
|
||||
local args = {...}
|
||||
local file = args[1]
|
||||
if not file then usage() return end
|
||||
|
||||
file = io.open(file)
|
||||
|
||||
if not file then
|
||||
print("File not found")
|
||||
return
|
||||
end
|
||||
|
||||
term.clear()
|
||||
local _, h = term.getResolution()
|
||||
io.write("\x1b[1;1H")
|
||||
print("...",h)
|
||||
for i = 1, h - 2 do
|
||||
local line = file:read("*l")
|
||||
if not line then print("input end")return end
|
||||
print(line)
|
||||
end
|
||||
|
||||
io.write("\x1b47m\x1b30m--More--\x1b39m\x1b49m")
|
||||
|
||||
while true do
|
||||
local c = io.read(1)
|
||||
if c == "\n" then
|
||||
local line = file:read("*l")
|
||||
if not line then return end
|
||||
print("\r\x1b[K" .. line)
|
||||
io.write("\x1b47m\x1b30m--More--\x1b39m\x1b49m")
|
||||
elseif c == "q" then
|
||||
return
|
||||
end
|
||||
end
|
@ -203,6 +203,7 @@ while run do
|
||||
if term.getCursor() > 1 then
|
||||
io.write("\n")
|
||||
end
|
||||
io.write("\x1b49m\x1b39m")
|
||||
io.write(expand(os.getenv("PS1")))
|
||||
local cmd = term.read(history)--io.read("*l")
|
||||
--print("--IN: ", cmd)
|
||||
|
@ -3,7 +3,7 @@ local args = {...}
|
||||
local f = io.open(args[1], "a")
|
||||
|
||||
while true do
|
||||
local data = io.read(1)
|
||||
local data = io.read("*L")
|
||||
if not data then
|
||||
f:close()
|
||||
return
|
||||
@ -11,7 +11,7 @@ while true do
|
||||
if io.input().remaining() > 0 then
|
||||
data = data .. io.read(io.input().remaining())
|
||||
end
|
||||
io.write(data)
|
||||
f:write(data)
|
||||
f:flush()
|
||||
io.write(data)
|
||||
end
|
||||
|
@ -9,7 +9,6 @@ proxy.isReadOnly = function() return true end
|
||||
proxy.rename = function() error("Permission Denied") end
|
||||
proxy.remove = function() error("Permission Denied") end
|
||||
proxy.setLabel = function() error("Permission Denied") end
|
||||
proxy.seek = function() error("Not supported") end
|
||||
proxy.size = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local file = data
|
||||
@ -22,7 +21,17 @@ proxy.getLabel = function() return "devfs" end
|
||||
|
||||
local allocator, handles = kernel.modules.util.getAllocator()
|
||||
|
||||
proxy.exists = function()end
|
||||
proxy.exists = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local file = data
|
||||
for _, d in pairs(seg) do
|
||||
if not file[d] then
|
||||
return false
|
||||
end
|
||||
file = file[d]
|
||||
end
|
||||
return file and true or false
|
||||
end
|
||||
proxy.open = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local file = data
|
||||
@ -48,6 +57,9 @@ end
|
||||
proxy.write = function(h, ...)
|
||||
return handles[h].file.write(handles[h], ...)
|
||||
end
|
||||
proxy.seek = function(h, ...)
|
||||
return handles[h].file.seek(handles[h], ...)
|
||||
end
|
||||
proxy.isDirectory = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local dir = data
|
||||
@ -69,8 +81,8 @@ proxy.list = function(path)
|
||||
error("File is not a directory")
|
||||
end
|
||||
local list = {}
|
||||
for f in pairs(dir) do
|
||||
list[#list + 1] = f
|
||||
for f, node in pairs(dir) do
|
||||
list[#list + 1] = f .. (node.__type and "" or "/")
|
||||
end
|
||||
return list
|
||||
end
|
||||
@ -80,6 +92,12 @@ data.null = {
|
||||
__type = "f",
|
||||
write = function()end
|
||||
}
|
||||
data.kmsg = {
|
||||
__type = "f",
|
||||
write = function(h, data)
|
||||
kernel.io.println(data)
|
||||
end
|
||||
}
|
||||
data.zero = {
|
||||
__type = "f",
|
||||
read = function(h, c)
|
||||
|
@ -15,6 +15,7 @@ proxy.getLabel = function() return "procfs" end
|
||||
local allocator, handles = kernel.modules.util.getAllocator()
|
||||
|
||||
proxy.exists = function()end
|
||||
|
||||
proxy.open = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local file = data
|
||||
@ -32,16 +33,21 @@ proxy.open = function(path)
|
||||
end
|
||||
return hnd.id
|
||||
end
|
||||
|
||||
proxy.read = function(h, n)
|
||||
return handles[h]:read(n)
|
||||
end
|
||||
|
||||
proxy.close = function(h)
|
||||
allocator:unset(handles[h])
|
||||
end
|
||||
|
||||
proxy.write = function() error("Permission Denied") end
|
||||
|
||||
proxy.isDirectory = function()
|
||||
|
||||
end
|
||||
|
||||
proxy.list = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local dir = data
|
||||
@ -51,11 +57,11 @@ proxy.list = function(path)
|
||||
local list = {}
|
||||
for pid, thr in pairs(kernel.modules.threading.threads) do
|
||||
if thr.coro and dir == data then
|
||||
list[#list + 1] = tostring(pid)
|
||||
list[#list + 1] = tostring(pid) .. "/"
|
||||
end
|
||||
end
|
||||
for f in pairs(dir) do
|
||||
list[#list + 1] = f
|
||||
for f, node in pairs(dir) do
|
||||
list[#list + 1] = f .. (type(node) == "table" and "/" or "")
|
||||
end
|
||||
return list
|
||||
end
|
||||
@ -72,13 +78,36 @@ data.cpuinfo = function()
|
||||
"cpu family : 1\n" ..
|
||||
"model : 1\n" ..
|
||||
"model name : OpenComputers Lua CPU @ unkown Tier\n" ..
|
||||
"microcode : 0x52\n" ..
|
||||
"microcode : " .. (string.pack and "0x53" or "0x52") .. "\n" ..
|
||||
"physical id : 0\n"
|
||||
end
|
||||
|
||||
data.uptime = function()
|
||||
return tostring(computer.uptime())
|
||||
end
|
||||
|
||||
setmetatable(data, {__index = function(_, k)
|
||||
if tonumber(k) and kernel.modules.threading.threads[tonumber(k)] and kernel.modules.threading.threads[tonumber(k)].coro then
|
||||
return {comm = function()return kernel.modules.threading.threads[tonumber(k)].name end}
|
||||
return {
|
||||
comm = function()return kernel.modules.threading.threads[tonumber(k)].name end,
|
||||
limits = function()
|
||||
local limits = "Limit Units Soft Limit\n"
|
||||
limits = limits .. "Max pending signals signals " .. kernel.modules.threading.threads[tonumber(k)].maxPendingSignals .. "\n"
|
||||
limits = limits .. "Max open files files " .. kernel.modules.threading.threads[tonumber(k)].maxOpenFiles .. "\n"
|
||||
return limits
|
||||
end,
|
||||
status = function()
|
||||
local status = ""
|
||||
status = status .. "Name: " .. kernel.modules.threading.threads[tonumber(k)].name .. "\n"
|
||||
status = status .. "State: " .. coroutine.status(kernel.modules.threading.threads[tonumber(k)].coro) .. "\n"
|
||||
status = status .. "Pid: " .. kernel.modules.threading.threads[tonumber(k)].pid .. "\n"
|
||||
status = status .. "Uid: " .. kernel.modules.threading.threads[tonumber(k)].uid .. "\n"
|
||||
|
||||
--TODO: count actual signals
|
||||
status = status .. "SigQ: " .. #kernel.modules.threading.threads[tonumber(k)].eventQueue .. "/" .. kernel.modules.threading.threads[tonumber(k)].maxPendingSignals .. "\n"
|
||||
return status
|
||||
end
|
||||
}
|
||||
end
|
||||
end})
|
||||
|
||||
|
@ -51,6 +51,7 @@ function kernel.userspace.os.spawn(prog, ...)
|
||||
local thread = kernel.modules.threading.spawn(prog, 0, name, isThread, _, ...)
|
||||
thread.io_output = kernel.modules.threading.currentThread.io_output
|
||||
thread.io_input = kernel.modules.threading.currentThread.io_input
|
||||
thread.io_error = kernel.modules.threading.currentThread.io_error
|
||||
return thread.pid
|
||||
end
|
||||
|
||||
@ -78,6 +79,7 @@ end
|
||||
|
||||
function kernel.userspace.os.exit()
|
||||
kernel.modules.threading.kill(kernel.modules.threading.currentThread.pid)
|
||||
coroutine.yield("yield", 0)
|
||||
end
|
||||
|
||||
function kernel.userspace.os.sleep(time)
|
||||
@ -142,7 +144,12 @@ end
|
||||
|
||||
kernel.userspace.coroutine = {}
|
||||
|
||||
kernel.userspace.coroutine.yield = function(...)
|
||||
return coroutine.yield(...)--TODO: FIX; move to debug
|
||||
end
|
||||
|
||||
--lua 5.3 <-> 5.2 compat
|
||||
kernel.userspace.bit32 = bit32 or load([[return {
|
||||
band = function(a, b) return a & b end,
|
||||
bor = function(a, b) return a | b end,
|
||||
bxor = function(a, b) return a ~ b end,
|
||||
bnot = function(a) return ~a end,
|
||||
rshift = function(a, n) return a >> n end,
|
||||
lshift = function(a, n) return a << n end,
|
||||
}]])()
|
||||
|
@ -39,18 +39,17 @@ end
|
||||
local function pathSearcher(module)
|
||||
local filepath, reason = kernel.userspace.package.searchpath(module, kernel.userspace.os.getenv("LIBPATH"))
|
||||
if filepath then
|
||||
local loader, reason = kernel.userspace.loadfile(filepath, "bt", setmetatable({},{__index = kernel.userspace}))
|
||||
local loader
|
||||
loader, reason = kernel.userspace.loadfile(filepath, "bt", setmetatable({},{__index = kernel.userspace}))
|
||||
if loader then
|
||||
local state, mod = pcall(loader)
|
||||
local state
|
||||
state, reason = pcall(loader)
|
||||
if state then
|
||||
return mod
|
||||
else
|
||||
kernel.io.println("Module '" .. tostring(module) .. "' loading failed: " .. tostring(mod))
|
||||
return reason
|
||||
end
|
||||
end
|
||||
else
|
||||
return nil, reason
|
||||
end
|
||||
return nil, reason
|
||||
end
|
||||
|
||||
kernel.userspace.package.searchers[#kernel.userspace.package.searchers + 1] = preloadSearcher
|
||||
@ -65,19 +64,23 @@ kernel.userspace.require = function(module)
|
||||
if kernel.userspace.package.loading[module] then
|
||||
error("Already loading "..tostring(module))
|
||||
else
|
||||
local reason
|
||||
|
||||
kernel.userspace.package.loading[module] = true
|
||||
for _, searcher in ipairs(kernel.userspace.package.searchers) do
|
||||
local res, mod, reason = pcall(searcher, module)
|
||||
if res and mod then
|
||||
local success, mod, res = pcall(searcher, module)
|
||||
if success and mod then
|
||||
kernel.userspace.package.loading[module] = nil
|
||||
kernel.userspace.package.loaded[module] = mod
|
||||
return mod
|
||||
elseif not mod and reason then
|
||||
kernel.io.println("Searcher for '" .. tostring(module) .. "' loading failed: " .. tostring(reason))
|
||||
elseif (not success) and mod then
|
||||
reason = mod
|
||||
elseif res then
|
||||
reason = res
|
||||
end
|
||||
end
|
||||
kernel.userspace.package.loading[module] = nil
|
||||
error("Could not load module " .. tostring(module))
|
||||
error(string.format("Could not load module '%s': %s", module, reason or "module returned nil"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,47 @@
|
||||
cards = {}
|
||||
|
||||
|
||||
local function buildDevfs()
|
||||
for file in pairs(kernel.modules.devfs.data) do
|
||||
if file == "urandom" then
|
||||
kernel.modules.devfs.data[file] = nil
|
||||
end
|
||||
end
|
||||
|
||||
kernel.modules.devfs.data["urandom"] = {
|
||||
__type = "f",
|
||||
read = function(h, len)
|
||||
return component.invoke(cards[1], "random", len)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
local function onComponentAdded(_, address, componentType)
|
||||
if componentType == "data" then
|
||||
cards[#cards + 1] = address
|
||||
buildDevfs()
|
||||
end
|
||||
end
|
||||
|
||||
local function onComponentRemoved(_, address, componentType)
|
||||
if componentType == "data" then
|
||||
local t
|
||||
for i, card in ipairs(cards) do
|
||||
if card == address then
|
||||
t = i
|
||||
break
|
||||
end
|
||||
end
|
||||
table.remove(cards, t)
|
||||
buildDevfs()
|
||||
end
|
||||
end
|
||||
|
||||
--function start()
|
||||
--for card, t in component.list("data") do
|
||||
-- onComponentAdded(_, card, t)
|
||||
--end
|
||||
--end
|
||||
|
||||
kernel.modules.keventd.listen("component_added", onComponentAdded)
|
||||
kernel.modules.keventd.listen("component_removed", onComponentRemoved)
|
@ -0,0 +1,117 @@
|
||||
drives = {}
|
||||
|
||||
function writeSectors(drive, data, at)
|
||||
local sectorSize = component.invoke(drive, "getSectorSize")
|
||||
repeat
|
||||
local atSector = math.floor((at - 1) / sectorSize) + 1
|
||||
|
||||
local inSectorStart = (at - 1) % sectorSize + 1
|
||||
local writable = math.min(#data, sectorSize - inSectorStart + 1)
|
||||
|
||||
local old = component.invoke(drive, "readSector", atSector)
|
||||
|
||||
local before = old:sub(0, inSectorStart - 1)
|
||||
local after = old:sub(inSectorStart + writable)
|
||||
|
||||
local toWrite = before .. data:sub(1, writable) .. after
|
||||
data = data:sub(writable + 1)
|
||||
|
||||
kernel.io.println("Wd: " .. atSector .. "/" .. #toWrite .. ": "..inSectorStart.." [ " .. writable .. " ] "..(inSectorStart + writable) .. " #old="..#old)
|
||||
component.invoke(drive, "writeSector", atSector, toWrite)
|
||||
|
||||
at = at + writable
|
||||
until #data < 1
|
||||
end
|
||||
|
||||
function readSectors(drive, at, len)
|
||||
local data = ""
|
||||
local sectorSize = component.invoke(drive, "getSectorSize")
|
||||
repeat
|
||||
local atSector = math.floor(at / sectorSize) + 1
|
||||
|
||||
sector = component.invoke(drive, "readSector", atSector)
|
||||
kernel.io.println("Rsect " .. atSector .. ": " .. tostring((at - 1) % sectorSize + 1) .. " -> " .. tostring(math.min((at - 1) % sectorSize + len - #data, sectorSize)))
|
||||
local read = sector:sub((at - 1) % sectorSize + 1, math.min((at - 1) % sectorSize + len - #data, sectorSize))
|
||||
|
||||
data = data .. read
|
||||
at = at + #read
|
||||
until #data >= len
|
||||
return data
|
||||
end
|
||||
|
||||
local function buildDevfs()
|
||||
for file in pairs(kernel.modules.devfs.data) do
|
||||
if file:match("^sd") then
|
||||
kernel.modules.devfs.data[file] = nil
|
||||
end
|
||||
end
|
||||
for k, drive in ipairs(drives) do
|
||||
kernel.modules.devfs.data["sd" .. string.char(k + 96)] = {
|
||||
__type = "f",
|
||||
open = function(hnd)
|
||||
--component.invoke(drive, "seek", -math.huge)
|
||||
hnd.drive = drive
|
||||
hnd.pos = 1
|
||||
--kernel.io.println("Od: " .. hnd.pos .. "/" .. component.invoke(drive, "getCapacity"))
|
||||
end,
|
||||
size = function()
|
||||
return component.invoke(drive, "getCapacity")
|
||||
end,
|
||||
write = function(h, data)
|
||||
|
||||
writeSectors(drive, data, h.pos)
|
||||
--kernel.io.println("Wd: " .. h.pos .. "(+" .. #data .. ")/" .. component.invoke(drive, "getCapacity"))
|
||||
h.pos = h.pos + #data
|
||||
return not (h.pos >= component.invoke(drive, "getCapacity"))
|
||||
--TODO: do this correctly
|
||||
end,
|
||||
read = function(h, len)
|
||||
len = math.ceil(len)
|
||||
kernel.io.println("Rd " .. tostring(len) .. ": " .. h.pos .. "/" .. component.invoke(drive, "getCapacity"))
|
||||
if h.pos >= component.invoke(drive, "getCapacity") then
|
||||
return
|
||||
end
|
||||
local data = readSectors(drive, h.pos, len)
|
||||
h.pos = h.pos + len
|
||||
return data
|
||||
end,
|
||||
seek = function(h, whence, offset)
|
||||
offset = offset or 0
|
||||
if whence == "end" then
|
||||
h.pos = math.min(component.invoke(drive, "getCapacity"), math.max(1, component.invoke(drive, "getCapacity") - offset))
|
||||
return h.pos - 1
|
||||
elseif whence == "set" then
|
||||
h.pos = math.min(component.invoke(drive, "getCapacity"), math.max(1, 1 + offset))
|
||||
return h.pos - 1
|
||||
else
|
||||
h.pos = math.min(component.invoke(drive, "getCapacity"), math.max(1, h.pos + offset))
|
||||
return h.pos - 1
|
||||
end
|
||||
return math.floor(h.pos)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function onComponentAdded(_, address, componentType)
|
||||
if componentType == "drive" then
|
||||
drives[#drives + 1] = address
|
||||
buildDevfs()
|
||||
end
|
||||
end
|
||||
|
||||
local function onComponentRemoved(_, address, componentType)
|
||||
if componentType == "drive" then
|
||||
local t
|
||||
for i, drive in ipairs(drives) do
|
||||
if drive == address then
|
||||
t = i
|
||||
break
|
||||
end
|
||||
end
|
||||
table.remove(drives, t)
|
||||
buildDevfs()
|
||||
end
|
||||
end
|
||||
kernel.modules.keventd.listen("component_added", onComponentAdded)
|
||||
kernel.modules.keventd.listen("component_removed", onComponentRemoved)
|
@ -321,6 +321,7 @@ startNetwork = function()
|
||||
end
|
||||
sent = nil
|
||||
else
|
||||
|
||||
--we've already requested this addr so if we get the route
|
||||
--we'll respond
|
||||
routeRequests[dest][#routeRequests[dest]+1] = {type = "R", host = origin}
|
||||
|
@ -15,20 +15,33 @@ local function buildDevfs()
|
||||
end
|
||||
component.invoke(tape, "seek", -math.huge)
|
||||
hnd.tape = tape
|
||||
hnd.pos = 0
|
||||
end,
|
||||
size = function()
|
||||
return component.invoke(tape, "getSize")
|
||||
end,
|
||||
write = function(h, data)
|
||||
component.invoke(tape, "write", data)
|
||||
return not component.invoke(tape, "isEnd", data)
|
||||
h.pos = h.pos + #data
|
||||
return not (h.pos >= component.invoke(tape, "getSize"))
|
||||
--TODO: do this correctly
|
||||
end,
|
||||
read = function(h, len)
|
||||
if component.invoke(tape, "isEnd", data) then
|
||||
if h.pos >= component.invoke(tape, "getSize") then
|
||||
return
|
||||
end
|
||||
h.pos = h.pos + len
|
||||
return component.invoke(tape, "read", len)
|
||||
end,
|
||||
seek = function(h, whence, offset)
|
||||
if whence == "end" then
|
||||
h.pos = h.pos + component.invoke(tape, "seek", component.invoke(tape, "getSize") - h.pos - (offset or 0))
|
||||
elseif whence == "set" then
|
||||
h.pos = h.pos + component.invoke(tape, "seek", (offset or 0) - h.pos)
|
||||
else
|
||||
h.pos = h.pos + component.invoke(tape, "seek", offset or 0)
|
||||
end
|
||||
return math.floor(h.pos)
|
||||
end
|
||||
}
|
||||
end
|
||||
@ -55,11 +68,11 @@ local function onComponentRemoved(_, address, componentType)
|
||||
end
|
||||
end
|
||||
|
||||
function start()
|
||||
for tape, t in component.list("tape_drive") do
|
||||
onComponentAdded(_, tape, t)
|
||||
end
|
||||
end
|
||||
--function start()
|
||||
-- for tape, t in component.list("tape_drive") do
|
||||
-- onComponentAdded(_, tape, t)
|
||||
-- end
|
||||
--end
|
||||
|
||||
kernel.modules.keventd.listen("component_added", onComponentAdded)
|
||||
kernel.modules.keventd.listen("component_removed", onComponentRemoved)
|
||||
|
@ -71,6 +71,8 @@ function spawn(exec, child, name, isthread, _, ...)
|
||||
currentHandlerArg = nil,
|
||||
eventQueue = {{"arg", ...}},
|
||||
name = name or "unnamed",
|
||||
maxPendingSignals = 32,
|
||||
maxOpenFiles = 8,
|
||||
uid = nextUid
|
||||
}
|
||||
|
||||
@ -132,7 +134,7 @@ local function processSignals()
|
||||
for _, thread in ipairs(threads) do
|
||||
if thread.coro then
|
||||
local nsig, oldest = countThreadSignals(thread, "signal")
|
||||
if nsig > 32 then --TODO: make it a bit more intelligent
|
||||
if nsig > thread.maxPendingSignals then --TODO: make it a bit more intelligent
|
||||
table.remove(thread.eventQueue, oldest)
|
||||
end
|
||||
if thread.currentHandler == "yield" then
|
||||
|
@ -1,4 +1,5 @@
|
||||
function joinThread(pid)
|
||||
--coroutine.yield("yield", 0)
|
||||
while true do
|
||||
local dead = coroutine.yield("kill")
|
||||
if pid == dead then
|
||||
@ -30,7 +31,7 @@ function userKill(pid, signal, ...)
|
||||
local args = {...}
|
||||
local thread = kernel.modules.threading.threads[pid]
|
||||
kernel.modules.manageg.protect(thread.sandbox)
|
||||
--TODO: probably ser threading.currentThread here
|
||||
--TODO: probably set threading.currentThread here
|
||||
local res, reason = pcall(function()
|
||||
thread.kill[signal](table.unpack(args))
|
||||
end)
|
||||
@ -41,7 +42,7 @@ function userKill(pid, signal, ...)
|
||||
return true
|
||||
end
|
||||
|
||||
function setKillHandler(signal, handler)
|
||||
function setKillHandler(signal, handler) --WAT
|
||||
if not kernel.modules.threading.threads[pid]
|
||||
or not kernel.modules.threading.threads[pid].coro then
|
||||
return nil, "Thread does not exists"
|
||||
|
@ -1,6 +1,8 @@
|
||||
local term = {}
|
||||
|
||||
local function read(from, to)
|
||||
term.escape = "\x1b"
|
||||
local write = function(text) io.write(term.escape..text) end
|
||||
local read = function(from, to)
|
||||
local started, data
|
||||
while true do
|
||||
local char = io.read(1)
|
||||
@ -19,6 +21,279 @@ local function read(from, to)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
term.color={}
|
||||
term.color.black=30
|
||||
term.color.red=31
|
||||
term.color.green=32
|
||||
term.color.yellow=33
|
||||
term.color.blue=34
|
||||
term.color.magenta=35
|
||||
term.color.cyan=36
|
||||
term.color.white=37
|
||||
|
||||
term.attr={}
|
||||
term.attr.resetAllAttr=0
|
||||
term.attr.bright=1
|
||||
term.attr.dim=2
|
||||
term.attr.blink=5
|
||||
term.attr.reverse=7
|
||||
term.attr.hidden=8
|
||||
|
||||
------------------------------------------
|
||||
--Set Display Attributes
|
||||
------------------------------------------
|
||||
|
||||
--Set Attribute Mode *ESC*[{attr1};...;{attrn}m
|
||||
function term.setAttr(attr)
|
||||
write(attr.."m")
|
||||
end
|
||||
|
||||
function term.setForeground(color)
|
||||
write(color.."m")
|
||||
end
|
||||
|
||||
function term.setBackground(color)
|
||||
write((color+10).."m")
|
||||
end
|
||||
|
||||
------------------------------------------
|
||||
--Erasing Text
|
||||
------------------------------------------
|
||||
|
||||
--Erase End of Line *ESC*[K
|
||||
--Erases from the current cursor position to the end of the current line.
|
||||
function term.eraseEndOfLine()
|
||||
write("[K")
|
||||
end
|
||||
|
||||
--Erase Start of Line *ESC*[1K
|
||||
--Erases from the current cursor position to the start of the current line.
|
||||
function term.eraseStartOfLine()
|
||||
write("[1K")
|
||||
end
|
||||
|
||||
--Erase Line *ESC*[2K
|
||||
--Erases the entire current line.
|
||||
function term.eraseLine()
|
||||
write("[2K")
|
||||
end
|
||||
term.clearLine = term.eraseLine
|
||||
|
||||
--Erase Down *ESC*[J
|
||||
--Erases the screen from the current line down to the bottom of the screen.
|
||||
function term.eraseDown()
|
||||
write("[J")
|
||||
end
|
||||
|
||||
--Erase Up *ESC*[1J
|
||||
--Erases the screen from the current line up to the top of the screen.
|
||||
function term.eraseUp()
|
||||
write("[1J")
|
||||
end
|
||||
|
||||
--Erase Screen *ESC*[2J
|
||||
--Erases the screen with the background colour and moves the cursor to home.
|
||||
function term.clear()
|
||||
write("[2J")
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------
|
||||
--Tab Control
|
||||
------------------------------------------
|
||||
|
||||
--Set Tab *ESC*H
|
||||
--Sets a tab at the current position.
|
||||
function term.tab()
|
||||
write("[H")
|
||||
end
|
||||
|
||||
--Clear Tab *ESC*[g
|
||||
--Clears tab at the current position.
|
||||
function term.clearTab()
|
||||
write("[g")
|
||||
end
|
||||
|
||||
--Clear All Tabs *ESC*[3g
|
||||
--Clears all tabs.
|
||||
function term.clearTabs()
|
||||
write("[3g")
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------
|
||||
--Scrolling
|
||||
------------------------------------------
|
||||
|
||||
--Scroll Screen *ESC*[r
|
||||
--Enable scrolling for entire display.
|
||||
function term.enableScroll()
|
||||
write("[r")
|
||||
end
|
||||
|
||||
--Scroll Screen *ESC*[{start};{end}r
|
||||
--Enable scrolling from row {start} to row {end}.
|
||||
function term.scrollScreen(from,to)
|
||||
write(string.format("[%d;%dr",from,to))
|
||||
end
|
||||
|
||||
--Scroll Down *ESC*D
|
||||
--Scroll display down one line.
|
||||
function term.scrollScreenDown()
|
||||
write("D")
|
||||
end
|
||||
|
||||
--Scroll Up *ESC*M
|
||||
--Scroll display up one line.
|
||||
function term.scrollScreenUp()
|
||||
write("M")
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------
|
||||
--Cursor Control
|
||||
------------------------------------------
|
||||
|
||||
--Cursor Home *ESC*[{ROW};{COLUMN}H
|
||||
--Sets the cursor position where subsequent text will begin. If no row/column parameters are provided (ie. *ESC*[H), the cursor will move to the home position, at the upper left of the screen.
|
||||
function term.setCursorPosition(row,col)
|
||||
write(string.format("[%d;%dH", row, col))
|
||||
end
|
||||
|
||||
function term.resetCursor()
|
||||
write("[H")
|
||||
end
|
||||
|
||||
--Cursor Up *ESC*[{COUNT}A
|
||||
--Moves the cursor up by COUNT rows; the default count is 1.
|
||||
function term.cursorUp(count)
|
||||
write(string.format("[%dA",(count or 1)))
|
||||
end
|
||||
|
||||
--Cursor Down *ESC*[{COUNT}B
|
||||
--Moves the cursor down by COUNT rows; the default count is 1.
|
||||
function term.cursorDown(count)
|
||||
write(string.format("[%dB",(count or 1)))
|
||||
end
|
||||
|
||||
--Cursor Forward *ESC*[{COUNT}C
|
||||
--Moves the cursor forward by COUNT columns; the default count is 1.
|
||||
function term.cursorForward(count)
|
||||
write(string.format("[%dC",(count or 1)))
|
||||
end
|
||||
|
||||
--Cursor Backward *ESC*[{COUNT}D
|
||||
--Moves the cursor backward by COUNT columns; the default count is 1.
|
||||
function term.cursorBackward(count)
|
||||
write(string.format("[%dD",(count or 1)))
|
||||
end
|
||||
|
||||
--Force Cursor Position *ESC*[{ROW};{COLUMN}f
|
||||
--Identical to Cursor Home.
|
||||
function term.forceCursorPosition(row, col)
|
||||
write(string.format("[%d;%df", row, col))
|
||||
end
|
||||
|
||||
--Save Cursor *ESC*[s
|
||||
--Save current cursor position.
|
||||
function term.saveCursor()
|
||||
write("[s")
|
||||
end
|
||||
|
||||
--Unsave Cursor *ESC*[u
|
||||
--Restores cursor position after a Save Cursor.
|
||||
function term.restoreCursor()
|
||||
write("[u")
|
||||
end
|
||||
|
||||
--Save Cursor & Attrs *ESC*7
|
||||
--Save current cursor position.
|
||||
function term.saveCursorAndAttr()
|
||||
write("7")
|
||||
end
|
||||
|
||||
--Restore Cursor & Attrs *ESC*8
|
||||
--Restores cursor position after a Save Cursor.
|
||||
function term.restoreCursorAndAttr()
|
||||
write("8")
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------
|
||||
--Terminal Setup
|
||||
------------------------------------------
|
||||
|
||||
--Reset Device *ESC*c
|
||||
--Reset all terminal settings to default.
|
||||
function term.reset()
|
||||
write("c")
|
||||
end
|
||||
|
||||
--Enable Line Wrap *ESC*[7h
|
||||
--Text wraps to next line if longer than the length of the display area.
|
||||
function term.enableLineWrap()
|
||||
write("[7h")
|
||||
end
|
||||
|
||||
--Disable Line Wrap *ESC*[7l
|
||||
--Disables line wrapping.
|
||||
function term.disableLineWrap()
|
||||
write("[7l")
|
||||
end
|
||||
|
||||
------------------------------------------
|
||||
--Plan9k codes
|
||||
------------------------------------------
|
||||
|
||||
-- \x1b9[H];[W]R - set resolution
|
||||
function term.setResolution(height,width)
|
||||
write(string.format("9%d;%dR", height, width))
|
||||
end
|
||||
|
||||
-- \x1b9[Row];[Col];[Height];[Width]F -- fill
|
||||
function term.fill(row, col, height, width)
|
||||
write(string.format("9%d;%d;%d;%dF", row, col, height, width))
|
||||
end
|
||||
|
||||
-- \x1b9[Row];[Col];[Height];[Width];[Dest Row];[Dest Col]c -- copy
|
||||
function term.copy(row, col, height, width, destRow, destCol)
|
||||
write(string.format("9%d;%d;%d;%d;%d;%dc", row, col, height, width, destRow, destCol ))
|
||||
end
|
||||
|
||||
--get resolution
|
||||
function term.getResolution()
|
||||
local y, x = term.getCursorPosition()
|
||||
term.setCursorPosition(999,999)
|
||||
local h, w = term.getCursorPosition()
|
||||
term.setCursorPosition(y,x)
|
||||
return tonumber(h), tonumber(w)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function term.clear()
|
||||
io.write("\x1b[2J")
|
||||
|
@ -0,0 +1,42 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
|
||||
local args, parms = shell.parse(...)
|
||||
if parms.h or parms.help then
|
||||
io.stderr:write("See: man base64" .. "\n")
|
||||
os.exit(true)
|
||||
end
|
||||
local encodingfun = nil
|
||||
local encode
|
||||
if parms.d or parms.decode then
|
||||
encodingfun = data.decode64
|
||||
encode = false
|
||||
else
|
||||
encodingfun = data.encode64
|
||||
encode = true
|
||||
end
|
||||
|
||||
if #args == 0 then
|
||||
repeat
|
||||
local read = io.read(encode and 3 or 4)
|
||||
if read then
|
||||
io.write(encodingfun(read))
|
||||
end
|
||||
until not read
|
||||
else
|
||||
for i = 1, #args do
|
||||
local file, reason = io.open(shell.resolve(args[i]))
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local line = file:read(encode and 3 or 4)
|
||||
if line then
|
||||
io.write(encodingfun(line))
|
||||
end
|
||||
until not line
|
||||
file:close()
|
||||
end
|
||||
end
|
@ -0,0 +1,25 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
local args = shell.parse(...)
|
||||
if #args == 0 then
|
||||
local read = ""
|
||||
repeat
|
||||
local current = io.read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
io.write(data.deflate(read))
|
||||
else
|
||||
local read = ""
|
||||
local file, reason = io.open(shell.resolve(args[1]))
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local current = file:read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.deflate(read))
|
||||
end
|
@ -0,0 +1,244 @@
|
||||
--[[
|
||||
-- A program that allows user to perform all crypto operations provided by Tier II / Tier III data cards
|
||||
-- Author: makkarpov
|
||||
--]]
|
||||
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
local term = require("term")
|
||||
local filesystem = require("filesystem")
|
||||
local serialization = require("serialization")
|
||||
|
||||
local args, options = shell.parse(...)
|
||||
|
||||
local function writeFile(path, data)
|
||||
if filesystem.exists(path) then
|
||||
io.stderr:write("gpg: failed to write file: " .. path .. "\n")
|
||||
io.stderr:write("gpg: error was: file already exists\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if type(data) == "table" then
|
||||
data = serialization.serialize(data)
|
||||
end
|
||||
|
||||
local h, err = io.open(path, "wb")
|
||||
|
||||
if not h then
|
||||
io.stderr:write("gpg: failed to write file: " .. path .. "\n")
|
||||
io.stderr:write("gpg: error was: " .. err .. "\n")
|
||||
return false
|
||||
end
|
||||
|
||||
h:write(data)
|
||||
h:close()
|
||||
return true
|
||||
end
|
||||
|
||||
local function readFile(path, deserialize)
|
||||
local h = io.open(path, "rb")
|
||||
local r = h:read("*a")
|
||||
h:close()
|
||||
|
||||
if deserialize then
|
||||
r = serialization.unserialize(r)
|
||||
end
|
||||
|
||||
return r
|
||||
end
|
||||
|
||||
local function parseKey(path, isPublic)
|
||||
local d = readFile(path, true)
|
||||
local k, err = data.deserializeKey(d.d, d.t)
|
||||
|
||||
if not k then
|
||||
io.stderr:write("gpg: failed to parse key: " .. err .. "\n")
|
||||
return nil
|
||||
end
|
||||
|
||||
if k.isPublic() ~= isPublic then
|
||||
io.stderr:write("gpg: wrong key type\n")
|
||||
return nil
|
||||
end
|
||||
|
||||
return k
|
||||
end
|
||||
|
||||
local function deriveName(base, encrypt)
|
||||
if encrypt then
|
||||
return base .. ".gpg"
|
||||
else
|
||||
local d = base:gsub(".gpg", "")
|
||||
if d == base then
|
||||
d = d .. ".dec"
|
||||
io.write("gpg: decrypting to " .. d .. "\n")
|
||||
end
|
||||
return d
|
||||
end
|
||||
end
|
||||
|
||||
local function ensureMethods(...)
|
||||
if not require("component").isAvailable("data") then
|
||||
io.stderr:write("gpg: you must have data card in order to run this program\n")
|
||||
error("data card is absent")
|
||||
end
|
||||
|
||||
local names = table.pack(...)
|
||||
for i = 1, names.n do
|
||||
if names[i] and not data[names[i]] then
|
||||
io.stderr:write("gpg: method " .. names[i] .. " required on data card to run this program\n")
|
||||
error("data card tier insufficient")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if options['g'] and (#args == 2) then
|
||||
ensureMethods("generateKeyPair")
|
||||
local pub, priv = data.generateKeyPair(384)
|
||||
|
||||
priv = { t = priv.keyType(), d = priv.serialize() }
|
||||
pub = { t = pub.keyType(), d = pub.serialize() }
|
||||
|
||||
if not writeFile(args[1], priv) then
|
||||
io.stderr:write("gpg: failed to write private key, aborting\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if not writeFile(args[2], pub) then
|
||||
io.stderr:write("gpg: failed to write public key, aborting\n")
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if options['c'] and (options['e'] or options['d']) and (#args == 1) then
|
||||
ensureMethods("md5", "sha256", "encrypt", "decrypt", "random")
|
||||
if options['d'] and options['e'] then
|
||||
io.stderr:write("gpg: please specify either -d or -e\n")
|
||||
return false
|
||||
end
|
||||
|
||||
io.write("gpg: enter password: ")
|
||||
local aesKey = data.md5(term.read(nil, nil, nil, "*"))
|
||||
local checkValue = data.sha256(aesKey)
|
||||
|
||||
if options['e'] then
|
||||
local iv = data.random(16)
|
||||
local d = data.encrypt(readFile(args[1]), aesKey, iv)
|
||||
|
||||
return writeFile(deriveName(args[1], true), {
|
||||
t = "pwd",
|
||||
kdf = "md5",
|
||||
iv = iv,
|
||||
cv = checkValue,
|
||||
d = d
|
||||
})
|
||||
else
|
||||
local d = readFile(args[1], true)
|
||||
|
||||
if d.t ~= "pwd" then
|
||||
io.stderr:write("gpg: file is not encrypted with a password\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if checkValue ~= d.cv then
|
||||
io.stderr:write("gpg: password incorrect\n")
|
||||
return false
|
||||
end
|
||||
|
||||
return writeFile(deriveName(args[1], false), data.decrypt(d.d, aesKey, d.iv))
|
||||
end
|
||||
end
|
||||
|
||||
if (options['d'] or options['e']) and (#args == 2) then
|
||||
ensureMethods("md5", "sha256", "encrypt", "decrypt", "random", "generateKeyPair", "deserializeKey", "ecdh")
|
||||
if options['d'] and options['e'] then
|
||||
io.stderr:write("gpg: please specify either -d or -e\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if options['e'] then
|
||||
local userPub = parseKey(args[1], true)
|
||||
local tmpPub, tmpPriv = data.generateKeyPair(384)
|
||||
local aesKey = data.md5(data.ecdh(tmpPriv, userPub))
|
||||
local checkValue = data.sha256(aesKey)
|
||||
local iv = data.random(16)
|
||||
|
||||
local d = data.encrypt(readFile(args[2]), aesKey, iv)
|
||||
return writeFile(deriveName(args[2], true), {
|
||||
t = "ecdh",
|
||||
kdf = "md5",
|
||||
iv = iv,
|
||||
cv = checkValue,
|
||||
k = {
|
||||
t = tmpPub.keyType(),
|
||||
d = tmpPub.serialize()
|
||||
},
|
||||
d = d
|
||||
})
|
||||
else
|
||||
local userPriv = parseKey(args[1], false)
|
||||
local d = readFile(args[2], true)
|
||||
|
||||
if d.t ~= "ecdh" then
|
||||
io.stderr:write("gpg: file is not encrypted with a key\n")
|
||||
return false
|
||||
end
|
||||
|
||||
local tmpPub = data.deserializeKey(d.k.d, d.k.t)
|
||||
local aesKey = data.md5(data.ecdh(userPriv, tmpPub))
|
||||
|
||||
if d.cv ~= data.sha256(aesKey) then
|
||||
io.stderr:write("gpg: invalid key\n")
|
||||
return false
|
||||
end
|
||||
|
||||
return writeFile(deriveName(args[2], false), data.decrypt(d.d, aesKey, d.iv))
|
||||
end
|
||||
end
|
||||
|
||||
if (options['s'] or options['v']) and (#args == 2) then
|
||||
ensureMethods("deserializeKey", "ecdsa")
|
||||
if options['s'] and options['v'] then
|
||||
io.stderr:write("gpg: please specify either -s or -v\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if options['s'] then
|
||||
local userPriv = parseKey(args[1], false)
|
||||
local sign = data.ecdsa(readFile(args[2]), userPriv)
|
||||
|
||||
return writeFile(args[2] .. ".sig", {
|
||||
t = "ecdsa",
|
||||
s = sign
|
||||
})
|
||||
else
|
||||
local userPub = parseKey(args[1], true)
|
||||
local sign = readFile(args[2] .. ".sig", true)
|
||||
|
||||
if sign.t ~= "ecdsa" then
|
||||
io.stderr:write("gpg: unsupported signature type\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if not data.ecdsa(readFile(args[2]), userPub, sign.s) then
|
||||
io.stderr:write("gpg: signature verification failed\n")
|
||||
return false
|
||||
end
|
||||
|
||||
io.write("gpg: signature is valid\n")
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
io.write("Usages:\n")
|
||||
io.write("gpg -ce <file> -- encrypt file with password\n")
|
||||
io.write("gpg -cd <file> -- decrypt file with password\n")
|
||||
io.write("gpg -e <key> <file> -- encrypt file\n")
|
||||
io.write("gpg -d <key> <file> -- decrypt file\n")
|
||||
io.write("gpg -g <private key file> <public key file> -- generate keypair\n")
|
||||
io.write("gpg -s <key> <file> -- sign file\n")
|
||||
io.write("gpg -v <key> <file> -- verify file\n")
|
||||
return false
|
@ -0,0 +1,25 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
local args = shell.parse(...)
|
||||
if #args == 0 then
|
||||
local read = ""
|
||||
repeat
|
||||
local current = io.read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
io.write(data.inflate(read))
|
||||
else
|
||||
local read = ""
|
||||
local file, reason = io.open(shell.resolve(args[1]))
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local current = file:read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.inflate(read))
|
||||
end
|
@ -0,0 +1,27 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
local args = shell.parse(...)
|
||||
if #args == 0 then
|
||||
local read = ""
|
||||
repeat
|
||||
local current = io.read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
io.write(data.toHex(data.md5(read)))
|
||||
else
|
||||
for i = 1, #args do
|
||||
local read = ""
|
||||
local file, reason = io.open(args[i])
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local current = file:read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.toHex(data.md5(read)) .. "\t".. args[i] .. "\n")
|
||||
end
|
||||
end
|
@ -81,17 +81,25 @@ ocBackend = {
|
||||
print(" Upgrade all packages that are out-of-date on the")
|
||||
print(" local system. Only package versions are used to find outdated packages;")
|
||||
print(" replacements are not checked here. This is a ?remove-then-add? process.")
|
||||
print(" -f, --force")
|
||||
print(" Force operation, in case of upgrade it redownloads all packages")
|
||||
print(" --root='/some/dir'")
|
||||
print(" Set alternative root directory")
|
||||
print(" -v")
|
||||
print(" More output")
|
||||
print(" -y")
|
||||
print(" Don't ask any questions, answer automatically")
|
||||
print(" -r, --reboot")
|
||||
print(" reboot after operation")
|
||||
return
|
||||
end
|
||||
|
||||
if options.v then loglevel = 0 end
|
||||
|
||||
if options.f or options.force then
|
||||
core.data.force = true
|
||||
end
|
||||
|
||||
if options.S or options.sync then
|
||||
for _, pack in ipairs(args) do
|
||||
core.install(pack)
|
||||
@ -114,6 +122,8 @@ ocBackend = {
|
||||
if options.y then
|
||||
ocBackend.prompt = function()return true end
|
||||
end
|
||||
|
||||
core.reboot = optionsr or options.reboot
|
||||
core.doWork()
|
||||
end,
|
||||
|
||||
@ -208,7 +218,8 @@ ocBackend = {
|
||||
if p:sub(1,1):upper() ~= "Y" then
|
||||
error("User stopped")
|
||||
end
|
||||
end
|
||||
end,
|
||||
reboot = function()computer.shutdown(true) end
|
||||
}
|
||||
|
||||
local mptFrontend
|
||||
@ -249,7 +260,7 @@ mptFrontend = {
|
||||
local toCheck = {}
|
||||
for pack, data in pairs(base.installed) do
|
||||
if data.frontend == mptFrontend.name then
|
||||
toCheck[pack] = base.installed[pack].data.checksum
|
||||
toCheck[pack] = base.installed[pack].data.checksum .. (core.data.force and "WAT" or "")
|
||||
end
|
||||
end
|
||||
local updateResp = backend.getText(config.frontend.mpt.api.."update", toCheck)
|
||||
@ -368,6 +379,8 @@ core = {
|
||||
upgrade = false,
|
||||
remove = false,
|
||||
|
||||
force = false,
|
||||
|
||||
--User requested packages
|
||||
userInstall = {},
|
||||
|
||||
@ -603,7 +616,8 @@ end
|
||||
core.log(1, "Main", "> Saving settings")
|
||||
core.finalize()
|
||||
|
||||
|
||||
|
||||
if core.reboot then
|
||||
backend.reboot()
|
||||
end
|
||||
|
||||
|
||||
|
@ -0,0 +1,27 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
local args = shell.parse(...)
|
||||
if #args == 0 then
|
||||
local read = ""
|
||||
repeat
|
||||
local current = io.read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
io.write(data.toHex(data.sha256(read)))
|
||||
else
|
||||
for i = 1, #args do
|
||||
local read = ""
|
||||
local file, reason = io.open(shell.resolve(args[i]))
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local current = file:read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.toHex(data.sha256(read)) .. "\t".. args[i] .. "\n")
|
||||
end
|
||||
end
|
@ -0,0 +1,26 @@
|
||||
local component = require("component")
|
||||
|
||||
local data = {}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-- Converts binary data into hexadecimal string.
|
||||
function data.toHex(data)
|
||||
return (data:gsub('.', function (c)
|
||||
return string.format('%02X', string.byte(c))
|
||||
end))
|
||||
end
|
||||
|
||||
-- Converts hexadecimal string into binary data.
|
||||
function data.fromHex(hex)
|
||||
return (hex:gsub('..', function (cc)
|
||||
return string.char(tonumber(cc, 16))
|
||||
end))
|
||||
end
|
||||
|
||||
-- Forward everything else to the primary data card.
|
||||
setmetatable(data, { __index = function(_, key) return component.data[key] end })
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
return data
|
@ -1 +1 @@
|
||||
{cacheDir="/var/lib/mpt/cache/",database="/var/lib/mpt/base.db",frontend={mpt={api="http://mpt.magik6k.net/api/"}}}
|
||||
{database="/var/lib/mpt/base.db",cacheDir="/var/lib/mpt/cache/",frontend={mpt={api="http://mpt.magik6k.net/api/"}}}
|
@ -1 +1 @@
|
||||
{installed={["plan9k-drivers"]={frontend="MPT",data={name="plan9k-drivers",repo="plan9k",checksum="-2327b14292d5c08f547d24e9b5122349",files={"/lib/modules/base/17_tape.lua","/lib/modules/base/17_eeprom.lua","/lib/modules/base/17_nfc.lua","/lib/modules/base/17_chatbox.lua"},dependencies={}},deps={}},["plan9k-shell"]={frontend="MPT",data={name="plan9k-shell",repo="plan9k",checksum="-4ebb18f6dedde575d4d61460494b3bbb",files={"/bin/sh.lua"},dependencies={}},deps={}},["plan9k-corelibs"]={frontend="MPT",data={name="plan9k-corelibs",repo="plan9k",checksum="1d01d437b10e8561a39cb9f108cc3d47",files={"/lib/serialization.lua","/lib/term.lua","/lib/text.lua","/lib/shell.lua","/lib/event.lua"},dependencies={}},deps={}},mpt={frontend="MPT",data={name="mpt",repo="mpt",checksum="f9d7744571e5c46c658f405043c656",files={"/usr/bin/mpt.lua"},dependencies={}},deps={}},["plan9k-fsutil"]={frontend="MPT",data={name="plan9k-fsutil",repo="plan9k",checksum="aded7c8083efcdcfe43908183370687",files={"/bin/cat.lua","/bin/ln.lua","/bin/ls.lua","/bin/mv.lua","/bin/rm.lua","/bin/tee.lua","/bin/df.lua","/bin/dd.lua","/bin/cp.lua","/bin/touch.lua","/bin/mount.lua","/bin/mount.cow.lua","/bin/mkdir.lua","/bin/pwd.lua"},dependencies={"plan9k-corelibs"}},deps={"plan9k-corelibs"}},["plan9k-network"]={frontend="MPT",data={name="plan9k-network",repo="plan9k",checksum="-29d10c88b7ed4116d5b4eacd019d5ad9",files={"/lib/internet.lua","/bin/pastebin.lua","/bin/wget.lua","/lib/modules/base/17_network.lua","/lib/modules/base/19_libnetwork.lua","/bin/arp.lua","/bin/ifconfig.lua","/bin/ping.lua","/bin/route.lua","/lib/modules/network/loopback.lua","/lib/modules/network/modem.lua","/usr/bin/nc.lua","/lib/modules/network/tunnel.lua"},dependencies={}},deps={}},pipes={frontend="MPT",data={name="pipes",repo="plan9k",checksum="6d088970fd4fb29b78279eef4d417646",files={"/boot/kernel/pipes","/lib/modules/base/05_vfs.lua","/lib/modules/base/20_threading.lua","/lib/modules/base/19_manageg.lua","/lib/modules/base/25_init.lua","/lib/modules/base/15_userspace.lua","/usr/man/pipes","/lib/modules/base/16_buffer.lua","/lib/modules/base/17_io.lua","/lib/modules/base/16_require.lua","/lib/modules/base/18_syscall.lua","/lib/modules/base/21_threadUtil.lua","/lib/modules/base/21_timer.lua","/lib/modules/base/16_component.lua","/lib/modules/base/15_keventd.lua","/lib/modules/base/10_procfs.lua","/lib/modules/base/01_util.lua","/lib/modules/base/10_devfs.lua","/lib/modules/base/18_pty.lua","/lib/modules/base/17_keyboard.lua","/lib/modules/base/06_cowfs.lua","/lib/modules/base/09_rootfs.lua","/lib/modules/base/01_gc.lua"},dependencies={"openloader-init"}},deps={"openloader-init"}},["plan9k-edit"]={frontend="MPT",data={name="plan9k-edit",repo="plan9k",checksum="fed5f4ee1212297b07247afa1cfe3a2",files={"/bin/edit.lua"},dependencies={}},deps={}},["plan9k-core"]={frontend="MPT",data={name="plan9k-core",repo="plan9k",checksum="-4f5e4f44875482035444a2b61e96243d",files={"/bin/init.lua","/bin/getty.lua","/bin/readkey.lua","/lib/rc.lua","/bin/rc.lua"},dependencies={"pipes","plan9k-coreutil","plan9k-shell"}},deps={"pipes","plan9k-coreutil","plan9k-shell"}},plan9k={frontend="MPT",data={name="plan9k",repo="plan9k",checksum="-c16ccdf21a1ff13be8f6258d1a17d89",files={},dependencies={"plan9k-core","plan9k-network","plan9k-drivers","plan9k-edit"}},deps={"plan9k-core","plan9k-network","plan9k-drivers","plan9k-edit"}},["plan9k-installer"]={frontend="MPT",data={name="plan9k-installer",repo="plan9k",checksum="52c8f82357c966ce3e19c97bf3942012",files={"/bin/install.lua"},dependencies={"plan9k","mpt"}},deps={"plan9k","mpt"}},["openloader-init"]={frontend="MPT",data={name="openloader-init",repo="disks",checksum="-45e6d7b1e41468c1d335952ee3b89e13",files={"/init.lua"},dependencies={}},deps={}},["plan9k-coreutil"]={frontend="MPT",data={name="plan9k-coreutil",repo="plan9k",checksum="-50d3cee571b07b6cb05f6fb01989997c",files={"/bin/echo.lua","/bin/wc.lua","/bin/ps.lua","/bin/lua.lua","/bin/kill.lua","/bin/reboot.lua","/bin/sleep.lua","/bin/clear.lua","/bin/components.lua","/bin/hostname.lua","/bin/dmesg.lua","/bin/shutdown.lua","/bin/label.lua","/bin/uptime.lua","/bin/resolution.lua"},dependencies={"plan9k-corelibs","plan9k-fsutil"}},deps={"plan9k-corelibs","plan9k-fsutil"}}}}
|
||||
{installed={["plan9k-shell"]={deps={},frontend="MPT",data={checksum="517b9e0693e734a4ab516f12a6798f14",files={"/bin/sh.lua"},name="plan9k-shell",repo="plan9k",dependencies={}}},plan9k={deps={"plan9k-core","plan9k-network","plan9k-drivers","plan9k-edit","plan9k-data"},frontend="MPT",data={checksum="-2d8f4b84ea60b0c9d5846f57e9f1691c",files={},name="plan9k",repo="plan9k",dependencies={"plan9k-core","plan9k-network","plan9k-drivers","plan9k-edit","plan9k-data"}}},["plan9k-fsutil"]={deps={"plan9k-corelibs"},frontend="MPT",data={checksum="6a974a71f62315e6e2294eae132d1751",files={"/bin/cat.lua","/bin/ln.lua","/bin/ls.lua","/bin/mv.lua","/bin/rm.lua","/bin/tee.lua","/bin/df.lua","/bin/dd.lua","/bin/cp.lua","/bin/touch.lua","/bin/mount.lua","/bin/mount.cow.lua","/bin/mkdir.lua","/bin/pwd.lua","/bin/more.lua"},name="plan9k-fsutil",repo="plan9k",dependencies={"plan9k-corelibs"}}},["plan9k-edit"]={deps={},frontend="MPT",data={checksum="34b1046ac9b7a87a1cdd74f8c03f27ea",files={"/bin/edit.lua"},name="plan9k-edit",repo="plan9k",dependencies={}}},["plan9k-core"]={deps={"pipes","plan9k-coreutil","plan9k-shell"},frontend="MPT",data={checksum="-6f77a020200f96eefd1559dcd8af14a5",files={"/bin/init.lua","/bin/getty.lua","/bin/readkey.lua","/lib/rc.lua","/bin/rc.lua"},name="plan9k-core",repo="plan9k",dependencies={"pipes","plan9k-coreutil","plan9k-shell"}}},["plan9k-installer"]={deps={"plan9k","mpt"},frontend="MPT",data={checksum="52c8f82357c966ce3e19c97bf3942012",files={"/bin/install.lua"},name="plan9k-installer",repo="plan9k",dependencies={"plan9k","mpt"}}},["plan9k-drivers"]={deps={},frontend="MPT",data={checksum="-35f098652460458c13f83499b4633e2d",files={"/lib/modules/base/17_tape.lua","/lib/modules/base/17_eeprom.lua","/lib/modules/base/17_nfc.lua","/lib/modules/base/17_chatbox.lua","/lib/modules/base/17_data.lua","/lib/modules/base/17_drive.lua"},name="plan9k-drivers",repo="plan9k",dependencies={}}},["plan9k-coreutil"]={deps={"plan9k-corelibs","plan9k-fsutil"},frontend="MPT",data={checksum="5fa7e70e3aba17fef97ed65489efb0ca",files={"/bin/echo.lua","/bin/wc.lua","/bin/ps.lua","/bin/lua.lua","/bin/kill.lua","/bin/reboot.lua","/bin/sleep.lua","/bin/clear.lua","/bin/components.lua","/bin/hostname.lua","/bin/dmesg.lua","/bin/shutdown.lua","/bin/label.lua","/bin/uptime.lua","/bin/resolution.lua"},name="plan9k-coreutil",repo="plan9k",dependencies={"plan9k-corelibs","plan9k-fsutil"}}},["openloader-init"]={deps={},frontend="MPT",data={checksum="-45e6d7b1e41468c1d335952ee3b89e13",files={"/init.lua"},name="openloader-init",repo="disks",dependencies={}}},mpt={deps={},frontend="MPT",data={checksum="-3435ded79cf9de20e7185f403eee4a28",files={"/usr/bin/mpt.lua"},name="mpt",repo="mpt",dependencies={}}},pipes={deps={"openloader-init"},frontend="MPT",data={checksum="123b56992859cf05cd03af825437d734",files={"/boot/kernel/pipes","/lib/modules/base/05_vfs.lua","/lib/modules/base/20_threading.lua","/lib/modules/base/19_manageg.lua","/lib/modules/base/25_init.lua","/lib/modules/base/15_userspace.lua","/usr/man/pipes","/lib/modules/base/16_buffer.lua","/lib/modules/base/17_io.lua","/lib/modules/base/16_require.lua","/lib/modules/base/18_syscall.lua","/lib/modules/base/21_threadUtil.lua","/lib/modules/base/21_timer.lua","/lib/modules/base/16_component.lua","/lib/modules/base/15_keventd.lua","/lib/modules/base/10_procfs.lua","/lib/modules/base/01_util.lua","/lib/modules/base/10_devfs.lua","/lib/modules/base/18_pty.lua","/lib/modules/base/17_keyboard.lua","/lib/modules/base/06_cowfs.lua","/lib/modules/base/09_rootfs.lua","/lib/modules/base/01_gc.lua"},name="pipes",repo="plan9k",dependencies={"openloader-init"}}},["plan9k-corelibs"]={deps={},frontend="MPT",data={checksum="1cb7fa12e1a1a35fc168409b60cfe552",files={"/lib/serialization.lua","/lib/term.lua","/lib/text.lua","/lib/shell.lua","/lib/event.lua"},name="plan9k-corelibs",repo="plan9k",dependencies={}}},["plan9k-data"]={deps={},frontend="MPT",data={checksum="480a898a741b2bf424f9e0e86e5072ba",files={"/usr/bin/base64.lua","/usr/lib/data.lua","/usr/bin/deflate.lua","/usr/bin/inflate.lua","/usr/bin/md5sum.lua","/usr/bin/sha256sum.lua","/usr/bin/gpg.lua"},name="plan9k-data",repo="plan9k",dependencies={}}},["plan9k-network"]={deps={},frontend="MPT",data={checksum="6e06e6cf5028583fe54047ba9e19abc6",files={"/lib/internet.lua","/bin/pastebin.lua","/bin/wget.lua","/lib/modules/base/17_network.lua","/lib/modules/base/19_libnetwork.lua","/bin/arp.lua","/bin/ifconfig.lua","/bin/ping.lua","/bin/route.lua","/lib/modules/network/loopback.lua","/lib/modules/network/modem.lua","/usr/bin/nc.lua","/lib/modules/network/tunnel.lua"},name="plan9k-network",repo="plan9k",dependencies={}}}}}
|
@ -1320,6 +1320,23 @@ local libcomputer = {
|
||||
|
||||
beep = function(...)
|
||||
libcomponent.invoke(computer.address(), "beep", ...)
|
||||
end,
|
||||
|
||||
getArchitectures = function(...)
|
||||
return spcall(computer.getArchitectures, ...)
|
||||
end,
|
||||
getArchitecture = function(...)
|
||||
return spcall(computer.getArchitecture, ...)
|
||||
end,
|
||||
setArchitecture = function(...)
|
||||
local result, reason = spcall(computer.setArchitecture, ...)
|
||||
if not result then
|
||||
if reason then
|
||||
return result, reason
|
||||
end
|
||||
else
|
||||
coroutine.yield(true) -- reboot
|
||||
end
|
||||
end
|
||||
}
|
||||
sandbox.computer = libcomputer
|
||||
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "block/cube_bottom_top",
|
||||
"textures": {
|
||||
"top": "opencomputers:blocks/switch_top",
|
||||
"bottom": "opencomputers:blocks/generic_top",
|
||||
"side": "opencomputers:blocks/switch_side"
|
||||
}
|
||||
}
|
@ -0,0 +1,221 @@
|
||||
{
|
||||
"textures": {
|
||||
"bottom": "opencomputers:blocks/transposer_top",
|
||||
"top": "opencomputers:blocks/transposer_top",
|
||||
"side": "opencomputers:blocks/transposer_side",
|
||||
"particle": "opencomputers:blocks/generic_top"
|
||||
},
|
||||
"elements": [
|
||||
{ "from": [ 0, 0, 0 ],
|
||||
"to": [ 7, 7, 7 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 0, 0, 7, 7 ], "texture": "#top" },
|
||||
"down": { "uv": [ 0, 9, 7, 16 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 9, 9, 16, 16 ], "texture": "#side" },
|
||||
"south": { "uv": [ 0, 9, 7, 16 ], "texture": "#side" },
|
||||
"west": { "uv": [ 0, 9, 7, 16 ], "texture": "#side" },
|
||||
"east": { "uv": [ 9, 9, 16, 16 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 0, 0, 9 ],
|
||||
"to": [ 7, 7, 16 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 0, 9, 7, 16 ], "texture": "#top" },
|
||||
"down": { "uv": [ 0, 0, 7, 7 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 9, 9, 16, 16 ], "texture": "#side" },
|
||||
"south": { "uv": [ 0, 9, 7, 16 ], "texture": "#side" },
|
||||
"west": { "uv": [ 9, 9, 16, 16 ], "texture": "#side" },
|
||||
"east": { "uv": [ 0, 9, 7, 16 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 0, 9, 0 ],
|
||||
"to": [ 7, 16, 7 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 0, 0, 7, 7 ], "texture": "#top" },
|
||||
"down": { "uv": [ 0, 9, 7, 16 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 9, 0, 16, 7 ], "texture": "#side" },
|
||||
"south": { "uv": [ 0, 0, 7, 7 ], "texture": "#side" },
|
||||
"west": { "uv": [ 0, 0, 7, 7 ], "texture": "#side" },
|
||||
"east": { "uv": [ 9, 0, 16, 7 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 0, 9, 9 ],
|
||||
"to": [ 7, 16, 16 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 0, 9, 7, 16 ], "texture": "#top" },
|
||||
"down": { "uv": [ 0, 0, 7, 7 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 9, 0, 16, 7 ], "texture": "#side" },
|
||||
"south": { "uv": [ 0, 0, 7, 7 ], "texture": "#side" },
|
||||
"west": { "uv": [ 9, 0, 16, 7 ], "texture": "#side" },
|
||||
"east": { "uv": [ 0, 0, 7, 7 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 9, 0, 0 ],
|
||||
"to": [ 16, 7, 7 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 9, 0, 16, 7 ], "texture": "#top" },
|
||||
"down": { "uv": [ 9, 9, 16, 16 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 0, 9, 7, 16 ], "texture": "#side" },
|
||||
"south": { "uv": [ 9, 9, 16, 16 ], "texture": "#side" },
|
||||
"west": { "uv": [ 0, 9, 7, 16 ], "texture": "#side" },
|
||||
"east": { "uv": [ 9, 9, 16, 16 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 9, 0, 9 ],
|
||||
"to": [ 16, 7, 16 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 9, 9, 16, 16 ], "texture": "#top" },
|
||||
"down": { "uv": [ 9, 0, 16, 7 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 0, 9, 7, 16 ], "texture": "#side" },
|
||||
"south": { "uv": [ 9, 9, 16, 16 ], "texture": "#side" },
|
||||
"west": { "uv": [ 9, 9, 16, 16 ], "texture": "#side" },
|
||||
"east": { "uv": [ 0, 9, 7, 16 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 9, 9, 0 ],
|
||||
"to": [ 16, 16, 7 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 9, 0, 16, 7 ], "texture": "#top" },
|
||||
"down": { "uv": [ 9, 9, 16, 16 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 0, 0, 7, 7 ], "texture": "#side" },
|
||||
"south": { "uv": [ 9, 0, 16, 7 ], "texture": "#side" },
|
||||
"west": { "uv": [ 0, 0, 7, 7 ], "texture": "#side" },
|
||||
"east": { "uv": [ 9, 0, 16, 7 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 9, 9, 9 ],
|
||||
"to": [ 16, 16, 16 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 9, 9, 16, 16 ], "texture": "#top" },
|
||||
"down": { "uv": [ 9, 0, 16, 7 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 0, 0, 7, 7 ], "texture": "#side" },
|
||||
"south": { "uv": [ 9, 0, 16, 7 ], "texture": "#side" },
|
||||
"west": { "uv": [ 9, 0, 16, 7 ], "texture": "#side" },
|
||||
"east": { "uv": [ 0, 0, 7, 7 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
|
||||
{ "from": [ 0, 0, 7 ],
|
||||
"to": [ 5, 5, 9 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 0, 7, 5, 9 ], "texture": "#top" },
|
||||
"down": { "uv": [ 0, 7, 5, 9 ], "texture": "#bottom" },
|
||||
"west": { "uv": [ 7, 11, 9, 16 ], "texture": "#side" },
|
||||
"east": { "uv": [ 7, 11, 9, 16 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 0, 11, 7 ],
|
||||
"to": [ 5, 16, 9 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 0, 7, 5, 9 ], "texture": "#top" },
|
||||
"down": { "uv": [ 0, 7, 5, 9 ], "texture": "#bottom" },
|
||||
"west": { "uv": [ 7, 0, 9, 5 ], "texture": "#side" },
|
||||
"east": { "uv": [ 7, 0, 9, 5 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 11, 0, 7 ],
|
||||
"to": [ 16, 5, 9 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 11, 7, 16, 9 ], "texture": "#top" },
|
||||
"down": { "uv": [ 11, 7, 16, 9 ], "texture": "#bottom" },
|
||||
"west": { "uv": [ 7, 11, 9, 16 ], "texture": "#side" },
|
||||
"east": { "uv": [ 7, 11, 9, 16 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 11, 11, 7 ],
|
||||
"to": [ 16, 16, 9 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 11, 7, 16, 9 ], "texture": "#top" },
|
||||
"down": { "uv": [ 11, 7, 16, 9 ], "texture": "#bottom" },
|
||||
"west": { "uv": [ 7, 0, 9, 5 ], "texture": "#side" },
|
||||
"east": { "uv": [ 7, 0, 9, 5 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
|
||||
{ "from": [ 0, 7, 0 ],
|
||||
"to": [ 5, 9, 5 ],
|
||||
"faces": {
|
||||
"north": { "uv": [ 11, 7, 16, 9 ], "texture": "#side" },
|
||||
"south": { "uv": [ 0, 7, 5, 9 ], "texture": "#side" },
|
||||
"west": { "uv": [ 0, 7, 5, 9 ], "texture": "#side" },
|
||||
"east": { "uv": [ 11, 7, 16, 9 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 0, 7, 11 ],
|
||||
"to": [ 5, 9, 16 ],
|
||||
"faces": {
|
||||
"north": { "uv": [ 11, 7, 16, 9 ], "texture": "#side" },
|
||||
"south": { "uv": [ 0, 7, 5, 9 ], "texture": "#side" },
|
||||
"west": { "uv": [ 11, 7, 16, 9 ], "texture": "#side" },
|
||||
"east": { "uv": [ 0, 7, 5, 9 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 11, 7, 0 ],
|
||||
"to": [ 16, 9, 5 ],
|
||||
"faces": {
|
||||
"north": { "uv": [ 0, 7, 5, 9 ], "texture": "#side" },
|
||||
"south": { "uv": [ 11, 7, 16, 9 ], "texture": "#side" },
|
||||
"west": { "uv": [ 0, 7, 5, 9 ], "texture": "#side" },
|
||||
"east": { "uv": [ 11, 7, 16, 9 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 11, 7, 11 ],
|
||||
"to": [ 16, 9, 16 ],
|
||||
"faces": {
|
||||
"north": { "uv": [ 0, 7, 5, 9 ], "texture": "#side" },
|
||||
"south": { "uv": [ 11, 7, 16, 9 ], "texture": "#side" },
|
||||
"west": { "uv": [ 11, 7, 16, 9 ], "texture": "#side" },
|
||||
"east": { "uv": [ 0, 7, 5, 9 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
|
||||
{ "from": [ 7, 0, 0 ],
|
||||
"to": [ 9, 5, 5 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 7, 0, 9, 5 ], "texture": "#top" },
|
||||
"down": { "uv": [ 7, 11, 9, 16 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 7, 11, 9, 16 ], "texture": "#side" },
|
||||
"south": { "uv": [ 7, 11, 9, 16 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 7, 0, 11 ],
|
||||
"to": [ 9, 5, 16 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 7, 11, 9, 16 ], "texture": "#top" },
|
||||
"down": { "uv": [ 7, 0, 9, 5 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 7, 11, 9, 16 ], "texture": "#side" },
|
||||
"south": { "uv": [ 7, 11, 9, 16 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 7, 11, 0 ],
|
||||
"to": [ 9, 16, 5 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 7, 0, 9, 5 ], "texture": "#top" },
|
||||
"down": { "uv": [ 7, 11, 9, 16 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 7, 0, 9, 5 ], "texture": "#side" },
|
||||
"south": { "uv": [ 7, 0, 9, 5 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{ "from": [ 7, 11, 11 ],
|
||||
"to": [ 9, 16, 16 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 7, 11, 9, 16 ], "texture": "#top" },
|
||||
"down": { "uv": [ 7, 0, 9, 5 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 7, 0, 9, 5 ], "texture": "#side" },
|
||||
"south": { "uv": [ 7, 0, 9, 5 ], "texture": "#side" }
|
||||
}
|
||||
},
|
||||
|
||||
{ "from": [ 1, 1, 1 ],
|
||||
"to": [ 15, 15, 15 ],
|
||||
"faces": {
|
||||
"up": { "uv": [ 1, 1, 15, 15 ], "texture": "#top" },
|
||||
"down": { "uv": [ 1, 1, 15, 15 ], "texture": "#bottom" },
|
||||
"north": { "uv": [ 1, 1, 15, 15 ], "texture": "#side" },
|
||||
"south": { "uv": [ 1, 1, 15, 15 ], "texture": "#side" },
|
||||
"west": { "uv": [ 1, 1, 15, 15 ], "texture": "#side" },
|
||||
"east": { "uv": [ 1, 1, 15, 15 ], "texture": "#side" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"parent": "opencomputers:block/relay",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ 10, -45, 170 ],
|
||||
"translation": [ 0, 1.5, -2.75 ],
|
||||
"scale": [ 0.375, 0.375, 0.375 ]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"parent": "opencomputers:block/transposer",
|
||||
"display": {
|
||||
"thirdperson": {
|
||||
"rotation": [ 10, -45, 170 ],
|
||||
"translation": [ 0, 1.5, -2.75 ],
|
||||
"scale": [ 0.375, 0.375, 0.375 ]
|
||||
}
|
||||
}
|
||||
}
|
@ -504,11 +504,6 @@ interweb {
|
||||
[string, string, string]]
|
||||
}
|
||||
|
||||
accessPoint {
|
||||
input: [[ingotIron, "oc:wlanCard", ingotIron]
|
||||
["oc:cable", "oc:lanCard", "oc:cable"]
|
||||
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]
|
||||
}
|
||||
adapter {
|
||||
input: [[ingotIron, "oc:cable", ingotIron]
|
||||
["oc:cable", "oc:circuitChip1", "oc:cable"]
|
||||
@ -607,7 +602,7 @@ powerDistributor {
|
||||
serverRack {
|
||||
input: [["oc:circuitChip2", "oc:wlanCard", "oc:circuitChip2"]
|
||||
[fenceIron, chest, fenceIron]
|
||||
["oc:switch", "oc:materialCircuitBoardPrinted", "oc:powerDistributor"]]
|
||||
["oc:relay", "oc:materialCircuitBoardPrinted", "oc:powerDistributor"]]
|
||||
}
|
||||
raid {
|
||||
input: [[nuggetIron, "oc:cpu3", nuggetIron]
|
||||
@ -619,7 +614,7 @@ redstone {
|
||||
[blockRedstone, "oc:redstoneCard1", blockRedstone]
|
||||
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]
|
||||
}
|
||||
switch {
|
||||
relay {
|
||||
input: [[ingotIron, "oc:cable", ingotIron]
|
||||
["oc:cable", "oc:lanCard", "oc:cable"]
|
||||
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]
|
||||
@ -639,6 +634,12 @@ screen3 {
|
||||
[yellowDust, "oc:circuitChip3", glass]
|
||||
[obsidian, yellowDust, obsidian]]
|
||||
}
|
||||
transposer {
|
||||
input: [[ingotIron, "oc:inventoryControllerUpgrade", ingotIron]
|
||||
[hopper, bucket, hopper]
|
||||
[ingotIron, "oc:tankControllerUpgrade", ingotIron]]
|
||||
output: 4
|
||||
}
|
||||
waypoint {
|
||||
input: [[ingotIron, "oc:circuitChip1", ingotIron]
|
||||
["oc:materialTransistor", "oc:materialInterweb", "oc:materialTransistor"],
|
||||
|
@ -318,7 +318,7 @@ powerDistributor {
|
||||
serverRack {
|
||||
input: [[craftingToolScrewdriver, "oc:wlanCard", craftingToolWrench]
|
||||
["ic2.reactorVentDiamond", chest, "ic2.reactorVentDiamond"]
|
||||
["oc:switch", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]]
|
||||
["oc:relay", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]]
|
||||
}
|
||||
redstone {
|
||||
# 32731 = Activity Detector
|
||||
@ -326,7 +326,7 @@ redstone {
|
||||
[{item="gt.metaitem.01", subID=32731}, {block="gt.blockcasings", subID=2}, "oc:redstoneCard1"]
|
||||
["oc:circuitChip2", "oc:materialCircuitBoardPrinted", "oc:circuitChip2"]]
|
||||
}
|
||||
switch {
|
||||
relay {
|
||||
input: [["", "oc:lanCard", ""]
|
||||
["oc:cable", {block="gt.blockcasings", subID=2}, "oc:cable"]
|
||||
["oc:materialCircuitBoardPrinted", craftingToolWrench, "oc:materialCircuitBoardPrinted"]]
|
||||
|
@ -363,14 +363,14 @@ powerDistributor {
|
||||
serverRack {
|
||||
input: [["oc:circuitChip3", "oc:wlanCard", "oc:circuitChip3"]
|
||||
[fenceIron, chest, fenceIron]
|
||||
["oc:switch", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]]
|
||||
["oc:relay", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]]
|
||||
}
|
||||
redstone {
|
||||
input: [[ingotIron, "oc:circuitChip3", ingotIron]
|
||||
[blockRedstone, "oc:redstoneCard1", blockRedstone]
|
||||
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]
|
||||
}
|
||||
switch {
|
||||
relay {
|
||||
input: [[ingotIron, "oc:cable", ingotIron]
|
||||
["oc:cable", "oc:lanCard", "oc:cable"]
|
||||
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 425 B |
Binary file not shown.
After Width: | Height: | Size: 154 B |
Binary file not shown.
After Width: | Height: | Size: 523 B |
Binary file not shown.
After Width: | Height: | Size: 185 B |
@ -25,12 +25,14 @@ object Constants {
|
||||
final val Keyboard = "keyboard"
|
||||
final val Microcontroller = "microcontroller"
|
||||
final val MotionSensor = "motionSensor"
|
||||
final val NetSplitter = "netSplitter"
|
||||
final val PowerConverter = "powerConverter"
|
||||
final val PowerDistributor = "powerDistributor"
|
||||
final val Print = "print"
|
||||
final val Printer = "printer"
|
||||
final val Raid = "raid"
|
||||
final val Redstone = "redstone"
|
||||
final val Relay = "relay"
|
||||
final val Robot = "robot"
|
||||
final val RobotAfterimage = "robotAfterimage"
|
||||
final val ScreenTier1 = "screen1"
|
||||
@ -38,7 +40,7 @@ object Constants {
|
||||
final val ScreenTier3 = "screen3"
|
||||
final val ServerRack = "serverRack"
|
||||
final val Switch = "switch"
|
||||
final val NetSplitter = "netSplitter"
|
||||
final val Transposer = "transposer"
|
||||
final val Waypoint = "waypoint"
|
||||
|
||||
def Case(tier: Int) = ItemUtils.caseNameWithTierSuffix("case", tier)
|
||||
|
@ -201,6 +201,7 @@ class Settings(val config: Config) {
|
||||
val dataCardComplex = config.getDouble("power.cost.dataCardComplex") max 0
|
||||
val dataCardComplexByte = config.getDouble("power.cost.dataCardComplexByte") max 0
|
||||
val dataCardAsymmetric = config.getDouble("power.cost.dataCardAsymmetric") max 0
|
||||
val transposerCost = config.getDouble("power.cost.transposer") max 0
|
||||
|
||||
// power.rate
|
||||
val accessPointRate = config.getDouble("power.rate.accessPoint") max 0
|
||||
@ -336,6 +337,7 @@ class Settings(val config: Config) {
|
||||
val dataCardHardLimit = config.getInt("misc.dataCardHardLimit") max 0
|
||||
val dataCardTimeout = config.getDouble("misc.dataCardTimeout") max 0
|
||||
val serverRackSwitchTier = (config.getInt("misc.serverRackSwitchTier") - 1) max Tier.None min Tier.Three
|
||||
val redstoneDelay = config.getDouble("misc.redstoneDelay") max 0
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// printer
|
||||
|
@ -36,12 +36,14 @@ object GuiHandler extends CommonGuiHandler {
|
||||
new gui.DiskDrive(player.inventory, t)
|
||||
case t: tileentity.Printer if id == GuiType.Printer.id =>
|
||||
new gui.Printer(player.inventory, t)
|
||||
case t: tileentity.Raid if id == GuiType.Raid.id =>
|
||||
new gui.Raid(player.inventory, t)
|
||||
case t: tileentity.RobotProxy if id == GuiType.Robot.id =>
|
||||
new gui.Robot(player.inventory, t.robot)
|
||||
case t: tileentity.ServerRack if id == GuiType.Rack.id =>
|
||||
new gui.ServerRack(player.inventory, t)
|
||||
case t: tileentity.Raid if id == GuiType.Raid.id =>
|
||||
new gui.Raid(player.inventory, t)
|
||||
case t: tileentity.Relay if id == GuiType.Relay.id =>
|
||||
new gui.Relay(player.inventory, t)
|
||||
case t: tileentity.RobotProxy if id == GuiType.Robot.id =>
|
||||
new gui.Robot(player.inventory, t.robot)
|
||||
case t: tileentity.Screen if id == GuiType.Screen.id =>
|
||||
new gui.Screen(t.origin.buffer, t.tier > 0, () => t.origin.hasKeyboard, () => t.origin.buffer.isRenderingEnabled)
|
||||
case t: tileentity.Switch if id == GuiType.Switch.id =>
|
||||
|
@ -81,6 +81,7 @@ object PacketHandler extends CommonPacketHandler {
|
||||
case PacketType.ServerPresence => onServerPresence(p)
|
||||
case PacketType.Sound => onSound(p)
|
||||
case PacketType.SoundPattern => onSoundPattern(p)
|
||||
case PacketType.TransposerActivity => onTransposerActivity(p)
|
||||
case PacketType.WaypointLabel => onWaypointLabel(p)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
@ -260,6 +261,15 @@ object PacketHandler extends CommonPacketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
def onNetSplitterState(p: PacketParser) =
|
||||
p.readTileEntity[NetSplitter]() match {
|
||||
case Some(t) =>
|
||||
t.isInverted = p.readBoolean()
|
||||
t.openSides = t.uncompressSides(p.readByte())
|
||||
t.world.markBlockForUpdate(t.getPos)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onParticleEffect(p: PacketParser) = {
|
||||
val dimension = p.readInt()
|
||||
world(p.player, dimension) match {
|
||||
@ -420,7 +430,7 @@ object PacketHandler extends CommonPacketHandler {
|
||||
}
|
||||
|
||||
def onSwitchActivity(p: PacketParser) =
|
||||
p.readTileEntity[Switch]() match {
|
||||
p.readTileEntity[traits.SwitchLike]() match {
|
||||
case Some(t) => t.lastMessage = System.currentTimeMillis()
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
@ -589,15 +599,6 @@ object PacketHandler extends CommonPacketHandler {
|
||||
buffer.rawSetForeground(col, row, color)
|
||||
}
|
||||
|
||||
def onNetSplitterState(p: PacketParser) =
|
||||
p.readTileEntity[NetSplitter]() match {
|
||||
case Some(t) =>
|
||||
t.isInverted = p.readBoolean()
|
||||
t.openSides = t.uncompressSides(p.readByte())
|
||||
t.world.markBlockForUpdate(t.getPos)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onScreenTouchMode(p: PacketParser) =
|
||||
p.readTileEntity[Screen]() match {
|
||||
case Some(t) => t.invertTouchMode = p.readBoolean()
|
||||
@ -638,6 +639,12 @@ object PacketHandler extends CommonPacketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
def onTransposerActivity(p: PacketParser) =
|
||||
p.readTileEntity[Transposer]() match {
|
||||
case Some(transposer) => transposer.lastOperation = System.currentTimeMillis()
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onWaypointLabel(p: PacketParser) =
|
||||
p.readTileEntity[Waypoint]() match {
|
||||
case Some(waypoint) => waypoint.label = p.readUTF()
|
||||
|
@ -63,15 +63,17 @@ private[oc] class Proxy extends CommonProxy {
|
||||
else
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Hologram], HologramRendererFallback)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Microcontroller], MicrocontrollerRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.NetSplitter], NetSplitterRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.PowerDistributor], PowerDistributorRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Printer], PrinterRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Raid], RaidRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.ServerRack], ServerRackRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Switch], SwitchRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.AccessPoint], SwitchRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Relay], SwitchRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.RobotProxy], RobotRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Screen], ScreenRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.NetSplitter], NetSplitterRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Transposer], TransposerRenderer)
|
||||
|
||||
ClientRegistry.registerKeyBinding(KeyBindings.materialCosts)
|
||||
ClientRegistry.registerKeyBinding(KeyBindings.clipboardPaste)
|
||||
|
@ -59,6 +59,7 @@ object Textures {
|
||||
val RobotSelection = L("robot_selection")
|
||||
val Server = L("server")
|
||||
val Slot = L("slot")
|
||||
val UpgradeTab = L("upgrade_tab")
|
||||
val Waypoint = L("waypoint")
|
||||
|
||||
override protected def basePath = "textures/gui/%s.png"
|
||||
@ -142,6 +143,7 @@ object Textures {
|
||||
val RaidFrontError = L("overlay/raid_front_error")
|
||||
val ScreenUpIndicator = L("overlay/screen_up_indicator")
|
||||
val SwitchSideOn = L("overlay/switch_side_on")
|
||||
val TransposerOn = L("overlay/transposer_on")
|
||||
|
||||
val Cable = L("cable")
|
||||
val CableCap = L("cableCap")
|
||||
|
123
src/main/scala/li/cil/oc/client/gui/Relay.scala
Normal file
123
src/main/scala/li/cil/oc/client/gui/Relay.scala
Normal file
@ -0,0 +1,123 @@
|
||||
package li.cil.oc.client.gui
|
||||
|
||||
import java.lang.Iterable
|
||||
import java.text.DecimalFormat
|
||||
import java.util
|
||||
|
||||
import codechicken.nei.VisiblityData
|
||||
import codechicken.nei.api.INEIGuiHandler
|
||||
import codechicken.nei.api.TaggedInventoryArea
|
||||
import li.cil.oc.Localization
|
||||
import li.cil.oc.client.Textures
|
||||
import li.cil.oc.common.container
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.Mods
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.inventory.GuiContainer
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraftforge.fml.common.Optional
|
||||
import org.lwjgl.opengl.GL11
|
||||
import org.lwjgl.util.Rectangle
|
||||
|
||||
@Optional.Interface(iface = "codechicken.nei.api.INEIGuiHandler", modid = Mods.IDs.NotEnoughItems)
|
||||
class Relay(playerInventory: InventoryPlayer, val relay: tileentity.Relay) extends DynamicGuiContainer(new container.Relay(playerInventory, relay)) with INEIGuiHandler {
|
||||
private val format = new DecimalFormat("#.##hz")
|
||||
|
||||
private val tabPosition = new Rectangle(xSize, 10, 23, 26)
|
||||
|
||||
override protected def drawSecondaryBackgroundLayer(): Unit = {
|
||||
super.drawSecondaryBackgroundLayer()
|
||||
|
||||
// Tab background.
|
||||
GL11.glColor4f(1, 1, 1, 1)
|
||||
Minecraft.getMinecraft.getTextureManager.bindTexture(Textures.GUI.UpgradeTab)
|
||||
val x = windowX + tabPosition.getX
|
||||
val y = windowY + tabPosition.getY
|
||||
val w = tabPosition.getWidth
|
||||
val h = tabPosition.getHeight
|
||||
val t = Tessellator.getInstance
|
||||
val r = t.getWorldRenderer
|
||||
r.startDrawingQuads()
|
||||
r.addVertexWithUV(x, y + h, zLevel, 0, 1)
|
||||
r.addVertexWithUV(x + w, y + h, zLevel, 1, 1)
|
||||
r.addVertexWithUV(x + w, y, zLevel, 1, 0)
|
||||
r.addVertexWithUV(x, y, zLevel, 0, 0)
|
||||
t.draw()
|
||||
}
|
||||
|
||||
override def mouseClicked(mouseX: Int, mouseY: Int, button: Int): Unit = {
|
||||
// So MC doesn't throw away the item in the upgrade slot when we're trying to pick it up...
|
||||
val originalWidth = xSize
|
||||
try {
|
||||
xSize += tabPosition.getWidth
|
||||
super.mouseClicked(mouseX, mouseY, button)
|
||||
}
|
||||
finally {
|
||||
xSize = originalWidth
|
||||
}
|
||||
}
|
||||
|
||||
override def mouseReleased(mouseX: Int, mouseY: Int, button: Int): Unit = {
|
||||
// So MC doesn't throw away the item in the upgrade slot when we're trying to pick it up...
|
||||
val originalWidth = xSize
|
||||
try {
|
||||
xSize += tabPosition.getWidth
|
||||
super.mouseReleased(mouseX, mouseY, button)
|
||||
}
|
||||
finally {
|
||||
xSize = originalWidth
|
||||
}
|
||||
}
|
||||
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately(relay.getName),
|
||||
8, 6, 0x404040)
|
||||
|
||||
fontRendererObj.drawString(
|
||||
Localization.Switch.TransferRate,
|
||||
14, 20, 0x404040)
|
||||
fontRendererObj.drawString(
|
||||
Localization.Switch.PacketsPerCycle,
|
||||
14, 39, 0x404040)
|
||||
fontRendererObj.drawString(
|
||||
Localization.Switch.QueueSize,
|
||||
14, 58, 0x404040)
|
||||
|
||||
fontRendererObj.drawString(
|
||||
format.format(20f / inventoryContainer.relayDelay),
|
||||
108, 20, 0x404040)
|
||||
fontRendererObj.drawString(
|
||||
inventoryContainer.packetsPerCycleAvg + " / " + inventoryContainer.relayAmount,
|
||||
108, 39, thresholdBasedColor(inventoryContainer.packetsPerCycleAvg, math.ceil(inventoryContainer.relayAmount / 2f).toInt, inventoryContainer.relayAmount))
|
||||
fontRendererObj.drawString(
|
||||
inventoryContainer.queueSize + " / " + inventoryContainer.maxQueueSize,
|
||||
108, 58, thresholdBasedColor(inventoryContainer.queueSize, inventoryContainer.maxQueueSize / 2, inventoryContainer.maxQueueSize))
|
||||
}
|
||||
|
||||
private def thresholdBasedColor(value: Int, yellow: Int, red: Int) = {
|
||||
if (value < yellow) 0x009900
|
||||
else if (value < red) 0x999900
|
||||
else 0x990000
|
||||
}
|
||||
|
||||
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
|
||||
override def modifyVisiblity(gui: GuiContainer, currentVisibility: VisiblityData): VisiblityData = null
|
||||
|
||||
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
|
||||
override def getItemSpawnSlots(gui: GuiContainer, stack: ItemStack): Iterable[Integer] = null
|
||||
|
||||
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
|
||||
override def getInventoryAreas(gui: GuiContainer): util.List[TaggedInventoryArea] = null
|
||||
|
||||
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
|
||||
override def handleDragNDrop(gui: GuiContainer, mouseX: Int, mouseY: Int, stack: ItemStack, button: Int): Boolean = false
|
||||
|
||||
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
|
||||
override def hideItemPanelSlot(gui: GuiContainer, x: Int, y: Int, w: Int, h: Int): Boolean = {
|
||||
new Rectangle(x - windowX, y - windowY, w, h).intersects(tabPosition)
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import li.cil.oc.common.container
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
|
||||
// TODO Remove in 1.7
|
||||
class Switch(playerInventory: InventoryPlayer, val switch: tileentity.Switch) extends DynamicGuiContainer(new container.Switch(playerInventory, switch)) {
|
||||
private val format = new DecimalFormat("#.##hz")
|
||||
|
||||
|
@ -12,7 +12,7 @@ object SwitchRenderer extends TileEntitySpecialRenderer {
|
||||
override def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, f: Float, damage: Int) {
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||
|
||||
val switch = tileEntity.asInstanceOf[tileentity.Switch]
|
||||
val switch = tileEntity.asInstanceOf[tileentity.traits.SwitchLike]
|
||||
val activity = math.max(0, 1 - (System.currentTimeMillis() - switch.lastMessage) / 1000.0)
|
||||
if (activity > 0) {
|
||||
RenderState.pushAttrib()
|
||||
|
@ -0,0 +1,78 @@
|
||||
package li.cil.oc.client.renderer.tileentity
|
||||
|
||||
import li.cil.oc.client.Textures
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.util.RenderState
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.client.renderer.texture.TextureMap
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
object TransposerRenderer extends TileEntitySpecialRenderer {
|
||||
override def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, f: Float, damage: Int) {
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||
|
||||
val transposer = tileEntity.asInstanceOf[tileentity.Transposer]
|
||||
val activity = math.max(0, 1 - (System.currentTimeMillis() - transposer.lastOperation) / 1000.0)
|
||||
if (activity > 0) {
|
||||
RenderState.pushAttrib()
|
||||
|
||||
RenderState.disableEntityLighting()
|
||||
RenderState.makeItBlend()
|
||||
RenderState.setBlendAlpha(activity.toFloat)
|
||||
|
||||
RenderState.pushMatrix()
|
||||
|
||||
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||
GL11.glScaled(1.0025, -1.0025, 1.0025)
|
||||
GL11.glTranslatef(-0.5f, -0.5f, -0.5f)
|
||||
|
||||
val t = Tessellator.getInstance
|
||||
val r = t.getWorldRenderer
|
||||
|
||||
Textures.Block.bind()
|
||||
r.startDrawingQuads()
|
||||
|
||||
val icon = Textures.getSprite(Textures.Block.TransposerOn)
|
||||
r.addVertexWithUV(0, 1, 0, icon.getMaxU, icon.getMinV)
|
||||
r.addVertexWithUV(1, 1, 0, icon.getMinU, icon.getMinV)
|
||||
r.addVertexWithUV(1, 1, 1, icon.getMinU, icon.getMaxV)
|
||||
r.addVertexWithUV(0, 1, 1, icon.getMaxU, icon.getMaxV)
|
||||
|
||||
r.addVertexWithUV(0, 0, 0, icon.getMaxU, icon.getMaxV)
|
||||
r.addVertexWithUV(0, 0, 1, icon.getMaxU, icon.getMinV)
|
||||
r.addVertexWithUV(1, 0, 1, icon.getMinU, icon.getMinV)
|
||||
r.addVertexWithUV(1, 0, 0, icon.getMinU, icon.getMaxV)
|
||||
|
||||
r.addVertexWithUV(1, 1, 0, icon.getMinU, icon.getMaxV)
|
||||
r.addVertexWithUV(0, 1, 0, icon.getMaxU, icon.getMaxV)
|
||||
r.addVertexWithUV(0, 0, 0, icon.getMaxU, icon.getMinV)
|
||||
r.addVertexWithUV(1, 0, 0, icon.getMinU, icon.getMinV)
|
||||
|
||||
r.addVertexWithUV(0, 1, 1, icon.getMinU, icon.getMaxV)
|
||||
r.addVertexWithUV(1, 1, 1, icon.getMaxU, icon.getMaxV)
|
||||
r.addVertexWithUV(1, 0, 1, icon.getMaxU, icon.getMinV)
|
||||
r.addVertexWithUV(0, 0, 1, icon.getMinU, icon.getMinV)
|
||||
|
||||
r.addVertexWithUV(0, 1, 0, icon.getMinU, icon.getMaxV)
|
||||
r.addVertexWithUV(0, 1, 1, icon.getMaxU, icon.getMaxV)
|
||||
r.addVertexWithUV(0, 0, 1, icon.getMaxU, icon.getMinV)
|
||||
r.addVertexWithUV(0, 0, 0, icon.getMinU, icon.getMinV)
|
||||
|
||||
r.addVertexWithUV(1, 1, 1, icon.getMinU, icon.getMaxV)
|
||||
r.addVertexWithUV(1, 1, 0, icon.getMaxU, icon.getMaxV)
|
||||
r.addVertexWithUV(1, 0, 0, icon.getMaxU, icon.getMinV)
|
||||
r.addVertexWithUV(1, 0, 1, icon.getMinU, icon.getMinV)
|
||||
|
||||
t.draw()
|
||||
|
||||
RenderState.enableEntityLighting()
|
||||
|
||||
RenderState.popMatrix()
|
||||
RenderState.popAttrib()
|
||||
}
|
||||
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
|
||||
}
|
||||
}
|
@ -30,6 +30,8 @@ abstract class GuiHandler extends IGuiHandler {
|
||||
new container.Printer(player.inventory, t)
|
||||
case t: tileentity.Raid if id == GuiType.Raid.id =>
|
||||
new container.Raid(player.inventory, t)
|
||||
case t: tileentity.Relay if id == GuiType.Relay.id =>
|
||||
new container.Relay(player.inventory, t)
|
||||
case t: tileentity.RobotProxy if id == GuiType.Robot.id =>
|
||||
new container.Robot(player.inventory, t.robot)
|
||||
case t: tileentity.ServerRack if id == GuiType.Rack.id =>
|
||||
|
@ -28,6 +28,7 @@ object GuiType extends ScalaEnum {
|
||||
val Printer = new EnumVal { def name = "Printer"; def subType = GuiType.Category.Block }
|
||||
val Rack = new EnumVal { def name = "Rack"; def subType = GuiType.Category.Block }
|
||||
val Raid = new EnumVal { def name = "Raid"; def subType = GuiType.Category.Block }
|
||||
val Relay = new EnumVal { def name = "Relay"; def subType = GuiType.Category.Block }
|
||||
val Robot = new EnumVal { def name = "Robot"; def subType = GuiType.Category.Block }
|
||||
val Screen = new EnumVal { def name = "Screen"; def subType = GuiType.Category.Block }
|
||||
val Server = new EnumVal { def name = "Server"; def subType = GuiType.Category.Item }
|
||||
|
@ -120,6 +120,13 @@ object InventorySlots {
|
||||
)
|
||||
)
|
||||
|
||||
val relay = Array(
|
||||
InventorySlot(Slot.CPU, Tier.Three),
|
||||
InventorySlot(Slot.Memory, Tier.Three),
|
||||
InventorySlot(Slot.HDD, Tier.Three),
|
||||
InventorySlot(Slot.Card, Tier.Three)
|
||||
)
|
||||
|
||||
val switch = Array(
|
||||
InventorySlot(Slot.CPU, Tier.Three),
|
||||
InventorySlot(Slot.Memory, Tier.Three),
|
||||
|
@ -20,6 +20,7 @@ object PacketType extends Enumeration {
|
||||
HologramTranslation,
|
||||
HologramValues,
|
||||
LootDisk,
|
||||
NetSplitterState,
|
||||
ParticleEffect,
|
||||
PetVisibility, // Goes both ways.
|
||||
PowerState,
|
||||
@ -49,11 +50,11 @@ object PacketType extends Enumeration {
|
||||
TextBufferMultiRawSetBackground,
|
||||
TextBufferMultiRawSetForeground,
|
||||
TextBufferPowerChange,
|
||||
NetSplitterState,
|
||||
ScreenTouchMode,
|
||||
ServerPresence,
|
||||
Sound,
|
||||
SoundPattern,
|
||||
TransposerActivity,
|
||||
WaypointLabel, // Goes both ways.
|
||||
|
||||
// Client -> Server
|
||||
|
@ -4,6 +4,7 @@ import li.cil.oc.Settings
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.world.World
|
||||
|
||||
// TODO Remove in 1.7
|
||||
class AccessPoint extends Switch with traits.PowerAcceptor {
|
||||
override def energyThroughput = Settings.get.accessPointRate
|
||||
|
||||
|
17
src/main/scala/li/cil/oc/common/block/Relay.scala
Normal file
17
src/main/scala/li/cil/oc/common/block/Relay.scala
Normal file
@ -0,0 +1,17 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Relay extends SimpleBlock with traits.GUI with traits.PowerAcceptor {
|
||||
override def guiType = GuiType.Relay
|
||||
|
||||
override def energyThroughput = Settings.get.accessPointRate
|
||||
|
||||
override def hasTileEntity(state: IBlockState) = true
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Relay()
|
||||
}
|
@ -5,6 +5,7 @@ import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.world.World
|
||||
|
||||
// TODO Remove in 1.7
|
||||
class Switch extends SimpleBlock with traits.GUI {
|
||||
override def guiType = GuiType.Switch
|
||||
|
||||
|
18
src/main/scala/li/cil/oc/common/block/Transposer.scala
Normal file
18
src/main/scala/li/cil/oc/common/block/Transposer.scala
Normal file
@ -0,0 +1,18 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Transposer extends SimpleBlock {
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = false
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def hasTileEntity(state: IBlockState): Boolean = true
|
||||
|
||||
override def createNewTileEntity(world: World, meta: Int) = new tileentity.Transposer()
|
||||
}
|
33
src/main/scala/li/cil/oc/common/container/Relay.scala
Normal file
33
src/main/scala/li/cil/oc/common/container/Relay.scala
Normal file
@ -0,0 +1,33 @@
|
||||
package li.cil.oc.common.container
|
||||
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class Relay(playerInventory: InventoryPlayer, relay: tileentity.Relay) extends Player(playerInventory, relay) {
|
||||
addSlotToContainer(151, 15, Slot.CPU)
|
||||
addSlotToContainer(151, 34, Slot.Memory)
|
||||
addSlotToContainer(151, 53, Slot.HDD)
|
||||
addSlotToContainer(178, 15, Slot.Card)
|
||||
addPlayerInventorySlots(8, 84)
|
||||
|
||||
def relayDelay = synchronizedData.getInteger("relayDelay")
|
||||
|
||||
def relayAmount = synchronizedData.getInteger("relayAmount")
|
||||
|
||||
def maxQueueSize = synchronizedData.getInteger("maxQueueSize")
|
||||
|
||||
def packetsPerCycleAvg = synchronizedData.getInteger("packetsPerCycleAvg")
|
||||
|
||||
def queueSize = synchronizedData.getInteger("queueSize")
|
||||
|
||||
override protected def detectCustomDataChanges(nbt: NBTTagCompound): Unit = {
|
||||
synchronizedData.setInteger("relayDelay", relay.relayDelay)
|
||||
synchronizedData.setInteger("relayAmount", relay.relayAmount)
|
||||
synchronizedData.setInteger("maxQueueSize", relay.maxQueueSize)
|
||||
synchronizedData.setInteger("packetsPerCycleAvg", relay.packetsPerCycleAvg())
|
||||
synchronizedData.setInteger("queueSize", relay.queue.size)
|
||||
super.detectCustomDataChanges(nbt)
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import li.cil.oc.common.tileentity
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
// TODO Remove in 1.7
|
||||
class Switch(playerInventory: InventoryPlayer, switch: tileentity.Switch) extends Player(playerInventory, switch) {
|
||||
addSlotToContainer(151, 15, Slot.CPU)
|
||||
addSlotToContainer(151, 34, Slot.Memory)
|
||||
|
@ -24,20 +24,22 @@ object Blocks {
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Geolyzer], Settings.namespace + "geolyzer")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Microcontroller], Settings.namespace + "microcontroller")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.MotionSensor], Settings.namespace + "motionSensor")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.NetSplitter], Settings.namespace + "netSplitter")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.PowerConverter], Settings.namespace + "powerConverter")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.PowerDistributor], Settings.namespace + "powerDistributor")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Print], Settings.namespace + "print")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Printer], Settings.namespace + "printer")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Raid], Settings.namespace + "raid")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Redstone], Settings.namespace + "redstone")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Relay], Settings.namespace + "relay")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.RobotProxy], Settings.namespace + "robot")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Switch], Settings.namespace + "switch")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Screen], Settings.namespace + "screen")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.ServerRack], Settings.namespace + "serverRack")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.NetSplitter], Settings.namespace + "netSplitter")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Transposer], Settings.namespace + "transposer")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Waypoint], Settings.namespace + "waypoint")
|
||||
|
||||
Recipes.addBlock(new AccessPoint(), Constants.BlockName.AccessPoint, "oc:accessPoint")
|
||||
Items.registerBlock(new AccessPoint(), Constants.BlockName.AccessPoint)
|
||||
Recipes.addBlock(new Adapter(), Constants.BlockName.Adapter, "oc:adapter")
|
||||
Recipes.addBlock(new Assembler(), Constants.BlockName.Assembler, "oc:assembler")
|
||||
Recipes.addBlock(new Cable(), Constants.BlockName.Cable, "oc:cable")
|
||||
@ -59,11 +61,12 @@ object Blocks {
|
||||
Recipes.addBlock(new Printer(), Constants.BlockName.Printer, "oc:printer")
|
||||
Recipes.addBlock(new Raid(), Constants.BlockName.Raid, "oc:raid")
|
||||
Recipes.addBlock(new Redstone(), Constants.BlockName.Redstone, "oc:redstone")
|
||||
Recipes.addBlock(new Relay(), Constants.BlockName.Relay, "oc:relay")
|
||||
Recipes.addBlock(new Screen(Tier.One), Constants.BlockName.ScreenTier1, "oc:screen1")
|
||||
Recipes.addBlock(new Screen(Tier.Three), Constants.BlockName.ScreenTier3, "oc:screen3")
|
||||
Recipes.addBlock(new Screen(Tier.Two), Constants.BlockName.ScreenTier2, "oc:screen2")
|
||||
Recipes.addBlock(new ServerRack(), Constants.BlockName.ServerRack, "oc:serverRack")
|
||||
Recipes.addBlock(new Switch(), Constants.BlockName.Switch, "oc:switch")
|
||||
Items.registerBlock(new Switch(), Constants.BlockName.Switch)
|
||||
Recipes.addBlock(new Waypoint(), Constants.BlockName.Waypoint, "oc:waypoint")
|
||||
|
||||
Items.registerBlock(new Case(Tier.Four), Constants.BlockName.CaseCreative)
|
||||
@ -77,5 +80,8 @@ object Blocks {
|
||||
|
||||
// v1.5.14
|
||||
Recipes.addBlock(new NetSplitter(), Constants.BlockName.NetSplitter, "oc:netSplitter")
|
||||
|
||||
// v1.5.16
|
||||
Recipes.addBlock(new Transposer(), Constants.BlockName.Transposer, "oc:transposer")
|
||||
}
|
||||
}
|
||||
|
@ -241,9 +241,11 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp
|
||||
|
||||
override def facing = RotationHelper.fromYaw(player.rotationYaw)
|
||||
|
||||
override def toLocal(value: EnumFacing) = value // -T-O-D-O- do we care? no we don't
|
||||
override def toLocal(value: EnumFacing) =
|
||||
RotationHelper.toLocal(EnumFacing.NORTH, facing, value)
|
||||
|
||||
override def toGlobal(value: EnumFacing) = value // -T-O-D-O- do we care? no we don't
|
||||
override def toGlobal(value: EnumFacing) =
|
||||
RotationHelper.toGlobal(EnumFacing.NORTH, facing, value)
|
||||
|
||||
def readFromNBT() {
|
||||
if (stack.hasTagCompound) {
|
||||
|
@ -3,12 +3,10 @@ package li.cil.oc.common.item.traits
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.machine.Architecture
|
||||
import li.cil.oc.integration.opencomputers.DriverCPU
|
||||
import li.cil.oc.util.Tooltip
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.ChatComponentTranslation
|
||||
import net.minecraft.world.World
|
||||
|
||||
@ -21,37 +19,19 @@ trait CPULike extends Delegate {
|
||||
override protected def tooltipData: Seq[Any] = Seq(Settings.get.cpuComponentSupport(cpuTier))
|
||||
|
||||
override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) {
|
||||
(if (stack.hasTagCompound) {
|
||||
Option(stack.getTagCompound.getString(Settings.namespace + "archName"))
|
||||
}
|
||||
else {
|
||||
val architectures = allArchitectures
|
||||
architectures.headOption.map(_._2)
|
||||
}) match {
|
||||
case Some(archName) if !archName.isEmpty => tooltip.addAll(Tooltip.get("CPU.Architecture", archName))
|
||||
case _ => allArchitectures.headOption.collect {
|
||||
case ((_, name)) => tooltip.addAll(Tooltip.get("CPU.Architecture", name))
|
||||
}
|
||||
}
|
||||
tooltip.addAll(Tooltip.get("CPU.Architecture", DriverCPU.getArchitectureName(DriverCPU.architecture(stack))))
|
||||
}
|
||||
|
||||
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = {
|
||||
if (player.isSneaking) {
|
||||
if (!world.isRemote) {
|
||||
val architectures = allArchitectures
|
||||
if (architectures.length > 0) {
|
||||
val currentIndex = if (stack.hasTagCompound) {
|
||||
val currentArch = stack.getTagCompound.getString(Settings.namespace + "archClass")
|
||||
architectures.indexWhere(_._1.getName == currentArch)
|
||||
}
|
||||
else {
|
||||
stack.setTagCompound(new NBTTagCompound())
|
||||
-1
|
||||
}
|
||||
val index = (currentIndex + 1) % architectures.length
|
||||
val (archClass, archName) = architectures(index)
|
||||
stack.getTagCompound.setString(Settings.namespace + "archClass", archClass.getName)
|
||||
stack.getTagCompound.setString(Settings.namespace + "archName", archName)
|
||||
val architectures = DriverCPU.allArchitectures.toList
|
||||
if (architectures.nonEmpty) {
|
||||
val currentIndex = architectures.indexOf(DriverCPU.architecture(stack))
|
||||
val newIndex = (currentIndex + 1) % architectures.length
|
||||
val archClass = architectures(newIndex)
|
||||
val archName = DriverCPU.getArchitectureName(archClass)
|
||||
DriverCPU.setArchitecture(stack, archClass)
|
||||
player.addChatMessage(new ChatComponentTranslation(Settings.namespace + "tooltip.CPU.Architecture", archName))
|
||||
}
|
||||
player.swingItem()
|
||||
@ -59,11 +39,4 @@ trait CPULike extends Delegate {
|
||||
}
|
||||
stack
|
||||
}
|
||||
|
||||
private def allArchitectures = api.Machine.architectures.map { arch =>
|
||||
arch.getAnnotation(classOf[Architecture.Name]) match {
|
||||
case annotation: Architecture.Name => (arch, annotation.value)
|
||||
case _ => (arch, arch.getSimpleName)
|
||||
}
|
||||
}.toArray
|
||||
}
|
||||
|
@ -326,6 +326,12 @@ object Recipes {
|
||||
GameRegistry.addRecipe(new ExtendedShapelessOreRecipe(
|
||||
lightPrint,
|
||||
print.createItemStack(1), new ItemStack(net.minecraft.init.Blocks.glowstone)))
|
||||
|
||||
// Switch/AccessPoint -> Relay conversion
|
||||
GameRegistry.addShapelessRecipe(api.Items.get(Constants.BlockName.Relay).createItemStack(1),
|
||||
api.Items.get(Constants.BlockName.AccessPoint).createItemStack(1))
|
||||
GameRegistry.addShapelessRecipe(api.Items.get(Constants.BlockName.Relay).createItemStack(1),
|
||||
api.Items.get(Constants.BlockName.Switch).createItemStack(1))
|
||||
}
|
||||
catch {
|
||||
case e: Throwable => OpenComputers.log.error("Error parsing recipes, you may not be able to craft any items from this mod!", e)
|
||||
|
@ -15,6 +15,7 @@ import net.minecraftforge.common.util.Constants.NBT
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
|
||||
// TODO Remove in 1.7
|
||||
class AccessPoint extends Switch with WirelessEndpoint with traits.PowerAcceptor {
|
||||
var strength = Settings.get.maxWirelessRange
|
||||
|
||||
@ -24,6 +25,8 @@ class AccessPoint extends Switch with WirelessEndpoint with traits.PowerAcceptor
|
||||
withComponent("access_point").
|
||||
create())
|
||||
|
||||
override def isWirelessEnabled = true
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@ -71,7 +74,7 @@ class AccessPoint extends Switch with WirelessEndpoint with traits.PowerAcceptor
|
||||
|
||||
override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet) {
|
||||
super.relayPacket(sourceSide, packet)
|
||||
if (strength > 0 && (sourceSide != None || isRepeater)) {
|
||||
if (strength > 0 && (sourceSide.isDefined || isRepeater)) {
|
||||
val cost = Settings.get.wirelessCostPerRange
|
||||
val tryChangeBuffer = sourceSide match {
|
||||
case Some(side) =>
|
||||
|
282
src/main/scala/li/cil/oc/common/tileentity/Relay.scala
Normal file
282
src/main/scala/li/cil/oc/common/tileentity/Relay.scala
Normal file
@ -0,0 +1,282 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
import li.cil.oc.Constants
|
||||
import li.cil.oc.Localization
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.Driver
|
||||
import li.cil.oc.api.machine.Arguments
|
||||
import li.cil.oc.api.machine.Callback
|
||||
import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.api.network.Analyzable
|
||||
import li.cil.oc.api.network.Connector
|
||||
import li.cil.oc.api.network.Node
|
||||
import li.cil.oc.api.network.Packet
|
||||
import li.cil.oc.api.network.Visibility
|
||||
import li.cil.oc.api.network.WirelessEndpoint
|
||||
import li.cil.oc.common.InventorySlots
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.item
|
||||
import li.cil.oc.common.item.Delegator
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.opencomputers.DriverLinkedCard
|
||||
import li.cil.oc.server.network.QuantumNetwork
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
|
||||
class Relay extends traits.SwitchLike with traits.ComponentInventory with traits.PowerAcceptor with Analyzable with WirelessEndpoint with QuantumNetwork.QuantumNode {
|
||||
lazy final val WirelessNetworkCard = api.Items.get(Constants.ItemName.WirelessNetworkCard)
|
||||
lazy final val LinkedCard = api.Items.get(Constants.ItemName.LinkedCard)
|
||||
|
||||
var strength = Settings.get.maxWirelessRange
|
||||
|
||||
var isRepeater = true
|
||||
|
||||
var isWirelessEnabled = false
|
||||
|
||||
var isLinkedEnabled = false
|
||||
|
||||
var tunnel = "creative"
|
||||
|
||||
val componentNodes = Array.fill(6)(api.Network.newNode(this, Visibility.Network).
|
||||
withComponent("relay").
|
||||
create())
|
||||
|
||||
override def canUpdate = isServer
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override protected def hasConnector(side: EnumFacing) = true
|
||||
|
||||
override protected def connector(side: EnumFacing) = sidedNode(side) match {
|
||||
case connector: Connector => Option(connector)
|
||||
case _ => None
|
||||
}
|
||||
|
||||
override def energyThroughput = Settings.get.accessPointRate
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = {
|
||||
if (isWirelessEnabled) {
|
||||
player.addChatMessage(Localization.Analyzer.WirelessStrength(strength))
|
||||
Array(componentNodes(side.getIndex))
|
||||
}
|
||||
else null
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@Callback(direct = true, doc = """function():number -- Get the signal strength (range) used when relaying messages.""")
|
||||
def getStrength(context: Context, args: Arguments): Array[AnyRef] = synchronized(result(strength))
|
||||
|
||||
@Callback(doc = """function(strength:number):number -- Set the signal strength (range) used when relaying messages.""")
|
||||
def setStrength(context: Context, args: Arguments): Array[AnyRef] = synchronized {
|
||||
strength = math.max(args.checkDouble(0), math.min(0, Settings.get.maxWirelessRange))
|
||||
result(strength)
|
||||
}
|
||||
|
||||
@Callback(direct = true, doc = """function():boolean -- Get whether the access point currently acts as a repeater (resend received wireless packets wirelessly).""")
|
||||
def isRepeater(context: Context, args: Arguments): Array[AnyRef] = synchronized(result(isRepeater))
|
||||
|
||||
@Callback(doc = """function(enabled:boolean):boolean -- Set whether the access point should act as a repeater.""")
|
||||
def setRepeater(context: Context, args: Arguments): Array[AnyRef] = synchronized {
|
||||
isRepeater = args.checkBoolean(0)
|
||||
result(isRepeater)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
protected def queueMessage(source: String, destination: String, port: Int, answerPort: Int, args: Array[AnyRef]) {
|
||||
/* TODO ComputerCraft
|
||||
for (computer <- computers.map(_.asInstanceOf[IComputerAccess])) {
|
||||
val address = s"cc${computer.getID}_${computer.getAttachmentName}"
|
||||
if (source != address && Option(destination).forall(_ == address) && openPorts(computer).contains(port))
|
||||
computer.queueEvent("modem_message", Array(Seq(computer.getAttachmentName, Int.box(port), Int.box(answerPort)) ++ args.map {
|
||||
case x: Array[Byte] => new String(x, Charsets.UTF_8)
|
||||
case x => x
|
||||
}: _*))
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def receivePacket(packet: Packet, source: WirelessEndpoint): Unit = {
|
||||
if (isWirelessEnabled) {
|
||||
tryEnqueuePacket(None, packet)
|
||||
}
|
||||
}
|
||||
|
||||
override def receivePacket(packet: Packet): Unit = {
|
||||
if (isLinkedEnabled) {
|
||||
tryEnqueuePacket(None, packet)
|
||||
}
|
||||
}
|
||||
|
||||
override def tryEnqueuePacket(sourceSide: Option[EnumFacing], packet: Packet): Boolean = {
|
||||
if (Mods.ComputerCraft.isAvailable) {
|
||||
packet.data.headOption match {
|
||||
case Some(answerPort: java.lang.Double) => queueMessage(packet.source, packet.destination, packet.port, answerPort.toInt, packet.data.drop(1))
|
||||
case _ => queueMessage(packet.source, packet.destination, packet.port, -1, packet.data)
|
||||
}
|
||||
}
|
||||
super.tryEnqueuePacket(sourceSide, packet)
|
||||
}
|
||||
|
||||
override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet): Unit = {
|
||||
super.relayPacket(sourceSide, packet)
|
||||
|
||||
val tryChangeBuffer = sourceSide match {
|
||||
case Some(side) =>
|
||||
(amount: Double) => plugs(side.ordinal).node.asInstanceOf[Connector].tryChangeBuffer(amount)
|
||||
case _ =>
|
||||
(amount: Double) => plugs.exists(_.node.asInstanceOf[Connector].tryChangeBuffer(amount))
|
||||
}
|
||||
|
||||
if (isWirelessEnabled && strength > 0 && (sourceSide.isDefined || isRepeater)) {
|
||||
val cost = Settings.get.wirelessCostPerRange
|
||||
if (tryChangeBuffer(-strength * cost)) {
|
||||
api.Network.sendWirelessPacket(this, strength, packet)
|
||||
}
|
||||
}
|
||||
|
||||
if (isLinkedEnabled && sourceSide.isDefined) {
|
||||
val cost = packet.size / 32.0 + Settings.get.wirelessCostPerRange * Settings.get.maxWirelessRange * 5
|
||||
if (tryChangeBuffer(-cost)) {
|
||||
val endpoints = QuantumNetwork.getEndpoints(tunnel).filter(_ != this)
|
||||
for (endpoint <- endpoints) {
|
||||
endpoint.receivePacket(packet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onSwitchActivity()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override protected def createNode(plug: Plug) = api.Network.newNode(plug, Visibility.Network).
|
||||
withConnector(math.round(Settings.get.bufferAccessPoint)).
|
||||
create()
|
||||
|
||||
override protected def onPlugConnect(plug: Plug, node: Node) {
|
||||
super.onPlugConnect(plug, node)
|
||||
if (node == plug.node) {
|
||||
api.Network.joinWirelessNetwork(this)
|
||||
}
|
||||
if (plug.isPrimary)
|
||||
plug.node.connect(componentNodes(plug.side.ordinal()))
|
||||
else
|
||||
componentNodes(plug.side.ordinal).remove()
|
||||
}
|
||||
|
||||
override protected def onPlugDisconnect(plug: Plug, node: Node) {
|
||||
super.onPlugDisconnect(plug, node)
|
||||
if (node == plug.node) {
|
||||
api.Network.leaveWirelessNetwork(this)
|
||||
}
|
||||
if (plug.isPrimary && node != plug.node)
|
||||
plug.node.connect(componentNodes(plug.side.ordinal()))
|
||||
else
|
||||
componentNodes(plug.side.ordinal).remove()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override protected def onItemAdded(slot: Int, stack: ItemStack) {
|
||||
super.onItemAdded(slot, stack)
|
||||
updateLimits(slot, stack)
|
||||
}
|
||||
|
||||
private def updateLimits(slot: Int, stack: ItemStack) {
|
||||
Option(Driver.driverFor(stack, getClass)) match {
|
||||
case Some(driver) if driver.slot(stack) == Slot.CPU =>
|
||||
relayDelay = math.max(1, relayBaseDelay - ((driver.tier(stack) + 1) * relayDelayPerUpgrade))
|
||||
case Some(driver) if driver.slot(stack) == Slot.Memory =>
|
||||
relayAmount = math.max(1, relayBaseAmount + (Delegator.subItem(stack) match {
|
||||
case Some(ram: item.Memory) => (ram.tier + 1) * relayAmountPerUpgrade
|
||||
case _ => (driver.tier(stack) + 1) * (relayAmountPerUpgrade * 2)
|
||||
}))
|
||||
case Some(driver) if driver.slot(stack) == Slot.HDD =>
|
||||
maxQueueSize = math.max(1, queueBaseSize + (driver.tier(stack) + 1) * queueSizePerUpgrade)
|
||||
case Some(driver) if driver.slot(stack) == Slot.Card =>
|
||||
val descriptor = api.Items.get(stack)
|
||||
if (descriptor == WirelessNetworkCard) {
|
||||
isWirelessEnabled = true
|
||||
}
|
||||
if (descriptor == LinkedCard) {
|
||||
val data = DriverLinkedCard.dataTag(stack)
|
||||
if (data.hasKey(Settings.namespace + "tunnel")) {
|
||||
tunnel = data.getString(Settings.namespace + "tunnel")
|
||||
isLinkedEnabled = true
|
||||
QuantumNetwork.add(this)
|
||||
}
|
||||
}
|
||||
case _ => // Dafuq u doin.
|
||||
}
|
||||
}
|
||||
|
||||
override protected def onItemRemoved(slot: Int, stack: ItemStack) {
|
||||
super.onItemRemoved(slot, stack)
|
||||
Driver.driverFor(stack, getClass) match {
|
||||
case driver if driver.slot(stack) == Slot.CPU => relayDelay = relayBaseDelay
|
||||
case driver if driver.slot(stack) == Slot.Memory => relayAmount = relayBaseAmount
|
||||
case driver if driver.slot(stack) == Slot.HDD => maxQueueSize = queueBaseSize
|
||||
case driver if driver.slot(stack) == Slot.Card =>
|
||||
isWirelessEnabled = false
|
||||
isLinkedEnabled = false
|
||||
QuantumNetwork.remove(this)
|
||||
}
|
||||
}
|
||||
|
||||
override def getSizeInventory = InventorySlots.relay.length
|
||||
|
||||
override def isItemValidForSlot(slot: Int, stack: ItemStack) =
|
||||
Option(Driver.driverFor(stack, getClass)).fold(false)(driver => {
|
||||
val provided = InventorySlots.relay(slot)
|
||||
val tierSatisfied = driver.slot(stack) == provided.slot && driver.tier(stack) <= provided.tier
|
||||
val cardTypeSatisfied = if (provided.slot == Slot.Card) api.Items.get(stack) == WirelessNetworkCard || api.Items.get(stack) == LinkedCard else true
|
||||
tierSatisfied && cardTypeSatisfied
|
||||
})
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def readFromNBTForServer(nbt: NBTTagCompound) {
|
||||
super.readFromNBTForServer(nbt)
|
||||
for (slot <- items.indices) items(slot) collect {
|
||||
case stack => updateLimits(slot, stack)
|
||||
}
|
||||
|
||||
if (nbt.hasKey(Settings.namespace + "strength")) {
|
||||
strength = nbt.getDouble(Settings.namespace + "strength") max 0 min Settings.get.maxWirelessRange
|
||||
}
|
||||
if (nbt.hasKey(Settings.namespace + "isRepeater")) {
|
||||
isRepeater = nbt.getBoolean(Settings.namespace + "isRepeater")
|
||||
}
|
||||
nbt.getTagList(Settings.namespace + "componentNodes", NBT.TAG_COMPOUND).toArray[NBTTagCompound].
|
||||
zipWithIndex.foreach {
|
||||
case (tag, index) => componentNodes(index).load(tag)
|
||||
}
|
||||
}
|
||||
|
||||
override def writeToNBTForServer(nbt: NBTTagCompound) = {
|
||||
super.writeToNBTForServer(nbt)
|
||||
nbt.setDouble(Settings.namespace + "strength", strength)
|
||||
nbt.setBoolean(Settings.namespace + "isRepeater", isRepeater)
|
||||
nbt.setNewTagList(Settings.namespace + "componentNodes", componentNodes.map {
|
||||
case node: Node =>
|
||||
val tag = new NBTTagCompound()
|
||||
node.save(tag)
|
||||
tag
|
||||
case _ => new NBTTagCompound()
|
||||
})
|
||||
}
|
||||
}
|
@ -6,25 +6,49 @@ import li.cil.oc.common.InventorySlots
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.item
|
||||
import li.cil.oc.common.item.Delegator
|
||||
import li.cil.oc.server.PacketSender
|
||||
import li.cil.oc.integration.Mods
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
|
||||
class Switch extends traits.Hub with traits.NotAnalyzable with traits.ComponentInventory {
|
||||
var lastMessage = 0L
|
||||
// TODO Remove in 1.7
|
||||
class Switch extends traits.SwitchLike with traits.NotAnalyzable with traits.ComponentInventory {
|
||||
override def isWirelessEnabled = false
|
||||
|
||||
override def isLinkedEnabled = false
|
||||
|
||||
override def canUpdate = isServer
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
protected def queueMessage(source: String, destination: String, port: Int, answerPort: Int, args: Array[AnyRef]) {
|
||||
/* TODO ComputerCraft
|
||||
for (computer <- computers.map(_.asInstanceOf[IComputerAccess])) {
|
||||
val address = s"cc${computer.getID}_${computer.getAttachmentName}"
|
||||
if (source != address && Option(destination).forall(_ == address) && openPorts(computer).contains(port))
|
||||
computer.queueEvent("modem_message", Array(Seq(computer.getAttachmentName, Int.box(port), Int.box(answerPort)) ++ args.map {
|
||||
case x: Array[Byte] => new String(x, Charsets.UTF_8)
|
||||
case x => x
|
||||
}: _*))
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def tryEnqueuePacket(sourceSide: Option[EnumFacing], packet: Packet): Boolean = {
|
||||
if (Mods.ComputerCraft.isAvailable) {
|
||||
packet.data.headOption match {
|
||||
case Some(answerPort: java.lang.Double) => queueMessage(packet.source, packet.destination, packet.port, answerPort.toInt, packet.data.drop(1))
|
||||
case _ => queueMessage(packet.source, packet.destination, packet.port, -1, packet.data)
|
||||
}
|
||||
}
|
||||
super.tryEnqueuePacket(sourceSide, packet)
|
||||
}
|
||||
|
||||
override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet) {
|
||||
super.relayPacket(sourceSide, packet)
|
||||
val now = System.currentTimeMillis()
|
||||
if (now - lastMessage >= (relayDelay - 1) * 50) {
|
||||
lastMessage = now
|
||||
PacketSender.sendSwitchActivity(this)
|
||||
}
|
||||
onSwitchActivity()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
25
src/main/scala/li/cil/oc/common/tileentity/Transposer.scala
Normal file
25
src/main/scala/li/cil/oc/common/tileentity/Transposer.scala
Normal file
@ -0,0 +1,25 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
import li.cil.oc.server.component
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class Transposer extends traits.Environment {
|
||||
val transposer = new component.Transposer(this)
|
||||
|
||||
def node = transposer.node
|
||||
|
||||
// Used on client side to check whether to render activity indicators.
|
||||
var lastOperation = 0L
|
||||
|
||||
override def canUpdate = false
|
||||
|
||||
override def readFromNBTForServer(nbt: NBTTagCompound) {
|
||||
super.readFromNBTForServer(nbt)
|
||||
transposer.load(nbt)
|
||||
}
|
||||
|
||||
override def writeToNBTForServer(nbt: NBTTagCompound) {
|
||||
super.writeToNBTForServer(nbt)
|
||||
transposer.save(nbt)
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user