Package org.getspout.spout.listeners

Source Code of org.getspout.spout.listeners.PostWorldTeleport

/*
* This file is part of SpoutcraftPlugin.
*
* Copyright (c) 2011 SpoutcraftDev <http://spoutcraft.org//>
* SpoutcraftPlugin is licensed under the GNU Lesser General Public License.
*
* SpoutcraftPlugin is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SpoutcraftPlugin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.getspout.spout.listeners;

import java.lang.reflect.Field;
import java.util.Iterator;

import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;

import org.getspout.spout.PlayerChunkMap;
import org.getspout.spout.Spout;
import org.getspout.spout.config.PermHandler;
import org.getspout.spout.inventory.SimpleMaterialManager;
import org.getspout.spout.player.SimplePlayerChunkMap;
import org.getspout.spout.player.SpoutCraftPlayer;
import org.getspout.spoutapi.SpoutManager;
import org.getspout.spoutapi.block.SpoutBlock;
import org.getspout.spoutapi.inventory.SpoutEnchantment;
import org.getspout.spoutapi.inventory.SpoutItemStack;
import org.getspout.spoutapi.material.CustomBlock;
import org.getspout.spoutapi.material.CustomItem;
import org.getspout.spoutapi.material.MaterialData;
import org.getspout.spoutapi.packet.PacketAllowVisualCheats;
import org.getspout.spoutapi.player.SpoutPlayer;

public class SpoutPlayerListener implements Listener {
  public final PlayerChunkMap manager = new PlayerChunkMap();

  public SpoutPlayerListener(Spout plugin) {
    Bukkit.getPluginManager().registerEvents(this, plugin);
  }

  @EventHandler(priority = EventPriority.LOWEST)
  public void onPlayerJoin(final PlayerJoinEvent event) {
    if (!event.getPlayer().getClass().equals(SpoutCraftPlayer.class)) {
      SpoutCraftPlayer.updatePlayerConnection(event.getPlayer());
      SpoutCraftPlayer.updateBukkitEntity(event.getPlayer());
      updatePlayerEvent(event);
      Spout.getInstance().authenticate(event.getPlayer());
      SpoutCraftPlayer player = (SpoutCraftPlayer)SpoutCraftPlayer.getPlayer(event.getPlayer());
    }
    ((SimplePlayerChunkMap)SpoutManager.getPlayerChunkMap()).onPlayerJoin(event.getPlayer());
    manager.onPlayerJoin(event.getPlayer());
    synchronized(Spout.getInstance().getOnlinePlayers()) {
      Spout.getInstance().getOnlinePlayers().add((SpoutPlayer) event.getPlayer());
    }
  }

  @EventHandler
  public void onPlayerKick(PlayerKickEvent event) {
    if (event.getPlayer() instanceof SpoutCraftPlayer) {
      SpoutCraftPlayer player = (SpoutCraftPlayer)event.getPlayer();
      if (event.getReason().equals("You moved too quickly :( (Hacking?)")) {
        if (player.canFly()) {
          event.setCancelled(true);
        }
        if (System.currentTimeMillis() < player.velocityAdjustmentTime) {
          event.setCancelled(true);
        }
      }
    }
  }

  @EventHandler(priority = EventPriority.LOWEST)
  public void onPlayerTeleport(PlayerTeleportEvent event) {
    SpoutPlayer splr = SpoutManager.getPlayer(event.getPlayer());
    if (event.getCause() == TeleportCause.UNKNOWN && splr.isSpoutCraftEnabled() && splr.isFlying() && splr.getFlySpeed() > 1.0f) {
      event.setCancelled(true);
    }
  }

  @EventHandler(priority = EventPriority.MONITOR)
  public void onPlayerTeleportMonitor(final PlayerTeleportEvent event) {
    if (!(event.getPlayer() instanceof SpoutPlayer)) {
      updatePlayerEvent(event);
    }
    if (event.isCancelled()) {
      return;
    }

    Runnable update = null;
    final SpoutCraftPlayer scp = (SpoutCraftPlayer)SpoutCraftPlayer.getPlayer(event.getPlayer());

    if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
      update = new PostTeleport(scp);
    } else {
      update = new PostWorldTeleport(scp);
    }
    if (update != null) {
      Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(Spout.getInstance(), update, 2);
    }
    if (event.getPlayer() instanceof SpoutPlayer) {
      scp.sendPacket(new PacketAllowVisualCheats(PermHandler.allowSkyCheat(scp),PermHandler.forceSkyCheat(scp),PermHandler.showSkyCheat(scp),PermHandler.allowClearWaterCheat(scp),PermHandler.forceClearWaterCheat(scp),PermHandler.showClearWaterCheat(scp),PermHandler.allowStarsCheat(scp),PermHandler.forceStarsCheat(scp),PermHandler.showStarsCheat(scp),PermHandler.allowWeatherCheat(scp),PermHandler.forceWeatherCheat(scp),PermHandler.showWeatherCheat(scp),PermHandler.allowTimeCheat(scp),PermHandler.allowCoordsCheat(scp),PermHandler.allowEntityLabelCheat(scp),PermHandler.allowVoidFogCheat(scp),PermHandler.forceVoidFogCheat(scp),PermHandler.showVoidFogCheat(scp),PermHandler.allowFlightSpeedCheat(scp)));
    }
  }

  @EventHandler(priority = EventPriority.MONITOR)
  public void onPlayerInteract(PlayerInteractEvent event) {
    if (!(event.getPlayer() instanceof SpoutPlayer)) {
      updatePlayerEvent(event);
    }
    if (event.isCancelled()) {
      return;
    }
    if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
      return;
    }

    SpoutCraftPlayer player = (SpoutCraftPlayer) SpoutCraftPlayer.getPlayer(event.getPlayer());

    if (event.getClickedBlock() != null) {
      boolean action = false;

      switch (event.getClickedBlock().getType()) {
      case BREWING_STAND:
      case CHEST:
      case DISPENSER:
      case ENCHANTMENT_TABLE:
      case FURNACE:
      case WORKBENCH:
      case BED_BLOCK:
      case CAKE_BLOCK:
      case CAULDRON:
      case DIODE_BLOCK_OFF:
      case DIODE_BLOCK_ON:
      case FENCE_GATE:
      case IRON_DOOR_BLOCK:
      case LEVER:
      case NOTE_BLOCK:
      case STONE_BUTTON:
      case TRAP_DOOR:
      case WOODEN_DOOR:
        action = true;
        break;
      }

      if (event.hasItem() && !action) {
        SpoutBlock block = (SpoutBlock)event.getClickedBlock().getRelative(event.getBlockFace());

        if (event.getClickedBlock().getType() == Material.SNOW) {
          block = block.getRelative(0, -1, 0);
        }

        ItemStack item = event.getItem();
        int damage = item.getDurability();
        if (item.getType() == Material.FLINT && damage != 0) {
          SimpleMaterialManager mm = (SimpleMaterialManager)SpoutManager.getMaterialManager();

          if (!player.getEyeLocation().getBlock().equals(block) && !player.getLocation().getBlock().equals(block)) {
            CustomBlock cb = MaterialData.getCustomBlock(damage);

            if (cb != null && isReplaceable(block.getType())) {
              BlockState oldState = block.getState();
              block.setTypeIdAndData(cb.getBlockId(), (byte)(cb.getBlockData()), true);
              cb.onBlockPlace(block.getWorld(), block.getX(), block.getY(), block.getZ(), player);

              int rot = Math.round(player.getLocation().getYaw() + 45 % 360);
              boolean mirrored = player.getLocation().getPitch() < -45;
              if (rot < 0 ) {
                rot += 360;
              }
              rot = (2 - (rot/90)) % 4;
              if (rot < 0) {
                rot += 4;
              }
              byte rotation;
              if (cb.canMirroredRotate() && mirrored) {
                rotation = cb.canRotate() ? (byte) (rot + 4) : 4;
              } else {
                rotation = cb.canRotate() ? (byte) rot : 0;
              }
              mm.overrideBlock(block, cb, rotation);

              if (canPlaceAt(block, oldState, (SpoutBlock)event.getClickedBlock(), item, player)) {
                // Yay, take the item from inventory
                if (player.getGameMode() == GameMode.SURVIVAL) {
                  if (item.getAmount() == 1) {
                  // Remove this for Stuff 
                  event.getPlayer().setItemInHand(null);
                  } else {
                    item.setAmount(item.getAmount() - 1);
                  }
                }
                player.playSound(player.getLocation(), Sound.DIG_STONE, 1.0F, 0.7936508F);
                player.updateInventory();
                // Now we have placed a nice custom block! We should check its rotation and rotate the base block!
                if (cb.canRotate()) {
                  if (cb.canMirroredRotate() && mirrored) {
                    if (block.getType() == Material.LEVER || block.getType() == Material.TORCH || block.getType() == Material.STONE_BUTTON || block.getType() == Material.WOOD_BUTTON) {
                      // The below Types need a slightly different data value to assign correct positioning.
                      if (event.getBlockFace() == BlockFace.UP) {
                        block.setData((byte) 5);
                      } else if (event.getBlockFace() == BlockFace.DOWN) {
                        block.setData((byte) 7);
                      } else if (rot == 1) {
                        block.setData((byte) 1);
                      } else if (rot == 2) {
                        block.setData((byte) 4);
                      } else if (rot == 3) {
                        block.setData((byte) 2);
                      } else if (rot == 0) {
                        block.setData((byte) 3);
                      }
                    } else {
                      if (rot == 1) {
                        block.setData((byte) 5);
                      } else if (rot == 2) {
                        block.setData((byte) 6);
                      } else if (rot == 3) {
                        block.setData((byte) 4);
                      } else {
                        block.setData((byte) 7);
                      }
                    }
                  } else {
                    if (block.getType() == Material.LEVER || block.getType() == Material.TORCH || block.getType() == Material.STONE_BUTTON || block.getType() == Material.WOOD_BUTTON) {
                      // The below Types need a slightly different data value to assign correct positioning.
                      if (event.getBlockFace() == BlockFace.UP) {
                        block.setData((byte) 5);
                      } else if (event.getBlockFace() == BlockFace.DOWN) {
                        block.setData((byte) 7);
                      } else if (rot == 1) {
                        block.setData((byte) 1);
                      } else if (rot == 2) {
                        block.setData((byte) 4);
                      } else if (rot == 3) {
                        block.setData((byte) 2);
                      } else if (rot == 0) {
                        block.setData((byte) 3);
                      }
                    } else {
                      if (rot == 1) {
                        block.setData((byte) 1);
                      } else if (rot == 2) {
                        block.setData((byte) 2);
                      } else if (rot == 3) {
                        block.setData((byte) 0);
                      } else if (rot == 0 ){
                        block.setData((byte) 3);
                      }
                    }
                  }
                }
              } else {
                // Event cancelled or can't build
                mm.removeBlockOverride(block);
                block.setTypeIdAndData(oldState.getTypeId(), oldState.getRawData(), true);
              }
            }
          }
        }
      }
    }
  }

  private boolean isReplaceable(Material type) {
    return type == Material.WATER || type == Material.STATIONARY_WATER || type == Material.LAVA || type == Material.STATIONARY_LAVA || type == Material.FIRE || type == Material.SNOW || type == Material.AIR || type == Material.VINE || type == Material.DEAD_BUSH || type == Material.LONG_GRASS;
  }

  // TODO canBuild should be set properly, CraftEventFactory.canBuild() would do this... but it's private so... here it is >.>
  private boolean canPlaceAt(SpoutBlock result, BlockState oldState, SpoutBlock clicked, ItemStack item, SpoutPlayer player) {
    int spawnRadius = Bukkit.getServer().getSpawnRadius();
    boolean canBuild = spawnRadius <= 0 || player.isOp();
    if (!canBuild) {
      Location spawn = clicked.getWorld().getSpawnLocation();
      if (Math.max(Math.abs(result.getX()-spawn.getBlockX()), Math.abs(result.getZ()-spawn.getBlockZ())) > spawnRadius) { // Slower check
        canBuild = true;
      }
    }

    BlockPlaceEvent placeEvent = new BlockPlaceEvent(result, oldState, clicked, item, player, canBuild);
    Bukkit.getPluginManager().callEvent(placeEvent);

    return !placeEvent.isCancelled() && placeEvent.canBuild();
  }

  private void updatePlayerEvent(PlayerEvent event) {
    try {
      Field player = PlayerEvent.class.getDeclaredField("player");
      player.setAccessible(true);
      player.set(event, SpoutCraftPlayer.getPlayer(event.getPlayer()));
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  @EventHandler(priority = EventPriority.LOWEST)
  public void onPlayerQuit(PlayerQuitEvent event) {
    Player player = event.getPlayer();
    synchronized(Spout.getInstance().getOnlinePlayers()) {
      Iterator<SpoutPlayer> i = Spout.getInstance().getOnlinePlayers().iterator();
      while (i.hasNext()) {
        String name = i.next().getName();
        if (name.equals(player.getName())) {
          i.remove();
        }
      }
    }
  }

  @EventHandler(priority = EventPriority.LOWEST)
  public void onPlayerDrop(PlayerDropItemEvent e) {
    SpoutItemStack sis = new SpoutItemStack(e.getItemDrop().getItemStack());
    if (!sis.containsEnchantment(SpoutEnchantment.UNSTACKABLE) && sis.isCustomItem()) {
      CustomItem ci = (CustomItem)sis.getMaterial();
      if (!ci.isStackable()) {
        sis.addEnchantment(SpoutEnchantment.UNSTACKABLE, 1000);
      }
    }
    e.getItemDrop().setItemStack(sis);
  }

  @EventHandler(priority = EventPriority.LOWEST)
  public void onPlayerPickupItem(PlayerPickupItemEvent e) {
    SpoutItemStack sis = new SpoutItemStack(e.getItem().getItemStack());
    if (!sis.containsEnchantment(SpoutEnchantment.UNSTACKABLE) && sis.isCustomItem()) {
      CustomItem ci = (CustomItem)sis.getMaterial();
      if (!ci.isStackable()) {
        sis.addEnchantment(SpoutEnchantment.UNSTACKABLE, 1000);
      }
    }
    e.getItem().setItemStack(sis);
  }
}

class PostTeleport implements Runnable {
  SpoutCraftPlayer player;
  public PostTeleport(SpoutCraftPlayer player) {
    this.player = player;
  }

  @Override
  public void run() {
    player.updateAppearance(player);
  }
}

class PostWorldTeleport implements Runnable {
  SpoutCraftPlayer player;
  public PostWorldTeleport(SpoutCraftPlayer player) {
    this.player = player;
  }

  @Override
  public void run() {
    player.updateAppearance(player);
    player.updateWaypoints();
  }
}
TOP

Related Classes of org.getspout.spout.listeners.PostWorldTeleport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.