@EventHandler(priority = EventPriority.NORMAL)
	public void onPlayerInteract(final PlayerInteractEvent event)
	{
		final IUser user = userMap.getUser(event.getPlayer());
		user.updateActivity(true);
		switch (event.getAction())
		{
		case RIGHT_CLICK_BLOCK:
			if (event.isCancelled())
			{
				return;
			}

			final ISettings settings = ess.getSettings();
			if (settings.getData().getCommands().getHome().isUpdateBedAtDaytime() && event.getClickedBlock().getType() == Material.BED_BLOCK)
			{
				event.getPlayer().setBedSpawnLocation(event.getClickedBlock().getLocation());
			}
			break;
		case LEFT_CLICK_AIR:
		case LEFT_CLICK_BLOCK:
			if (user.getData().hasPowerTools() && user.getData().isPowerToolsEnabled())
			{
				if (usePowertools(user))
				{
					event.setCancelled(true);
				}
			}
			break;
		default:
			break;
		}
	}
	@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
	public void onPlayerMove(final PlayerMoveEvent event)
	{
		final IUser user = userMap.getUser(event.getPlayer());

		final ISettings settings = ess.getSettings();

		if (user.getData().isAfk() && settings.getData().getCommands().getAfk().isFreezeAFKPlayers())
		{
			final Location from = event.getFrom();
			final Location to = event.getTo().clone();
			to.setX(from.getX());
			to.setY(from.getY());
			to.setZ(from.getZ());
			try
			{
				event.setTo(LocationUtil.getSafeDestination(to));
			}
			catch (Exception ex)
			{
				event.setTo(to);
			}
			return;
		}

		final Location afk = user.getAfkPosition();
		if (afk == null || !event.getTo().getWorld().equals(afk.getWorld()) || afk.distanceSquared(event.getTo()) > 9)
		{
			user.updateActivity(true);
		}
	}
	@EventHandler(priority = EventPriority.MONITOR)
	public void onPlayerQuit(final PlayerQuitEvent event)
	{
		final String quitMessage = ess.getSettings().getData().getGeneral().getLeaveMessage();
		if (quitMessage != null)
		{
			final IText itOutput = new KeywordReplacer(new SimpleTextInput(quitMessage), userMap.getUser(event.getPlayer()), ess);
			final SimpleTextPager stPager = new SimpleTextPager(itOutput);
			event.setQuitMessage(FormatUtil.replaceFormat(stPager.getString(0)));
		}
		else
		{
			event.setQuitMessage(null);
		}


		final IUser user = userMap.getUser(event.getPlayer());

		final ISettings settings = ess.getSettings();
		if (settings.getData().getCommands().getGod().isRemoveOnDisconnect() && user.isGodModeEnabled())
		{
			user.setGodModeEnabled(false);
		}
		if (user.isVanished())
		{
			user.toggleVanished();
		}
		if (user.getData().getInventory() != null)
		{
			user.getPlayer().getInventory().setContents(user.getData().getInventory().getBukkitInventory());
			user.getData().setInventory(null);
		}
		user.updateActivity(false);
		//user.getPlayer().dispose();
		if (settings.getData().getGeneral().isPtClearOnQuit())
		{
			user.getData().clearAllPowertools();
			user.queueSave();
			user.sendMessage(_("§6All powertool commands have been cleared."));
		}
	}
	@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
	public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event)
	{
		final IUser user = userMap.getUser(event.getPlayer());
		final String cmd = spaceSplit.split(event.getMessage().toLowerCase(Locale.ENGLISH))[0].replace("/", "").toLowerCase(Locale.ENGLISH);
		if (ess.getSettings().getData().getCommands().getSocialspy().getSocialspyCommands().contains(cmd))
		{
			for (Player player : ess.getServer().getOnlinePlayers())
			{
				IUser spyer = userMap.getUser(player);
				if (spyer.getData().isSocialspy() && !user.equals(spyer))
				{
					player.sendMessage(user.getPlayer().getDisplayName() + " : " + event.getMessage());
				}
			}
		}
		if (!cmd.equalsIgnoreCase("afk"))
		{
			user.updateActivity(true);
		}
	}
	@EventHandler(priority = EventPriority.LOWEST)
	public void onPlayerChat(final AsyncPlayerChatEvent event) // TODO: Does this update work?
	{
		final IUser user = userMap.getUser(event.getPlayer());
		if (user.getData().isMuted())
		{
			event.setCancelled(true);
			user.sendMessage(_("§6You have been muted!"));
			ess.getLogger().info(_("{0} tried to speak, but is muted.", user.getName()));
		}
		final Iterator<Player> it = event.getRecipients().iterator();
		while (it.hasNext())
		{
			final IUser u = userMap.getUser(it.next());
			if (u.getData().getIgnore().contains(user.getName()))
			{
				it.remove();
			}
		}
		user.updateActivity(true);
		user.setDisplayNick();
	}
	@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
	public void onPlayerFishEvent(final PlayerFishEvent event)
	{
		final IUser user = userMap.getUser(event.getPlayer());
		user.updateActivity(true);
	}
	public void delayedJoin(final Player player)
	{
		if (!player.isOnline())
		{
			return;
		}
		ess.getBackup().startTask();
		final IUser user = userMap.getUser(player);
		user.setDisplayNick();
		user.updateCompass();
		user.getData().setTimestamp(TimestampType.LOGIN, System.currentTimeMillis());
		user.updateActivity(false);

		if (!ess.getVanishedPlayers().isEmpty() && !Permissions.VANISH_SEE_OTHERS.isAuthorized(user))
		{
			for (String p : ess.getVanishedPlayers())
			{
				final Player toVanish = userMap.getUser(p).getPlayer();
				if (toVanish.isOnline())
				{
					user.setVanished(true);
				}
			}
		}

		if (Permissions.SLEEPINGIGNORED.isAuthorized(user))
		{
			ess.getPlugin().scheduleSyncDelayedTask(
					new Runnable()
					{
						@Override
						public void run()
						{
							user.getPlayer().setSleepingIgnored(true);
						}
					});
		}

		final Commands settings = ess.getSettings().getData().getCommands();

		if (!settings.isDisabled("motd") && Permissions.MOTD.isAuthorized(user))
		{
			try
			{
				final IText input = new TextInput(user, "motd", true, ess);
				final IText output = new KeywordReplacer(input, user, ess);
				final TextPager pager = new TextPager(output, true);
				pager.showPage("1", null, "motd", user);
			}
			catch (IOException ex)
			{
				if (ess.getSettings().isDebug())
				{
					ess.getLogger().log(Level.WARNING, ex.getMessage(), ex);
				}
				else
				{
					ess.getLogger().log(Level.WARNING, ex.getMessage());
				}
			}
		}

		if (!settings.isDisabled("mail") && Permissions.MAIL.isAuthorized(user))
		{
			final List<String> mail = user.getMails();
			if (mail.isEmpty())
			{
				final String msg = _("§6You have no new mail.");
				if (!msg.isEmpty())
				{
					user.sendMessage(msg);
				}
			}
			else
			{
				user.sendMessage(_("§6You have§c {0} §6messages! Type §c/mail read§6 to view your mail.", mail.size()));
			}
		}
		if (Permissions.FLY_SAFELOGIN.isAuthorized(user))
		{
			final Location loc = user.getPlayer().getLocation();
			final World world = loc.getWorld();
			final int x = loc.getBlockX();
			int y = loc.getBlockY();
			final int z = loc.getBlockZ();
			while (LocationUtil.isBlockUnsafe(world, x, y, z) && y > -1)
			{
				y--;
			}

			if (loc.getBlockY() - y > 1 || y < 0)
			{
				user.getPlayer().setAllowFlight(true);
				user.getPlayer().setFlying(true);
				user.sendMessage(_("§6Set fly mode§c {0} §6for {1}§6.", _("enabled"), user.getPlayer().getDisplayName()));
			}
		}
	}