Search in sources :

Example 11 with CauseStackManager

use of org.spongepowered.api.event.CauseStackManager in project SpongeCommon by SpongePowered.

the class DamageEventUtil method createEnchantmentModifiers.

public static Optional<List<DamageFunction>> createEnchantmentModifiers(final LivingEntity living, final DamageSource damageSource) {
    if (damageSource.isBypassMagic()) {
        return Optional.empty();
    }
    final Iterable<net.minecraft.world.item.ItemStack> inventory = living.getArmorSlots();
    final int damageProtection = EnchantmentHelper.getDamageProtection(inventory, damageSource);
    if (damageProtection <= 0) {
        return Optional.empty();
    }
    final List<DamageFunction> modifiers = new ArrayList<>();
    final DoubleUnaryOperator enchantmentFunction = incomingDamage -> -(incomingDamage - CombatRules.getDamageAfterMagicAbsorb((float) incomingDamage, damageProtection));
    try (final CauseStackManager.StackFrame frame = ((Server) living.getServer()).causeStackManager().pushCauseFrame()) {
        frame.pushCause(living);
        final DamageModifier enchantmentModifier = DamageModifier.builder().cause(frame.currentCause()).type(DamageModifierTypes.ARMOR_ENCHANTMENT).build();
        modifiers.add(new DamageFunction(enchantmentModifier, enchantmentFunction));
    }
    return Optional.of(modifiers);
}
Also used : ResourceLocation(net.minecraft.resources.ResourceLocation) LivingEntity(net.minecraft.world.entity.LivingEntity) AABB(net.minecraft.world.phys.AABB) LivingEntityAccessor(org.spongepowered.common.accessor.world.entity.LivingEntityAccessor) ItemStackSnapshot(org.spongepowered.api.item.inventory.ItemStackSnapshot) MobType(net.minecraft.world.entity.MobType) EventContext(org.spongepowered.api.event.EventContext) Registry(net.minecraft.core.Registry) ChunkSource(net.minecraft.world.level.chunk.ChunkSource) CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) ItemStack(org.spongepowered.api.item.inventory.ItemStack) Map(java.util.Map) PotionEffect(org.spongepowered.api.effect.potion.PotionEffect) Predicate(java.util.function.Predicate) Collection(java.util.Collection) Player(net.minecraft.world.entity.player.Player) List(java.util.List) BlockPos(net.minecraft.core.BlockPos) BlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.BlockDamageSource) Optional(java.util.Optional) ServerLocation(org.spongepowered.api.world.server.ServerLocation) Enchantment(net.minecraft.world.item.enchantment.Enchantment) LevelChunk(net.minecraft.world.level.chunk.LevelChunk) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) EventContextKeys(org.spongepowered.api.event.EventContextKeys) ServerWorld(org.spongepowered.api.world.server.ServerWorld) BlockState(net.minecraft.world.level.block.state.BlockState) HashMap(java.util.HashMap) DamageModifierTypes(org.spongepowered.api.event.cause.entity.damage.DamageModifierTypes) MobEffects(net.minecraft.world.effect.MobEffects) DoubleUnaryOperator(java.util.function.DoubleUnaryOperator) ArrayList(java.util.ArrayList) EntityDamageSource(net.minecraft.world.damagesource.EntityDamageSource) ItemStackUtil(org.spongepowered.common.item.util.ItemStackUtil) DamageSource(net.minecraft.world.damagesource.DamageSource) EnchantmentHelper(net.minecraft.world.item.enchantment.EnchantmentHelper) CombatRules(net.minecraft.world.damagesource.CombatRules) Server(org.spongepowered.api.Server) CauseStackManager(org.spongepowered.api.event.CauseStackManager) FallingBlockDamageSource(org.spongepowered.api.event.cause.entity.damage.source.FallingBlockDamageSource) Cause(org.spongepowered.api.event.Cause) Entity(net.minecraft.world.entity.Entity) DamageFunction(org.spongepowered.api.event.cause.entity.damage.DamageFunction) DamageModifier(org.spongepowered.api.event.cause.entity.damage.DamageModifier) EquipmentSlot(net.minecraft.world.entity.EquipmentSlot) Attributes(net.minecraft.world.entity.ai.attributes.Attributes) Mth(net.minecraft.util.Mth) Collections(java.util.Collections) ListTag(net.minecraft.nbt.ListTag) ArrayList(java.util.ArrayList) CauseStackManager(org.spongepowered.api.event.CauseStackManager) DamageModifier(org.spongepowered.api.event.cause.entity.damage.DamageModifier) DamageFunction(org.spongepowered.api.event.cause.entity.damage.DamageFunction) ItemStack(org.spongepowered.api.item.inventory.ItemStack) DoubleUnaryOperator(java.util.function.DoubleUnaryOperator)

