Rewrite session code and add support for persistent sessions.

This commit is contained in:
sk89q
2014-07-27 20:44:05 -07:00
parent e95eeefa2b
commit aaeaf19fc8
30 changed files with 1418 additions and 382 deletions

View File

@ -19,19 +19,27 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.WorldEditPermissionException;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.annotation.Nullable;
import java.io.File;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
public class BukkitCommandSender implements Actor {
/**
* One time generated ID.
*/
private static final UUID DEFAULT_ID = UUID.fromString("a233eb4b-4cab-42cd-9fd9-7e7b9a3f74be");
private CommandSender sender;
private WorldEditPlugin plugin;
@ -44,6 +52,11 @@ public class BukkitCommandSender implements Actor {
this.sender = sender;
}
@Override
public UUID getUniqueId() {
return DEFAULT_ID;
}
@Override
public String getName() {
return sender.getName();
@ -93,7 +106,7 @@ public class BukkitCommandSender implements Actor {
}
@Override
public void checkPermission(String permission) throws WorldEditPermissionException {
public void checkPermission(String permission) throws AuthorizationException {
}
@Override
@ -115,4 +128,29 @@ public class BukkitCommandSender implements Actor {
public void dispatchCUIEvent(CUIEvent event) {
}
@Override
public SessionKey getSessionKey() {
return new SessionKey() {
@Nullable
@Override
public String getName() {
return null;
}
@Override
public boolean isActive() {
return false;
}
@Override
public boolean isPersistent() {
return false;
}
@Override
public UUID getUniqueId() {
return DEFAULT_ID;
}
};
}
}

View File

@ -30,14 +30,18 @@ import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.session.SessionKey;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import javax.annotation.Nullable;
import java.util.UUID;
public class BukkitPlayer extends LocalPlayer {
private Player player;
private WorldEditPlugin plugin;
@ -46,6 +50,11 @@ public class BukkitPlayer extends LocalPlayer {
this.player = player;
}
@Override
public UUID getUniqueId() {
return player.getUniqueId();
}
@Override
public int getItemInHand() {
ItemStack itemStack = player.getItemInHand();
@ -192,4 +201,48 @@ public class BukkitPlayer extends LocalPlayer {
public <T> T getFacet(Class<? extends T> cls) {
return null;
}
@Override
public SessionKey getSessionKey() {
return new SessionKeyImpl(this.player.getUniqueId(), player.getName());
}
private static class SessionKeyImpl implements SessionKey {
// If not static, this will leak a reference
private final UUID uuid;
private final String name;
private SessionKeyImpl(UUID uuid, String name) {
this.uuid = uuid;
this.name = name;
}
@Override
public UUID getUniqueId() {
return uuid;
}
@Nullable
@Override
public String getName() {
return name;
}
@Override
public boolean isActive() {
// This is a thread safe call on CraftBukkit because it uses a
// CopyOnWrite list for the list of players, but the Bukkit
// specification doesn't require thread safety (though the
// spec is extremely incomplete)
return Bukkit.getServer().getPlayerExact(name) != null;
}
@Override
public boolean isPersistent() {
return true;
}
}
}

View File

@ -1,50 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program 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.
*
* This program 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 com.sk89q.worldedit.bukkit;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import com.sk89q.worldedit.SessionCheck;
import com.sk89q.worldedit.WorldEdit;
/**
* Used to remove expired sessions in Bukkit.
*/
class SessionTimer implements Runnable {
private WorldEdit worldEdit;
private SessionCheck checker;
SessionTimer(WorldEdit worldEdit, final Server server) {
this.worldEdit = worldEdit;
this.checker = new SessionCheck() {
public boolean isOnlinePlayer(String name) {
Player player = server.getPlayer(name);
return player != null && player.isOnline();
}
};
}
@Override
public void run() {
worldEdit.flushExpiredSessions(checker);
}
}

View File

@ -37,7 +37,6 @@ import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
/**
* Handles all events thrown in relation to a Player
@ -62,20 +61,6 @@ public class WorldEditListener implements Listener {
this.plugin = plugin;
}
/**
* Called when a player leaves a server
*
* @param event Relevant event details
*/
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
if (!plugin.getInternalPlatform().isHookingEvents()) {
return;
}
plugin.getWorldEdit().markExpire(plugin.wrapPlayer(event.getPlayer()));
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onGamemode(PlayerGameModeChangeEvent event) {
if (!plugin.getInternalPlatform().isHookingEvents()) {

View File

@ -110,9 +110,6 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
// Now we can register events
getServer().getPluginManager().registerEvents(new WorldEditListener(this), this);
// Register session timer
getServer().getScheduler().runTaskTimerAsynchronously(this, new SessionTimer(worldEdit, getServer()), 120, 120);
// If we are on MCPC+/Cauldron, then Forge will have already loaded
// Forge WorldEdit and there's (probably) not going to be any other
// platforms to be worried about... at the current time of writing