use of org.spongepowered.asm.mixin.injection.Inject in project SpongeCommon by SpongePowered.
the class MixinSlotCrafting method afterTake.
/**
* Create CraftItemEvent.Post result is also handled by
* {@link MixinContainer#redirectTransferStackInSlot} or
* {@link MixinContainer#redirectOnTakeThrow}
*/
@Inject(method = "onTake", cancellable = true, at = @At("RETURN"))
private void afterTake(EntityPlayer thePlayer, ItemStack stack, CallbackInfoReturnable<ItemStack> cir) {
if (((IMixinWorld) thePlayer.world).isFake()) {
return;
}
((IMixinContainer) thePlayer.openContainer).detectAndSendChanges(true);
((IMixinContainer) thePlayer.openContainer).setCaptureInventory(false);
Container container = thePlayer.openContainer;
Inventory craftInv = ((Inventory) container).query(QueryOperationTypes.INVENTORY_TYPE.of(CraftingInventory.class));
if (!(craftInv instanceof CraftingInventory)) {
SpongeImpl.getLogger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire.");
return;
}
// retain only last slot-transactions on output slot
SlotTransaction first = null;
List<SlotTransaction> capturedTransactions = ((IMixinContainer) container).getCapturedTransactions();
for (Iterator<SlotTransaction> iterator = capturedTransactions.iterator(); iterator.hasNext(); ) {
SlotTransaction trans = iterator.next();
Optional<SlotIndex> slotIndex = trans.getSlot().getInventoryProperty(SlotIndex.class);
if (slotIndex.isPresent() && slotIndex.get().getValue() == 0) {
iterator.remove();
if (first == null) {
first = trans;
}
}
}
ItemStackSnapshot craftedItem;
// if we got a transaction on the crafting-slot use this
if (first != null) {
capturedTransactions.add(first);
craftedItem = first.getOriginal().copy();
} else {
if (stack.isEmpty()) {
// if stack is empty this was probably shift-crafting so we use the captured itemstack instead
craftedItem = ItemStackUtil.snapshotOf(this.craftedStack);
} else {
craftedItem = ItemStackUtil.snapshotOf(stack);
}
}
CraftingInventory craftingInventory = (CraftingInventory) craftInv;
CraftItemEvent.Craft event = SpongeCommonEventFactory.callCraftEventPost(thePlayer, craftingInventory, craftedItem, this.lastRecipe, container, capturedTransactions);
((IMixinContainer) container).setLastCraft(event);
((IMixinContainer) container).setFirePreview(true);
this.craftedStack = null;
SlotTransaction last = new SlotTransaction(craftingInventory.getResult(), ItemStackSnapshot.NONE, ItemStackUtil.snapshotOf(this.getStack()));
List<SlotTransaction> previewTransactions = ((IMixinContainer) container).getPreviewTransactions();
CraftingRecipe newRecipe = Sponge.getRegistry().getCraftingRecipeRegistry().findMatchingRecipe(craftingInventory.getCraftingGrid(), ((World) player.world)).orElse(null);
SpongeCommonEventFactory.callCraftEventPre(thePlayer, craftingInventory, last, newRecipe, container, previewTransactions);
previewTransactions.clear();
}
use of org.spongepowered.asm.mixin.injection.Inject in project SpongeCommon by SpongePowered.
the class MixinRConThreadClient method rconLogoutCallback.
@Inject(method = "closeSocket", at = @At("HEAD"))
public void rconLogoutCallback(CallbackInfo ci) {
if (this.loggedIn) {
SpongeImpl.getScheduler().callSync(() -> {
final CauseStackManager causeStackManager = Sponge.getCauseStackManager();
causeStackManager.pushCause(this);
causeStackManager.pushCause(this.source);
final RconConnectionEvent.Disconnect event = SpongeEventFactory.createRconConnectionEventDisconnect(causeStackManager.getCurrentCause(), (RconSource) this.source);
SpongeImpl.postEvent(event);
causeStackManager.popCauses(2);
return event;
});
}
}
use of org.spongepowered.asm.mixin.injection.Inject in project SpongeCommon by SpongePowered.
the class MixinDedicatedPlayerList method onBypassPlayerLimit.
@Inject(method = "bypassesPlayerLimit", at = @At("HEAD"), cancellable = true)
private void onBypassPlayerLimit(GameProfile profile, CallbackInfoReturnable<Boolean> ci) {
final PermissionService permissionService = Sponge.getServiceManager().provideUnchecked(PermissionService.class);
final Subject subject = permissionService.getUserSubjects().getSubject(profile.getId().toString()).orElse(permissionService.getDefaults());
final Tristate tristate = subject.getPermissionValue(SubjectData.GLOBAL_CONTEXT, LoginPermissions.BYPASS_PLAYER_LIMIT_PERMISSION);
// if we are still using the default permission service
if (tristate == Tristate.UNDEFINED && permissionService instanceof SpongePermissionService) {
return;
}
ci.setReturnValue(tristate.asBoolean());
}
use of org.spongepowered.asm.mixin.injection.Inject in project SpongeCommon by SpongePowered.
the class MixinMinecraftServer method onServerTickEnd.
@Inject(method = "tick", at = @At(value = "RETURN"))
public void onServerTickEnd(CallbackInfo ci) {
int lastAnimTick = SpongeCommonEventFactory.lastAnimationPacketTick;
int lastPrimaryTick = SpongeCommonEventFactory.lastPrimaryPacketTick;
int lastSecondaryTick = SpongeCommonEventFactory.lastSecondaryPacketTick;
if (SpongeCommonEventFactory.lastAnimationPlayer != null) {
EntityPlayerMP player = SpongeCommonEventFactory.lastAnimationPlayer.get();
if (player != null && lastAnimTick != lastPrimaryTick && lastAnimTick != lastSecondaryTick && lastAnimTick != 0 && lastAnimTick - lastPrimaryTick > 3 && lastAnimTick - lastSecondaryTick > 3) {
BlockSnapshot blockSnapshot = BlockSnapshot.NONE;
EnumFacing side = null;
final RayTraceResult result = SpongeImplHooks.rayTraceEyes(player, SpongeImplHooks.getBlockReachDistance(player) + 1);
// Hit non-air block
if (result != null && result.getBlockPos() != null) {
blockSnapshot = new Location<>((World) player.world, VecHelper.toVector3d(result.getBlockPos())).createSnapshot();
side = result.sideHit;
}
Sponge.getCauseStackManager().pushCause(player);
if (!player.getHeldItemMainhand().isEmpty()) {
if (SpongeCommonEventFactory.callInteractItemEventPrimary(player, player.getHeldItemMainhand(), EnumHand.MAIN_HAND, result == null ? null : VecHelper.toVector3d(result.hitVec), blockSnapshot).isCancelled()) {
SpongeCommonEventFactory.lastAnimationPacketTick = 0;
Sponge.getCauseStackManager().popCause();
return;
}
}
if (side != null) {
SpongeCommonEventFactory.callInteractBlockEventPrimary(player, blockSnapshot, EnumHand.MAIN_HAND, side, VecHelper.toVector3d(result.hitVec));
} else {
SpongeCommonEventFactory.callInteractBlockEventPrimary(player, EnumHand.MAIN_HAND, result == null ? null : VecHelper.toVector3d(result.hitVec));
}
Sponge.getCauseStackManager().popCause();
}
}
SpongeCommonEventFactory.lastAnimationPacketTick = 0;
TimingsManager.FULL_SERVER_TICK.stopTiming();
}
use of org.spongepowered.asm.mixin.injection.Inject in project SpongeCommon by SpongePowered.
the class MixinMinecraftServer method onUpdateTimeLightAndEntitiesHead.
// All chunk unload queuing needs to be processed BEFORE the future tasks are run as mods/plugins may have tasks that request chunks.
// This prevents a situation where a chunk is requested to load then unloads at end of tick.
@Inject(method = "updateTimeLightAndEntities", at = @At("HEAD"))
public void onUpdateTimeLightAndEntitiesHead(CallbackInfo ci) {
for (int i = 0; i < this.worlds.length; ++i) {
WorldServer worldServer = this.worlds[i];
// ChunkGC needs to be processed before a world tick in order to guarantee any chunk queued for unload
// can still be marked active and avoid unload if accessed during the same tick.
// Note: This injection must come before Forge's pre world tick event or it will cause issues with mods.
IMixinWorldServer spongeWorld = (IMixinWorldServer) worldServer;
if (spongeWorld.getChunkGCTickInterval() > 0) {
spongeWorld.doChunkGC();
}
// Moved from PlayerChunkMap to avoid chunks from unloading after being requested in same tick
if (worldServer.getPlayerChunkMap().players.isEmpty()) {
WorldProvider worldprovider = worldServer.provider;
if (!worldprovider.canRespawnHere()) {
worldServer.getChunkProvider().queueUnloadAll();
}
}
}
}
Aggregations