This uses a custom ComputerCraft packet to send chat messages to the
client. When received, we delete all messages of the same category
before sending the new ones.
This avoids cluttering the chat with near-identical messages, and helps
make working with the "individual dump" command easier, as the previous
computer's dump output is deleted.
Also change the max height of the TextTable to 18, so it fits within
Minecraft's default chat limit.
This implements an argument format similar to LuaReqeust, as described
in dan200/ComputerCraft#515. The Lua argument checking code is a little
verbose and repetitive, but I'm not sure how to avoid that - we should
look into improving it in the future.
Closes#21
- fixed circumflex typo: you can now cîrcûmflêx on all your friends
- added comment making it clearer that the following lines are intended for backwards compatibility.
Whilst the legacy ones are important for backwards compatibility, they
cannot have an ID of 0, which introduces issues when they are the first
disk created in the world.
This allows us to track how much work various peripherals are doing.
This will not work with all systems, such as Plethora, as that has its
own execution system.
The limit was added to prevent people creating arbitrarily large buffers
(for instance, handle.read(2^31) would create a 2GB char array). For
"large" counts, we now read in blocks of size 8192, adding to an
extendable buffer.
- Add additional maven metadata and strip dependencies
- Shift ICommand registration into the proxy, to avoid class loading
issues. This is probably rather temperamental, but classloading
always is.
- Trackers are created per-user, meaning multiple people can run
/computercraft track at once.
- Allow sorting the tracking information by arbitrary fields.
- Add support for tracking arbitrary fields (though none are currently
implemented).
- Abstract peripheral ID and type checking into separate class
- Update peripherals directly rather than marking as invalid then
fetching from the network.
- Update peripherals when adjacent tiles change
This does result in a slightly more ugly interface, but reduces the
amount of work needed to perform partial updates of peripherals, such as
those done by neighbouring tile updates.
Forge's default fake player implementation doesn't override all methods
which use the connection. As it is not set, we get an NPE and thus crash
the server. We simply stub those methods out ourselves to prevent such
an issue.
When initially attaching a modem, the adjacent computer would not show
up on its own peripheral list (like in vanilla CC). However, it would
show up when the chunk was reloaded as peripherals were added through a
different method.
This prevents such behaviour, always hiding the remote peripheral from
the object which provides it.
Closes#20
Shaders appear to ignore all the other subtle (and not-so-subtle) hints
we drop that monitors shouldn't be rendered with shadows. This solution
isn't optimal, as monitors may still be tinted due to sunlight, but
there is nothing we can do about that.
Many thanks to ferreusveritas for their help in diagnosing, fixing and
testing this issue.
Shader mods may perform multiple passes when rendering a tile, so
monitors will be drawn transparently on later passes. In order to
prevent this we allow drawing the a single tile multiple times in a
tick.
The two recipes are pretty similar, so this allows us to substantially
simplify the code. This now introduces the additional requirement that
computers must be used to create turtles, rather than pocket computers
or another turtle.
This adds IComputerItem.withFamily(ItemStack, ComputerFamily) as well as
a ComputerFamilyRecipe class. Each type of computer (normal, turtle,
pocket) defines a recipe using this class, as they require a different
number of gold ingots to upgrade.
These act similarly to conventional wired modems, but with the advantage
that they are a full block. This means they can be attached to
peripherals which are not solid (such as chests). Further more, as they
do not have a direction, they allow wrapping peripherals on all 6 sides.
It's worth noting that wired modems do not require a cable - they will
automatically form connections to adjacent network elements when placed.
There are several important things to note here:
- The network element is associated with the cable, whilst the
peripheral (and so packet sender/receiver) is associated with the
modem. This allows us to have the main element be in the centre of
the cable block, whilst the modem is in the centre of the adjacent
computer.
- Cables will connect to any adjacent network element, not just
other cables.
- Rednet messages are now sent on the computer thread, rather than the
cable tick.
The API is composed of three primary classes:
- IWiredElement: Represents some physical entity in the network. This
will generally be a block (such as a cable or modem), but it is not
required to be.
Each element can provide a series of peripherals, which will be
exposed to other elements on the network.
- IWiredNode: Every wired element has a unique wired node. This acts
as a thread-safe proxy for communicating with the rest of the
network (such as sending packets). Each node is also its own packet
network.
- IWiredNetwork: This is responsible for keeping track of nodes and
peripherals in the network. It provides methods for forming and
breaking connections, correctly joining and splitting networks where
needed.
Tiles which wish to be part of a wired network should implement
IWiredElementTile or register a custom IWiredProvider. When loaded into
the world, it should connect to adjacent nodes. Similarly, when removed
(either due to being broken or chunk unloads), it should break those
connections.
There is no method to query the layout of the network, as that offers
greater flexibility in changing or extending the implementation later
on.
This provides a mechanism for peripherals to see what else a computer is
connected to - and then interact with those peripherals.
We also add the ability to query what block or tile a peripheral
targets. This allows one to interact with the original block of adjacent
peripherals instead.
Mostly intended for those people who don't like .inspect() or
.getItemDetail(), but could allow modpacks to block equipping upgrades,
placing blocks, etc...
The main aim of this is to allow for greater extensibility for other
mods. For instance, you can now prevent turtles placing dirt blocks, or
turning when on gravel.
As of #458, BlockPeripheral will act as a full/opaque block for some
peripherals and a transparent one for others. However, some Block
methods use the default state rather than the current one. This means
modems report being a full block when they are not, leading to
suffocating entities and lighting glitches.
As of #458, BlockPeripheral will act as a full/opaque block for some
peripherals and a transparent one for others. However, some Block
methods use the default state rather than the current one. This means
modems report being a full block when they are not, leading to
suffocating entities and lighting glitches.
This restructures monitor in order to make it thread-safe: namely
removing any world interaction from the computer thread.
Instead of each monitor having their own terminal, resize flag, etc...
we use a monitor "multiblock" object. This is constructed on the origin
monitor and propagated to other monitors when required.
We attempt to construct the multiblock object (and so the corresponding
terminal) as lazily as posible. Consequently, we only create the
terminal when fetching the peripheral (not when attaching, as that is
done on the computer thread).
If a monitor is resized (say due to placing/breaking a monitor) then we
will invalidate all references to the multiblock object, construct a new
one if required, and propagate it to all component monitors.
This commit also fixes several instances of glLists not being deleted
after use. It is not a comprehensive fix, but that is outside the scope
of this commit.
- Ensure usage is consistent
- Allow computer selectors to return multiple values
- Fix commands being marked as usable when it isn't
- Add /computercraft turn-on, a counter to /computercraft shutdown
As tiles outside the world border are not ticked, turtles are rendered
entirely useless. Furthermore, the turtle animation will never progress
resulting in visual glitches.
In order to avoid this, we ensure the target position is within the
world border when moving to it.
When a player places a turtle, they are marked as its owner. Any actions
they perform (such as breaking blocks, moving, etc...) are performed
using this player's game profile.
This allows turtles to work correctly with various permissions mods.
Previously you would have to whitelist all turtles in order for them to
function within a claim.
This means one can call .getFamily() in a thread-safe manner, ensuring
turtle.getFuelLimit() does not cause issues. As we use a specialist
TE class for each family this does not require any specialist caching.
This adds several commands which may be useful for server owners. It'd
be nice to integrate this into ComputerCraft itself, but the associated
command framework is quite large so we'd have to think about it.
This migrates TurtleMultiModel's current vertex transformation system
into something more powerful and "correct". Namely, it has the following
improvements:
- Handles all position formats (float, byte, etc...)
- Correctly translates normals of quads
- Reorders faces if the winding order is reversed
ILuaAPI has been moved to dan200.computercraft.api.lua. One creates
a new API by registering an instance of ILuaAPIFactory. This takes an
instance of IComputerSystem and returns such an API.
IComputerSystem is an extension of IComputerAccess, with methods to
access additional information about the the computer, such as its label
and filesystem.
- ComputerThread constructs multiple threads instead of just one,
depending on a config options.
- The synchronized blocks of PeripheralAPI.PeripheralWrapper have been
shifted a little to ensure no deadlocks occur.
Whilst I'm pretty sure this is safe for general use, I'm disabling this
by default for now. I may consider enabling it in the future if no
issues are found.
This uses Netty's websocket functionality, meaning we do not have to
depend on another library.
As websockets do not fit neatly into the standard polling socket model,
the API is significantly more event based than CCTweaks's. One uses
http.websocket to connect, which will wait until a connection is
established and then returns the connection object (an async variant is
available).
Once you have a websocket object, you can use .send(msg) to transmit a
message. Incoming messages will fire a "websocket_message" event, with
the URL and content as arguments. A convenience method (.receive())
exists to aid waiting for valid messages.