The priority here isn't particularly important, we can allow ourselves
to overwrite early and still allow some injections from others take
place.
Fixes#4007
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Properly reintroduces superclass transformers with
ModLauncher's ITransformer api. There are some quirks with
needing to accept transforming classes multiple times based
on voting contexts. This functions as expected in both
development and production cases from limited testing.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
A general purpose project to enable SpongeForge and SpongeVanilla
to ship and share the same transformers thereby reducing code
duplication.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Expanding on the existing getMixinConfiguration, we can enable querying
for potentially parented configurations from child projects.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Some mods aren't aware of lifecycle restrictions/assumptions and
occasionally, Sponge's own regsitry types aren't handled early enough
before mods can trigger Mixin injected registry interactive code.
Working around this results in using Suppliers as a means of delaying
registry lookups until a more appropriate time when plugins are making
use of API calls. This should be a sufficient workaround for
fixing #3630.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Some of our factory code needs to be able to reference static types,
but occasionally that will class-load too early.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
This was brutal awakening of how much reflection is relied on to create all sorts
of classes. Fortunately, the brunt of the changes are to do with figuring out how
to use ASM visitors to do the discovery work. It is now unit tested to ensure
classes that can be triggered with reflection for failure, will not fail.
An advantage of this is now we are assured the only class loading failures would
be breaking changes to our own API classes.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
The end goal is to replace usage of Java Reflection API that can be prone
to classloading exceptions/errors that end up crashing or throwing errors.
The major problem with reflection is the lack of clear control over
ClassLoaders and their ability to throw any arbitrary error. In retrospect,
we can now safely scan entire classes for specific methods that we care
about without triggering these classes to be loaded. Likewise, as a test,
we can assure that a defined class with an impossible to use method will
still be correctly covered for our purposes.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Avoids game crashes for seemingly client sided methods.
Client sided methods can be included in class bytecode, but
ultimately it's up to the developer to exclude it properly. In our case,
we don't have control over it normally, so we'll have to expect any
client side code to trigger some RuntimeExceptions.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
This workaround does two things:
- Schedules world unloading onto the MinecraftServer's
Server Thread executor to enforce a uniform threaded
access and avoid possible race conditions with asynchronous tasks
causing a deadlock on worlds attempting to schedule new tasks
- Adds a safety net to PoiManager.add to avoid scheduling new files
to be read while the world itself is already unloaded.
This should resolve the issue well enough, but there might be other
corner cases of scheduled tasks that could trigger a similar issue.
This actively prevents notifying other players on a player logging in
if the player itself is vanished. Likewise prevents a player logging
in knowing that another player is vanished.
Transactions can now have some lazy initialization by virtue of the
StatefulTransaction. Slowly the transaction can be lazily initialized
with at-least-requirements to be potentially absorbed by a parent
transaction, but not completely empty of data that the deferral renders
data to be unusable. The end goal of a recorded transaction is that it
knows its final state so-long-as it has populated any of it's non-final
fields.
Some inventory transactions intrinsically do not have the luxury of
deferred initialization and instead must await for future transactions
to be accepted down the line.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Now the moat has been built around the inventory transactions being
captured or absorbed. The remaining pieces of logging can now be
properly handled.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Instead of having a pair of two functions, this can be better
represented as a semi-pure function that can be provided as an override.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
There's a caveat that you cannot compare lambdas, but you can compare
fields that are themselves functions...
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Unit tested iteration ordering and processing, both in isolation and
with the TransactionalCaptureSupplier in play. The benefit of these
iterators is the guarantee now by contract as to "how" the transactions
are iterated through when attempting to merge/absorb a transaction into
any existing effects/transactions.
There's a huge speed boost for noisy transactions with
TransactionFlow.canBeAbsorbed, which enables some fail-fast and iterator
avoidance for most cases.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
GameTransaction can now be used as the super class for a broadening
hierarchy of transaction types. Case in point, the MenuBasedTransaction
cleanly applies the hierarchy of all AbstractContainerMenu known
transactions. This takes more steps to cleaning up the "checks" around
inventory collecting for slot transactions.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
The goal with this commit is to better organize the different behaviors
of GameTransactions that now exist and likely will increase as more is
refactored/cleaned up. The ultimate goal of this piece is to better
improve the inventory transaction management and have a less brittle
nature to their recording and sanity.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
While the slot packets were being sent, the container's changes were not
being "updated" which results in the restored changes being re-sent and
re-transacted in the player's next tick.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
This was causing some awkward event creation where hotbar indexes were
not resulting in correct slots being used for the event. This now
correctly provides the right slot for usage.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Menus are being created and then set on the player after the player is
added as a container listener. This unfortunately means that we have to
record the transaction for the player, then after the menu is being set,
record the new container on the specific transaction.
This is a tad brittle in the sense that we're not always sure that an
OpenInventory is being performed (since the container menu can be null),
but the resulting effect makes for an empty event optional, which turns
into a no-operation during processing.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Many of these inventory states do not expressly allow for entities to be
captured, but the corner case that an erroneous call from a transaction
in these particular states will result in a warning log. The
ramifications of the records are nil for gameplay, but mean that the
entities spawned may not have an event thrown, and therefor plugins may
not be aware of them.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Eliminates the public usage of PacketPhase.Inventory states
throughout without reducing utility. A majority of the checks were due
to the legacy capture slot transactions needing to be processable,
but with transactions being near-fully implemented with the transactor
system, it's irrelevant now.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
This avoids some persistence cases where a variety of slot changes ends
up being sent to the client in the next tick, losing any sort of cause
relation for the desired events. This has the side effect that we're now
always transacting inventory events if and only if the inventory has any
changes actually necessary.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
There isn't any case where we want the first transaction of a tree to be
considered the parent transaction. This fixes a minor behavior of
cancelling a block change potentially cancelling other transactions that
otherwise would've been expected to be unaffected.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
A lot of these mixins were somewhat instanceof checking a lot of
behaviors. They can now be correctly defined with their proper hierarchy
retained, without the naming mistake.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
A lot of the old restoring inventory behavior is replaced by restoring
in transactions. Also, the API contract is now correctly followed,
cancelling DropItemEvent.Pre does not roll back the inventory
transactions.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Based on the PhaseState, it can be possible to have entities that are
captured in the transaction itself. The key with this will be handling
the entities spawned and likewise, the restoration/purging of the
entities if the transaction is individually cancelled.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
This presents the required objects to perform positional transformations
on all entities/blocks/etc. within a Volume. The key with these changes
is that certain objects have requirements to perform "rotations" and
"mirroring" as a middle step. This is all built to support that out of
the box using the new Transformation API.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>
There's effectively a problem with positions of blocks, they're
technically considered the corners of a dotted world, and since
transformations are performed on the double accuracy positioning, we
want to be able to retain those positions as much as possible throughout
however many transformations on a volume are made.
This is mostly to support the ability to rotate and mirror volumes in
their entirety. The implementations are already semi-functional, pending
some off by one errors to be found and fixed.
Signed-off-by: Gabriel Harris-Rouquette <gabizou@me.com>