use of org.spongepowered.common.event.tracking.context.transaction.GameTransaction in project SpongeCommon by SpongePowered.
the class ContainerBasedTransaction method generateEvent.
@Override
public Optional<ClickContainerEvent> generateEvent(final PhaseContext<@NonNull ?> context, @Nullable final GameTransaction<@NonNull ?> parent, final ImmutableList<GameTransaction<ClickContainerEvent>> gameTransactions, final Cause currentCause) {
final ImmutableList<ContainerBasedTransaction> containerBasedTransactions = gameTransactions.stream().filter(tx -> tx instanceof ContainerBasedTransaction).map(tx -> (ContainerBasedTransaction) tx).filter(tx -> !tx.used).collect(ImmutableList.toImmutableList());
if (containerBasedTransactions.stream().map(c -> c.isContainerEventAllowed(context)).filter(b -> !b).findAny().orElse(false)) {
SpongeCommon.logger().warn("No event will be fired for existing ContainerBasedTransactions: {}", containerBasedTransactions.size());
return Optional.empty();
}
if (!((TrackedContainerBridge) this.menu).bridge$capturePossible()) {
// if (ContainerBasedTransaction.containersFailedCapture.add(this.menu.getClass())) {
// SpongeCommon.logger()
// .warn("Changes in modded Container were not captured. Inventory events will not fire for this. Container: " + this.menu.getClass());
// }
}
final List<Entity> entities = containerBasedTransactions.stream().map(ContainerBasedTransaction::getEntitiesSpawned).flatMap(List::stream).collect(Collectors.toList());
final List<SlotTransaction> slotTransactions = containerBasedTransactions.stream().map(ContainerBasedTransaction::getSlotTransactions).flatMap(List::stream).collect(Collectors.toList());
if (this.craftingInventory != null) {
// Event with Preview transaction on crafting inventory?
Slot slot = this.craftingInventory.result();
@Nullable final SlotTransaction preview = this.findPreviewTransaction(this.craftingInventory.result(), slotTransactions);
final ItemStackSnapshot previewItem = ItemStackUtil.snapshotOf(this.craftingInventory.peek());
if (preview != null) {
slot = preview.slot();
// Check if preview transaction is correct
if (!preview.defaultReplacement().equals(previewItem)) {
slotTransactions.remove(preview);
slotTransactions.add(new SlotTransaction(slot, preview.original(), previewItem));
}
} else if (!previewItem.isEmpty()) {
slotTransactions.add(new SlotTransaction(slot, previewItem, previewItem));
}
}
for (final ContainerBasedTransaction transaction : containerBasedTransactions) {
transaction.used = true;
}
final Optional<ClickContainerEvent> event = containerBasedTransactions.stream().map(t -> t.createInventoryEvent(slotTransactions, entities, context, currentCause)).filter(Optional::isPresent).map(Optional::get).findFirst();
if (!event.isPresent() && !slotTransactions.isEmpty()) {
SpongeCommon.logger().warn("Logged slot transactions without event! {} {}", gameTransactions.size(), this.menu.getClass().getName(), new Exception(""));
for (final SlotTransaction slotTransaction : slotTransactions) {
SpongeCommon.logger().warn(slotTransaction);
}
}
return event;
}
use of org.spongepowered.common.event.tracking.context.transaction.GameTransaction in project SpongeCommon by SpongePowered.
the class CloseMenuTransaction method generateEvent.
@Override
public Optional<InteractContainerEvent> generateEvent(final PhaseContext<@NonNull ?> context, @Nullable final GameTransaction<@NonNull ?> parent, final ImmutableList<GameTransaction<InteractContainerEvent>> gameTransactions, final Cause currentCause) {
final ItemStackSnapshot resultingCursor = ItemStackUtil.snapshotOf(this.player.inventory.getCarried());
final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(this.cursor, resultingCursor);
final InteractContainerEvent.Close event = SpongeEventFactory.createInteractContainerEventClose(currentCause, (Container) this.menu, cursorTransaction, (Container) this.menu, this.slotTransactions == null ? Collections.emptyList() : this.slotTransactions);
return Optional.of(event);
}
use of org.spongepowered.common.event.tracking.context.transaction.GameTransaction in project SpongeCommon by SpongePowered.
the class InventoryBasedTransaction method generateEvent.
@Override
public Optional<ChangeInventoryEvent> generateEvent(final PhaseContext<@NonNull ?> context, @Nullable final GameTransaction<@NonNull ?> parent, final ImmutableList<GameTransaction<ChangeInventoryEvent>> gameTransactions, final Cause currentCause) {
final ImmutableList<InventoryBasedTransaction> containerBasedTransactions = gameTransactions.stream().filter(tx -> tx instanceof InventoryBasedTransaction).map(tx -> (InventoryBasedTransaction) tx).filter(tx -> !tx.used).collect(ImmutableList.toImmutableList());
final List<SlotTransaction> slotTransactions = containerBasedTransactions.stream().map(InventoryBasedTransaction::getSlotTransactions).flatMap(List::stream).collect(Collectors.toList());
for (InventoryBasedTransaction transaction : containerBasedTransactions) {
transaction.used = true;
}
final List<Entity> entities = containerBasedTransactions.stream().map(InventoryBasedTransaction::getEntitiesSpawned).flatMap(List::stream).collect(Collectors.toList());
// TODO on pickup grouping does not work?
final Map<Slot, List<SlotTransaction>> collected = slotTransactions.stream().collect(Collectors.groupingBy(SlotTransaction::slot));
slotTransactions.clear();
collected.values().forEach(list -> {
final SlotTransaction first = list.get(0);
if (list.size() > 1) {
final ItemStackSnapshot last = list.get(list.size() - 1).defaultReplacement();
slotTransactions.add(new SlotTransaction(first.slot(), first.original(), last));
} else {
slotTransactions.add(first);
}
});
return containerBasedTransactions.stream().map(t -> t.createInventoryEvent(slotTransactions, entities, context, currentCause)).filter(Optional::isPresent).map(Optional::get).findFirst();
}
use of org.spongepowered.common.event.tracking.context.transaction.GameTransaction in project SpongeCommon by SpongePowered.
the class OpenMenuTransaction method generateEvent.
@Override
public Optional<InteractContainerEvent> generateEvent(final PhaseContext<@NonNull ?> context, @Nullable final GameTransaction<@NonNull ?> parent, final ImmutableList<GameTransaction<InteractContainerEvent>> gameTransactions, final Cause currentCause) {
final ItemStackSnapshot resultingCursor = ItemStackUtil.snapshotOf(this.player.inventory.getCarried());
final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(this.cursor, resultingCursor);
final InteractContainerEvent.Open event = SpongeEventFactory.createInteractContainerEventOpen(currentCause, (Container) this.menu, cursorTransaction);
return Optional.of(event);
}
use of org.spongepowered.common.event.tracking.context.transaction.GameTransaction in project SpongeCommon by SpongePowered.
the class BlockEventBasedTransaction method generateEvent.
@Override
public final Optional<ChangeBlockEvent.All> generateEvent(final PhaseContext<@NonNull ?> context, @Nullable final GameTransaction<@NonNull ?> parent, final ImmutableList<GameTransaction<ChangeBlockEvent.All>> transactions, final Cause currentCause) {
final Optional<ServerWorld> o = ((SpongeServer) SpongeCommon.server()).worldManager().world(this.worldKey);
if (!o.isPresent()) {
return Optional.empty();
}
final ListMultimap<BlockPos, SpongeBlockSnapshot> positions = LinkedListMultimap.create();
for (final GameTransaction<@NonNull ?> transaction : transactions) {
final BlockEventBasedTransaction blockTransaction = (BlockEventBasedTransaction) transaction;
if (!positions.containsKey(blockTransaction.affectedPosition)) {
positions.put(blockTransaction.affectedPosition, blockTransaction.getOriginalSnapshot());
}
if (blockTransaction.getResultingSnapshot() != null) {
positions.put(blockTransaction.affectedPosition, blockTransaction.getResultingSnapshot());
}
}
final ImmutableList<BlockTransaction> eventTransactions = positions.asMap().values().stream().map(spongeBlockSnapshots -> {
final List<SpongeBlockSnapshot> snapshots = new ArrayList<>(spongeBlockSnapshots);
if (snapshots.isEmpty() || snapshots.size() < 2) {
// Error case
return Optional.<BlockTransaction>empty();
}
final SpongeBlockSnapshot original = snapshots.get(0);
final SpongeBlockSnapshot result = snapshots.get(snapshots.size() - 1);
final ImmutableList<BlockSnapshot> intermediary;
if (snapshots.size() > 2) {
intermediary = ImmutableList.copyOf(snapshots.subList(1, snapshots.size() - 2));
} else {
intermediary = ImmutableList.of();
}
final Operation operation = context.getBlockOperation(original, result);
final BlockTransaction eventTransaction = new BlockTransaction(original, result, intermediary, operation);
return Optional.of(eventTransaction);
}).filter(Optional::isPresent).map(Optional::get).collect(ImmutableList.toImmutableList());
if (eventTransactions.isEmpty()) {
return Optional.empty();
}
return Optional.of(SpongeEventFactory.createChangeBlockEventAll(currentCause, eventTransactions, o.get()));
}
Aggregations