@Override public Optional<ImmutableEyeLocationData> with( Key<? extends BaseValue<?>> key, Object value, ImmutableEyeLocationData immutable) { final Vector3d entityLocation = ((ImmutableSpongeEyeLocationData) immutable).getEntityLocation(); if (Keys.EYE_HEIGHT.equals(key)) { return Optional.<ImmutableEyeLocationData>of( new ImmutableSpongeEyeLocationData(entityLocation, ((Number) value).doubleValue())); } else if (Keys.EYE_LOCATION.equals(key)) { return Optional.<ImmutableEyeLocationData>of( new ImmutableSpongeEyeLocationData( entityLocation, ((Vector3d) value).getY() - entityLocation.getY())); } return Optional.absent(); }
@Listener public void onPlayerMove(DisplaceEntityEvent.Move.TargetPlayer playerMoveEvent) { Vector3d oldLocation = playerMoveEvent.getFromTransform().getPosition(); Vector3d newLocation = playerMoveEvent.getToTransform().getPosition(); if ((oldLocation.getFloorX() != newLocation.getFloorX() || oldLocation.getFloorZ() != newLocation.getFloorZ())) { checkLoginStatus(playerMoveEvent, playerMoveEvent.getTargetEntity()); } }
@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(); } } } }
@Override public Optional<Entity> createEntity(EntityType type, Vector3d position) { checkNotNull(type, "The entity type cannot be null!"); checkNotNull(position, "The position cannot be null!"); Entity entity = null; Class<? extends Entity> entityClass = type.getEntityClass(); double x = position.getX(); double y = position.getY(); double z = position.getZ(); if (entityClass.isAssignableFrom(EntityPlayerMP.class) || entityClass.isAssignableFrom(EntityDragonPart.class)) { // Unable to construct these return Optional.empty(); } net.minecraft.world.World world = (net.minecraft.world.World) (Object) this; // Not all entities have a single World parameter as their constructor if (entityClass.isAssignableFrom(EntityLightningBolt.class)) { entity = (Entity) new EntityLightningBolt(world, x, y, z); } else if (entityClass.isAssignableFrom(EntityEnderPearl.class)) { EntityArmorStand tempEntity = new EntityArmorStand(world, x, y, z); tempEntity.posY -= tempEntity.getEyeHeight(); entity = (Entity) new EntityEnderPearl(world, tempEntity); ((EnderPearl) entity).setShooter(ProjectileSource.UNKNOWN); } // Some entities need to have non-null fields (and the easiest way to // set them is to use the more specialised constructor). if (entityClass.isAssignableFrom(EntityFallingBlock.class)) { entity = (Entity) new EntityFallingBlock(world, x, y, z, Blocks.sand.getDefaultState()); } else if (entityClass.isAssignableFrom(EntityItem.class)) { entity = (Entity) new EntityItem(world, x, y, z, new ItemStack(Blocks.stone)); } if (entity == null) { try { entity = ConstructorUtils.invokeConstructor(entityClass, this); ((net.minecraft.entity.Entity) entity).setPosition(x, y, z); } catch (Exception e) { SpongeImpl.getLogger().error(ExceptionUtils.getStackTrace(e)); } } // TODO - replace this with an actual check /* if (entity instanceof EntityHanging) { if (((EntityHanging) entity).facingDirection == null) { // TODO Some sort of detection of a valid direction? // i.e scan immediate blocks for something to attach onto. ((EntityHanging) entity).facingDirection = EnumFacing.NORTH; } if (!((EntityHanging) entity).onValidSurface()) { return Optional.empty(); } }*/ // Last chance to fix null fields if (entity instanceof EntityPotion) { // make sure EntityPotion.potionDamage is not null ((EntityPotion) entity).getPotionDamage(); } else if (entity instanceof EntityPainting) { // This is default when art is null when reading from NBT, could // choose a random art instead? ((EntityPainting) entity).art = EnumArt.KEBAB; } return Optional.ofNullable(entity); }
@Subscribe public void onWorldChange(EntityTeleportEvent event) { Entity entity = event.getEntity(); if (entity instanceof Player) { org.spongepowered.api.world.Location from = event.getOldLocation(); org.spongepowered.api.world.Location to = event.getNewLocation(); int x2; if (getInt(from.getX()) != (x2 = getInt(to.getX()))) { Player player = (Player) entity; PlotPlayer pp = SpongeUtil.getPlayer(player); Extent extent = to.getExtent(); if (!(extent instanceof World)) { pp.deleteMeta("location"); return; } pp.setMeta("location", SpongeUtil.getLocation(player)); World world = (World) extent; String worldname = ((World) extent).getName(); PlotWorld plotworld = PS.get().getPlotWorld(worldname); if (plotworld == null) { return; } PlotManager plotManager = PS.get().getPlotManager(worldname); PlotId id = plotManager.getPlotId(plotworld, x2, 0, getInt(to.getZ())); Plot lastPlot = (Plot) pp.getMeta("lastplot"); if (id == null) { if (lastPlot == null) { return; } if (!PlotListener.plotExit(pp, lastPlot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED); if (lastPlot.equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { event.setNewLocation(from); } else { event.setNewLocation(world.getSpawnLocation()); } return; } } else if (lastPlot != null && id.equals(lastPlot.id)) { return; } else { Plot plot = MainUtil.getPlot(worldname, id); if (!PlotListener.plotEntry(pp, plot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED); if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { event.setNewLocation(from); } else { event.setNewLocation(world.getSpawnLocation()); } return; } } Integer border = MainUtil.worldBorder.get(worldname); if (border != null) { if (x2 > border) { Vector3d pos = to.getPosition(); to = to.setPosition(new Vector3d(border - 4, pos.getY(), pos.getZ())); event.setNewLocation(to); MainUtil.sendMessage(pp, C.BORDER); } else if (x2 < -border) { Vector3d pos = to.getPosition(); to = to.setPosition(new Vector3d(-border + 4, pos.getY(), pos.getZ())); event.setNewLocation(to); MainUtil.sendMessage(pp, C.BORDER); } } return; } int z2; if (getInt(from.getZ()) != (z2 = getInt(to.getZ()))) { Player player = (Player) entity; PlotPlayer pp = SpongeUtil.getPlayer(player); Extent extent = to.getExtent(); if (!(extent instanceof World)) { pp.deleteMeta("location"); return; } pp.setMeta("location", SpongeUtil.getLocation(player)); World world = (World) extent; String worldname = ((World) extent).getName(); PlotWorld plotworld = PS.get().getPlotWorld(worldname); if (plotworld == null) { return; } PlotManager plotManager = PS.get().getPlotManager(worldname); PlotId id = plotManager.getPlotId(plotworld, x2, 0, z2); Plot lastPlot = (Plot) pp.getMeta("lastplot"); if (id == null) { if (lastPlot == null) { return; } if (!PlotListener.plotExit(pp, lastPlot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_EXIT_DENIED); if (lastPlot.equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { event.setNewLocation(from); } else { event.setNewLocation(player.getWorld().getSpawnLocation()); } return; } } else if (lastPlot != null && id.equals(lastPlot.id)) { return; } else { Plot plot = MainUtil.getPlot(worldname, id); if (!PlotListener.plotEntry(pp, plot)) { MainUtil.sendMessage(pp, C.NO_PERMISSION_EVENT, C.PERMISSION_ADMIN_ENTRY_DENIED); if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(worldname, from)))) { event.setNewLocation(from); } else { event.setNewLocation(player.getWorld().getSpawnLocation()); } return; } } Integer border = MainUtil.worldBorder.get(worldname); if (border != null) { if (z2 > border) { Vector3d pos = to.getPosition(); to = to.setPosition(new Vector3d(pos.getX(), pos.getY(), border - 4)); event.setNewLocation(to); MainUtil.sendMessage(pp, C.BORDER); } else if (z2 < -border) { Vector3d pos = to.getPosition(); to = to.setPosition(new Vector3d(pos.getX(), pos.getY(), -border + 4)); event.setNewLocation(to); MainUtil.sendMessage(pp, C.BORDER); } } } } }
@Subscribe public void onBigBoom(final WorldOnExplosionEvent event) { World worldObj = event.getWorld(); final String world = worldObj.getName(); if (!PS.get().isPlotWorld(world)) { return; } Explosion explosion = event.getExplosion(); Vector3d origin = explosion.getOrigin(); Location loc = new Location(world, origin.getFloorX(), origin.getFloorY(), origin.getFloorZ()); final Plot plot = MainUtil.getPlot(loc); if ((plot != null) && plot.hasOwner()) { if (FlagManager.isPlotFlagTrue(plot, "explosion")) { event.filterLocations( new Predicate<org.spongepowered.api.world.Location<World>>() { @Override public boolean apply(org.spongepowered.api.world.Location loc) { if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(loc)))) { return false; } return true; } }); event.filterEntities( new Predicate<Entity>() { @Override public boolean apply(Entity entity) { if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(entity)))) { return false; } return true; } }); return; } } if (MainUtil.isPlotArea(loc)) { explosion.shouldBreakBlocks(false); explosion.canCauseFire(false); explosion.setRadius(0); event.filterEntities( new Predicate<Entity>() { @Override public boolean apply(Entity entity) { if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(entity)))) { return false; } return true; } }); return; } else { if (FlagManager.isPlotFlagTrue(plot, "explosion")) { event.filterLocations( new Predicate<org.spongepowered.api.world.Location<World>>() { @Override public boolean apply(org.spongepowered.api.world.Location loc) { if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(loc)))) { return false; } return true; } }); event.filterEntities( new Predicate<Entity>() { @Override public boolean apply(Entity entity) { if (!plot.equals(MainUtil.getPlot(SpongeUtil.getLocation(entity)))) { return false; } return true; } }); return; } } }