Example 12 with CauseStackManager

use of org.spongepowered.api.event.CauseStackManager in project SpongeCommon by SpongePowered.

the class RconClientMixin method run.

/**
 * @author Cybermaxke
 * @reason Fix RCON, is completely broken
 */
@SuppressWarnings("ConstantConditions")
@Override
@Overwrite
public void run() {
    // / Sponge: START
    // Initialize the source
    this.impl$source = new RconConsoleSource(SpongeCommon.server());
    ((RconConsoleSourceBridge) this.impl$source).bridge$setClient((RconClient) (Object) this);
    // Call the connection event
    final RconConnectionEvent.Connect connectEvent;
    try {
        connectEvent = SpongeCommon.serverScheduler().execute(() -> {
            final CauseStackManager causeStackManager = PhaseTracker.getCauseStackManager();
            causeStackManager.pushCause(this);
            causeStackManager.pushCause(this.impl$source);
            final RconConnectionEvent.Connect event = SpongeEventFactory.createRconConnectionEventConnect(causeStackManager.currentCause(), (RconConnection) this.impl$source);
            SpongeCommon.post(event);
            causeStackManager.popCauses(2);
            return event;
        }).get();
    } catch (final InterruptedException | ExecutionException ignored) {
        this.closeSocket();
        return;
    }
    if (connectEvent.isCancelled()) {
        this.closeSocket();
        return;
    }
    // /         'closeSocket' is moved out of the loop
    while (true) {
        try {
            if (!this.running) {
                break;
            }
            final BufferedInputStream bufferedinputstream = new BufferedInputStream(this.client.getInputStream());
            final int i = bufferedinputstream.read(this.buf, 0, this.buf.length);
            // / Sponge: START
            if (i == -1) {
                // continue to return EOF until we manually exit the loop.
                break;
            }
            if (10 <= i) {
                int j = 0;
                final int k = PktUtils.intFromByteArray(this.buf, 0, i);
                if (k != i - 4) {
                    break;
                }
                j += 4;
                final int l = PktUtils.intFromByteArray(this.buf, j, i);
                j += 4;
                final int i1 = PktUtils.intFromByteArray(this.buf, j);
                j += 4;
                switch(i1) {
                    case 2:
                        if (this.authed) {
                            final String command = PktUtils.stringFromByteArray(this.buf, j, i);
                            try {
                                // / Sponge: START
                                // Execute the command on the main thread and wait for it
                                SpongeCommon.serverScheduler().execute(() -> {
                                    final CauseStackManager causeStackManager = PhaseTracker.getCauseStackManager();
                                    // Only add the RemoteConnection here, the RconSource
                                    // will be added by the command manager
                                    causeStackManager.pushCause(this);
                                    SpongeCommon.server().getCommands().performCommand(this.impl$source.createCommandSourceStack(), command);
                                    causeStackManager.popCause();
                                }).get();
                                final String logContents = this.impl$source.getCommandResponse();
                                this.impl$source.prepareForCommand();
                                this.shadow$sendCmdResponse(l, logContents);
                            // / Sponge: END
                            } catch (final Exception exception) {
                                this.shadow$sendCmdResponse(l, "Error executing: " + command + " (" + exception.getMessage() + ")");
                            }
                            continue;
                        }
                        this.shadow$sendAuthFailure();
                        // Sponge: 'continue' -> 'break', disconnect when a invalid operation is requested
                        break;
                    case 3:
                        final String password = PktUtils.stringFromByteArray(this.buf, j, i);
                        if (!password.isEmpty() && password.equals(this.rconPassword)) {
                            // / Sponge: START
                            final RconConnectionEvent.Auth event = SpongeCommon.serverScheduler().execute(() -> {
                                final CauseStackManager causeStackManager = PhaseTracker.getCauseStackManager();
                                causeStackManager.pushCause(this);
                                causeStackManager.pushCause(this.impl$source);
                                final RconConnectionEvent.Auth event1 = SpongeEventFactory.createRconConnectionEventAuth(causeStackManager.currentCause(), (RconConnection) this.impl$source);
                                SpongeCommon.post(event1);
                                causeStackManager.popCauses(2);
                                return event1;
                            }).get();
                            if (!event.isCancelled()) {
                                this.authed = true;
                                this.shadow$send(l, 2, "");
                                continue;
                            }
                        // / Sponge: END
                        }
                        this.authed = false;
                        this.shadow$sendAuthFailure();
                        // Sponge: 'continue' -> 'break', disconnect if login failed
                        break;
                    default:
                        this.shadow$sendCmdResponse(l, String.format("Unknown request %s", Integer.toHexString(i1)));
                        // Sponge: 'continue' -> 'break', disconnect when a invalid operation is requested
                        break;
                }
            }
        } catch (final IOException e) {
            break;
        } catch (final Exception e) {
            RconClientMixin.LOGGER.error("Exception whilst parsing RCON input", e);
            break;
        }
    }
    this.closeSocket();
}
Also used : RconConsoleSource(net.minecraft.server.rcon.RconConsoleSource) IOException(java.io.IOException) RconConsoleSourceBridge(org.spongepowered.common.bridge.server.rcon.RconConsoleSourceBridge) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) BufferedInputStream(java.io.BufferedInputStream) CauseStackManager(org.spongepowered.api.event.CauseStackManager) RconConnection(org.spongepowered.api.network.RconConnection) RconConnectionEvent(org.spongepowered.api.event.network.rcon.RconConnectionEvent) ExecutionException(java.util.concurrent.ExecutionException) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 13 with CauseStackManager

