@Inject(
     method = "newExplosion",
     at = @At(value = "INVOKE", target = "Lnet/minecraft/world/Explosion;doExplosionA()V"),
     locals = LocalCapture.CAPTURE_FAILHARD,
     cancellable = true)
 public void callWorldOnExplosionEvent(
     Entity entityIn,
     double x,
     double y,
     double z,
     float strength,
     boolean isFlaming,
     boolean isSmoking,
     CallbackInfoReturnable<Explosion> cir,
     Explosion explosion) {
   final ExplosionEvent.Pre event =
       SpongeEventFactory.createExplosionEventPre(
           Sponge.getGame(),
           Cause.of(this),
           (org.spongepowered.api.world.explosion.Explosion) explosion,
           (org.spongepowered.api.world.World) this);
   if (Sponge.getGame().getEventManager().post(event)) {
     cir.setReturnValue(explosion);
   }
 }
  /**
   * @Author Zidane
   *
   * <p>Invoke before {@code System.arraycopy(packetIn.getLines(), 0, tileentitysign.signText, 0,
   * 4);} (line 1156 in source) to call SignChangeEvent.
   *
   * @param packetIn Injected packet param
   * @param ci Info to provide mixin on how to handle the callback
   * @param worldserver Injected world param
   * @param blockpos Injected blockpos param
   * @param tileentity Injected tilentity param
   * @param tileentitysign Injected tileentitysign param
   */
  @Inject(
      method = "processUpdateSign",
      at =
          @At(
              value = "INVOKE",
              target =
                  "Lnet/minecraft/network/play/client/C12PacketUpdateSign;getLines()[Lnet/minecraft/util/IChatComponent;"),
      cancellable = true,
      locals = LocalCapture.CAPTURE_FAILSOFT)
  public void callSignChangeEvent(
      C12PacketUpdateSign packetIn,
      CallbackInfo ci,
      WorldServer worldserver,
      BlockPos blockpos,
      TileEntity tileentity,
      TileEntitySign tileentitysign) {
    ci.cancel();
    final Optional<SignData> existingSignData = ((Sign) tileentitysign).getData();
    if (!existingSignData.isPresent()) {
      // TODO Unsure if this is the best to do here...
      throw new RuntimeException("Critical error! Sign data not present on sign!");
    }
    final SignData changedSignData = existingSignData.get().copy();

    for (int i = 0; i < packetIn.getLines().length; i++) {
      changedSignData.setLine(i, SpongeTexts.toText(packetIn.getLines()[i]));
    }
    // I pass changedSignData in here twice to emulate the fact that even-though the current sign
    // data doesn't have the lines from the packet
    // applied, this is what it "is" right now. If the data shown in the world is desired, it can be
    // fetched from Sign.getData
    final SignChangeEvent event =
        SpongeEventFactory.createSignChange(
            Sponge.getGame(),
            new Cause(null, this.playerEntity, null),
            (Sign) tileentitysign,
            changedSignData,
            changedSignData);
    if (!Sponge.getGame().getEventManager().post(event)) {
      ((Sign) tileentitysign).offer(event.getNewData());
    } else {
      // If cancelled, I set the data back that was fetched from the sign. This means that if its a
      // new sign, the sign will be empty else
      // it will be the text of the sign that was showing in the world
      ((Sign) tileentitysign).offer(existingSignData.get());
    }
    tileentitysign.markDirty();
    worldserver.markBlockForUpdate(blockpos);
  }
 /**
  * @author Simon816
  *     <p>Fire the PlayerQuitEvent before playerLoggedOut is called in order for event handlers to
  *     change the quit message captured from {@link #onSendChatMsgCall}.
  */
 @Inject(
     method = "onDisconnect",
     at =
         @At(
             value = "INVOKE",
             target =
                 "Lnet/minecraft/server/management/ServerConfigurationManager;playerLoggedOut(Lnet/minecraft/entity/player/EntityPlayerMP;)V"))
 public void onDisconnectPlayer(IChatComponent reason, CallbackInfo ci) {
   PlayerQuitEvent event =
       SpongeImplEventFactory.createPlayerQuit(
           Sponge.getGame(),
           (Player) this.playerEntity,
           SpongeTexts.toText(this.tmpQuitMessage),
           ((Player) this.playerEntity).getMessageSink());
   this.tmpQuitMessage = null;
   Sponge.getGame().getEventManager().post(event);
   event.getSink().sendMessage(event.getNewMessage());
 }
