Multiverse/Multiverse-Core — Issue #188: POLL: onTeleport Permissions
Author: FernFerret
Created: 2011-10-14 02:09:20+00:00
State: open
Labels: Accepted, Feature, Suggestion

Ok. So i've been thinking a lot about teleport permissions, and here was one of my latest commit messages (revised to make more sense):

"There are still some access caveats. When an op or console requests that a player be teleported to you, there's currently not a good way to tell the teleport event that since an authority figure issued the teleport, override the user's teleport settings. So we either **get full control of all plugins and limited control to override it**, or **unlimited control to override with other plugins having unrestricted access to teleport players**
locations…"

The reason for this is the `PlayerTeleportEvent`. (Source: https://github.com/Bukkit/Bukkit/blob/master/src/main/java/org/bukkit/event/player/PlayerTeleportEvent.java)

```java
public PlayerTeleportEvent(Player player, Location from, Location to);
```
## Scenario A (Current)
This is the only way of telling if other plugins have teleported players (yes, yes, I know about `onPlayerPortal`, but for this issue, I'm lumping the two into one). However, this event does not tell us **who** requested the teleport. Was it the player? Or the console? We **can't ever know** with this method. Asking the Bukkit team to change the event is way out of the question, 99% of plugins don't care about this. This is what we are doing now, so even if you issue a `mvtp fernferret world` **from the console**, if player `fernferret` **does not have multivers.access.world** he will **not** be teleported. MVCore's logic will allow it, but when we monitor this event:

```java
@Override
public void onPlayerTeleport(PlayerTeleportEvent event) {
if (event.isCancelled()) {
return;
}
MultiverseWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld().getName());
MultiverseWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName());
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
// The player is Teleporting to the same world.
this.plugin.log(Level.FINER, "Player '" + event.getPlayer().getName() + "' is teleporting to the same world.");
return;
}
if (MultiverseCore.EnforceAccess) {
event.setCancelled(!playerCanGoFromTo(fromWorld, toWorld, event.getPlayer()));
if (event.isCancelled()) {
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName() + "' was DENIED ACCESS to '" + event.getTo().getWorld().getName() +
"' because they don't have: multiverse.access." + event.getTo().getWorld().getName());
}
} else {
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName() + "' was allowed to go to '" + event.getTo().getWorld().getName() + "' because enforceaccess is off.");
}
}
```

It will be caught on this line **REGARDLESS**

```java
event.setCancelled(!playerCanGoFromTo(fromWorld, toWorld, event.getPlayer()));
```

I've thought about using `onPlayerChangeWorld`, but that fires **after** a player changes worlds, meaning we'd have to take them back... If anyone has any good ideas on this, feel free to continue discussion here, or even issue a pull request!

What are your thoughts?