This was only present on the 1.21 NF version, hence not being noticed
before. Fixes#2020.
I pruned my Gradle cache recently, and I'm on some truly terrible hotel
wifi, so this is entirely untested. No beta, we die like men.
If the cursor is not visible then we'd end up blinking the last
character on the screen. And if the screen was empty we'd spew the logs
with GL errors.
Some mods run their own datafixer chain, rather than piggybacking on top
of vanilla's. This is A BAD IDEA, but what can you do. If such a mod
tries to use ItemStackComponentizationFix in their own schema, then
CC:T's mixins will try to look up the turtle block entitie, and fail (as
they're not registered under the modded schema).
We now inject the block entity fix as a separate fixer, rather than
abusing ItemStackComponentizationFix.
See #2012
- Use the correct index count for the cursor quad. Monitors are now
rendered as quads, rather than triangles.
- *Skip* rendering the cursor vertex, rather than additionally
rendering it.
I confess, I'm baffled how this code was ever written. From what I can
tell, this has been broken since it was first introduced in
4228011b84, and I'm sure I tested it then.
Fixes#2013. Probably.
Been dragging my feet over this for a while now, but increasingly
uncomfortable with Overwolf. I'm not going to delete the project (or any
existing versions), just not publish any new versions there.
- Don't construct a fake player when crafting: vanilla now has its own
automated crafting, so no longer requires the presence of a player.
- Fix remainder stack not being set in some situations. Closes#2007.
- Move redstone methods out of the IAPIEnvironment, and into a new
RedstoneAccess. We similarly move the implementation from Environment
into a new RedstoneState class.
The interface is possibly a little redundant (interfaces with a
single implementation are always a little suspect), but it's nice to
keep the consumer/producer interfaces separate.
- Abstract most redstone API methods into a separate shared class, that
can be used by both the rs API and the new redstone relay.
- Add the new redstone relay block.
The docs are probably a little lacking here, but I really struggled to
write anything which wasn't just "look, it's the same as the redstone
API".
Several functions accept a "timeout" argument, which is implemented by
starting a timer, and then racing the desired output against the timer
event.
However, if the timer never wins, we weren't cancelling the timer, and
so it was still queued. This is especially problematic if dozens or
hundreds of rednet (or websocket) messages are received in quick
succession, as we could fill the entire event queue, and stall the
computer.
See #1995
As part of the multi-loader work, we unified some of our event listening
code (0908acbe9b). This incorrectly caused
client pocket computer state to be reset when the player changes
dimension, rather than when the player (dis)connects.
The server code isn't aware of this behaviour, and so does not resend
pocket computer state when the player moves level. We could change this,
but just fixing when we clear the pocket computer state is a much nicer
fix!
Fixes#2004
v4 of the action seems to be much more restrictive in what can upload
coveage. I'll miss this (the historic view of coverage was nice!), but
not worth trying to get working again.
We also stop running client tests. These break so often, we only really
ran them for code coverage reasons.
The most annoying thing about pocket computers is handling computer
state (label, upgrades, etc...). Unlike other computers, which are tied
to a specific block entity, pocket computers float untethered. We can't
hold a reference to a specific item stack (as the computer might be
moved between inventories, crafted, etc...), so instead we explicitly
sync data between the computer and *current* stack, whenever the holding
player/entity is ticked.
In ed0b156e05 I rewrote this syncing code
to always treat the computer as the source of truth. Upgrades would be
copied to the computer, but never the other way round. However, this
meant that upgrades obtained by crafting would never be detected,
requiring the computer to be destroyed and recreated.
A more long-term fix here is probably to rewrite IPocketAccess to only
allow updating upgrade data on the main thread, and when we have a valid
PocketHolder. This is a breaking API change though, and so will have to
wait for 1.21.3.
For now, we just add a hook that refreshes the upgrade after crafting.
Fixes#1957
The update to Python 3.12 has broken the pre-commit action (as it
installs via pip rather than pipx). The maintainer seems unwilling to
fix it (to put it diplomatically), so let's just stop using the action
and imlement it ourselves.
One of the easiest things to mess up with writing a custom peripheral is
handling attached peripherals. IPeripheral.{attach,detach} are called
from multiple threads, so naive implementations that just store
computers in a set/list will at some point throw a CME.
Historically I've suggested using a concurrent collection (i.e.
ConcurrentHashMap). While this solves the problems of CMEs, it still has
some flaws. If a computer is detached while iterating over the
collection, the iterator will still yield the now-detached peripheral,
causing usages of that computer (e.g. queueEvent) to throw an exception.
The only fix here is to use a lock when updating and iterating over the
collection. This does come with some risks, but I think they are not too
serious:
- Lock contention: Contention is relatively rare in general (as
peripheral attach/detach is not especially frequent). If we do see
contention, both iteration and update actions are cheap, so I would
not expect the other thread to be blocked for a significant time.
- Deadlocks: One could imagine an implementation if IComputerAccess
that holds a lock both when detaching a peripheral and inside
queueEvent.
If we queue an event on one thread, and try to detach on the other,
we could see a deadlock:
Thread 1 | Thread 2
----------------------------------------------------------
AttachedComputerSet.queueEvent | MyModem.detach
(take lock #1) | (take lock #2)
-> MyModem.queueEvent | AttachedComputerSet.remove
(wait on lock #2) | (wait on lock #1)
Such code would have been broken already (some peripherals already
use locks), so I'm fairly sure we've fixed this in CC. But definitely
something to watch out for.
Anyway, the long and short of it:
- Add a new AttachedComputerSet that can be used to track the computers
attached to a peripheral. We also mention this in the attach/detach
docs, to hopefully make it a little more obvoius.
- Update speakers and monitors to use this new class.
Iris now has built-in support for NeoForge, so we can use the same
integration on both.
We also re-enable Forge's client tests, and test Iris there too.
Fixes#1967
Under Forge, netty-codec lives on the BOOT layer. However, this means it
does not have access to our jzlib (which lives on the GAME layer). To
fix this, we now shadow netty-codec (and its dependents, like netty-http
and netty-proxy) rather than jar-in-jaring them.
This involves some horrible build logic, but means websocket compression
works on Forge.
Fixes#1958.
- Place the player above the test region before running tests. This
guarantees the client has the chunks loaded (and rendered) before we
start running tests.
- Reset the time after running the monitor/printout tests.
- Fix rotation of turtle item models.
This still isn't perfect - the first test still fails with Iris and
Sodium - but is an improvement. Probably will still fail in CI though
:D:.
Previously we used an RGBA byte array. However, this comes with some
overhead (extra memory reads, bounds checks).
Minecraft 1.21+ uses ARGB32 colours for rendering (well, in the public
code — internaly it converts to ABGR), so it makes sense to match that
here.
We also add some helper functions for dealing with ARGB32 colours. These
can be removed in 1.21, as Minecraft will have these builtin.