示例#4
0
 @Inject(
     method = "randomTick",
     at = @At(value = "HEAD"),
     locals = LocalCapture.CAPTURE_FAILEXCEPTION,
     cancellable = true)
 public void callRandomTickEvent(
     World world, BlockPos pos, IBlockState state, Random rand, CallbackInfo ci) {
   final BlockRandomTickEvent event =
       SpongeEventFactory.createBlockRandomTick(
           Sponge.getGame(),
           null,
           new Location<org.spongepowered.api.world.World>(
               (org.spongepowered.api.world.World) world,
               VecHelper.toVector(pos))); // TODO Fix null Cause
   Sponge.getGame().getEventManager().post(event);
   if (event.isCancelled()) {
     ci.cancel();
   }
 }
  @Inject(
      method = "processPlayer",
      at =
          @At(
              value = "FIELD",
              target = "net.minecraft.network.NetHandlerPlayServer.hasMoved:Z",
              ordinal = 2),
      cancellable = true)
  public void proccesPlayerMoved(C03PacketPlayer packetIn, CallbackInfo ci) {
    if (packetIn.isMoving() || packetIn.getRotating() && !this.playerEntity.isDead) {
      Player player = (Player) this.playerEntity;
      Vector3d fromrot = player.getRotation();

      // If Sponge used the player's current location, the delta might never be triggered which
      // could be exploited
      Location from = player.getLocation();
      if (this.lastMoveLocation != null) {
        from = this.lastMoveLocation;
      }

      Vector3d torot = new Vector3d(packetIn.getPitch(), packetIn.getYaw(), 0);
      Location to =
          new Location(
              player.getWorld(),
              packetIn.getPositionX(),
              packetIn.getPositionY(),
              packetIn.getPositionZ());

      // Minecraft sends a 0, 0, 0 position when rotation only update occurs, this needs to be
      // recognized and corrected
      boolean rotationOnly = !packetIn.isMoving() && packetIn.getRotating();
      if (rotationOnly) {
        // Correct the to location so it's not misrepresented to plugins, only when player rotates
        // without moving
        // In this case it's only a rotation update, which isn't related to the to location
        from = player.getLocation();
        to = from;
      }

      // Minecraft does the same with rotation when it's only a positional update
      boolean positionOnly = packetIn.isMoving() && !packetIn.getRotating();
      if (positionOnly) {
        // Correct the new rotation to match the old rotation
        torot = fromrot;
      }

      double deltaSquared = to.getPosition().distanceSquared(from.getPosition());
      double deltaAngleSquared = fromrot.distanceSquared(torot);

      // These magic numbers are sad but help prevent excessive lag from this event.
      // eventually it would be nice to not have them
      if (deltaSquared > ((1f / 16) * (1f / 16)) || deltaAngleSquared > (.15f * .15f)) {
        PlayerMoveEvent event =
            SpongeEventFactory.createPlayerMove(Sponge.getGame(), player, from, to, torot);
        Sponge.getGame().getEventManager().post(event);
        if (event.isCancelled()) {
          player.setLocationAndRotation(from, fromrot);
          this.lastMoveLocation = from;
          ci.cancel();
        } else if (!event.getNewLocation().equals(to)) {
          player.setLocationAndRotation(event.getNewLocation(), event.getRotation());
          this.lastMoveLocation = event.getNewLocation();
          ci.cancel();
        } else if (!from.equals(player.getLocation()) && this.justTeleported) {
          this.lastMoveLocation = player.getLocation();
          // Prevent teleports during the move event from causing odd behaviors
          this.justTeleported = false;
          ci.cancel();
        } else {
          this.lastMoveLocation = event.getNewLocation();
        }
      }
    }
  }
  private SpongeVanilla() {
    Guice.createInjector(new VanillaGuiceModule(this, LogManager.getLogger("Sponge")))
        .getInstance(Sponge.class);

    this.game = Sponge.getGame();
  }