use of org.spongepowered.api.event.CauseStackManager in project SpongeCommon by SpongePowered.

the class CommandSourceStackMixin method impl$updateCauseOnWithWorld.

/*
     * A note on why we're doing this with the cause manually.
     *
     * When the object is first constructed, we get the cause from the stack manager. However, as the command processor
     * works through the nodes, this entire source may get replaced. We want to keep some of the changes in sync,
     * but the original cause may have gone by the time the source changes. Really, this command source is the analogue
     * of our Cause, NOT our CauseStackManager, so we just need to do `Cause.with(...)` along with their select `with*(...)`
     * methods.
     */
@Inject(method = "withLevel", at = @At("RETURN"))
private void impl$updateCauseOnWithWorld(final ServerLevel serverWorld, final CallbackInfoReturnable<CommandSourceStack> cir) {
    if (cir.getReturnValue() != (Object) this) {
        final ServerLocation location = this.impl$cause.context().get(EventContextKeys.LOCATION).map(x -> ServerLocation.of((org.spongepowered.api.world.server.ServerWorld) serverWorld, x.position())).orElseGet(() -> ServerLocation.of((org.spongepowered.api.world.server.ServerWorld) serverWorld, VecHelper.toVector3d(cir.getReturnValue().getPosition())));
        ((CommandSourceStackBridge) cir.getReturnValue()).bridge$setCause(this.impl$applyToCause(EventContextKeys.LOCATION, location));
    }
}
Also used : EventContextKey(org.spongepowered.api.event.EventContextKey) CommandSourceStackAccessor(org.spongepowered.common.accessor.commands.CommandSourceStackAccessor) EventContextKeys(org.spongepowered.api.event.EventContextKeys) CommandSourceStack(net.minecraft.commands.CommandSourceStack) Inject(org.spongepowered.asm.mixin.injection.Inject) HashMap(java.util.HashMap) ServerLevel(net.minecraft.server.level.ServerLevel) EventContext(org.spongepowered.api.event.EventContext) Supplier(java.util.function.Supplier) EntityAnchorArgument(net.minecraft.commands.arguments.EntityAnchorArgument) CallbackInfoReturnable(org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable) CallbackInfo(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) MinecraftServer(net.minecraft.server.MinecraftServer) Mixin(org.spongepowered.asm.mixin.Mixin) CommandSourceStackBridge(org.spongepowered.common.bridge.commands.CommandSourceStackBridge) Map(java.util.Map) EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Nullable(org.checkerframework.checker.nullness.qual.Nullable) At(org.spongepowered.asm.mixin.injection.At) Mutable(org.spongepowered.asm.mixin.Mutable) Component(net.minecraft.network.chat.Component) Sponge(org.spongepowered.api.Sponge) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) Final(org.spongepowered.asm.mixin.Final) SpongePermissions(org.spongepowered.common.service.server.permission.SpongePermissions) CommandSourceBridge(org.spongepowered.common.bridge.commands.CommandSourceBridge) Cause(org.spongepowered.api.event.Cause) CommandCause(org.spongepowered.api.command.CommandCause) Entity(net.minecraft.world.entity.Entity) Vec2(net.minecraft.world.phys.Vec2) Vec3(net.minecraft.world.phys.Vec3) VecHelper(org.spongepowered.common.util.VecHelper) Shadow(org.spongepowered.asm.mixin.Shadow) CommandSource(net.minecraft.commands.CommandSource) ResultConsumer(com.mojang.brigadier.ResultConsumer) ServerLocation(org.spongepowered.api.world.server.ServerLocation) ServerLocation(org.spongepowered.api.world.server.ServerLocation) CommandSourceStackBridge(org.spongepowered.common.bridge.commands.CommandSourceStackBridge) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 14 with CauseStackManager

use of org.spongepowered.api.event.CauseStackManager in project SpongeCommon by SpongePowered.

the class PlayerMixin method impl$postSleepingEvent.

@Redirect(method = "tick()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;isSleeping()Z"))
private boolean impl$postSleepingEvent(final net.minecraft.world.entity.player.Player self) {
    if (self.isSleeping()) {
        if (!((LevelBridge) this.level).bridge$isFake()) {
            final CauseStackManager csm = PhaseTracker.getCauseStackManager();
            csm.pushCause(this);
            final BlockPos bedLocation = this.shadow$getSleepingPos().get();
            final BlockSnapshot snapshot = ((ServerWorld) this.level).createSnapshot(bedLocation.getX(), bedLocation.getY(), bedLocation.getZ());
            SpongeCommon.post(SpongeEventFactory.createSleepingEventTick(csm.currentCause(), snapshot, (Living) this));
            csm.popCause();
        }
        return true;
    }
    return false;
}
Also used : ServerWorld(org.spongepowered.api.world.server.ServerWorld) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Living(org.spongepowered.api.entity.living.Living) BlockSnapshot(org.spongepowered.api.block.BlockSnapshot) BlockPos(net.minecraft.core.BlockPos) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Aggregations

CauseStackManager (org.spongepowered.api.event.CauseStackManager)14 HashMap (java.util.HashMap)4 Map (java.util.Map)4 EventContextKeys (org.spongepowered.api.event.EventContextKeys)4 RconConnectionEvent (org.spongepowered.api.event.network.rcon.RconConnectionEvent)4 Inject (org.spongepowered.asm.mixin.injection.Inject)4 IOException (java.io.IOException)3 BlockPos (net.minecraft.core.BlockPos)3 BufferedInputStream (java.io.BufferedInputStream)2 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2 Collections (java.util.Collections)2 List (java.util.List)2 Optional (java.util.Optional)2 ExecutionException (java.util.concurrent.ExecutionException)2 DoubleUnaryOperator (java.util.function.DoubleUnaryOperator)2 Predicate (java.util.function.Predicate)2 Registry (net.minecraft.core.Registry)2 ListTag (net.minecraft.nbt.ListTag)2 Entity (net.minecraft.world.entity.Entity)2