/* * This file is part of Skript. * * Skript is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Skript 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Skript. If not, see <http://www.gnu.org/licenses/>. * * * Copyright 2011-2013 Peter Güttinger * */ package ch.njol.skript.bukkitutil; import java.util.Map; import java.util.UUID; import java.util.concurrent.LinkedBlockingQueue; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.eclipse.jdt.annotation.Nullable; import ch.njol.skript.Skript; import ch.njol.skript.command.Commands; import ch.njol.util.Callback; import ch.njol.util.Closeable; /** * An {@link OfflinePlayer} that has only a name but no UUID set. * <p> * Should only be used in {@link Commands} and the parser for offline players. * <p> * Will produce {@link NullPointerException}s if used incorrectly. * * @author Peter Güttinger */ @SuppressWarnings("null") public class UnresolvedOfflinePlayer implements OfflinePlayer { final static LinkedBlockingQueue<UnresolvedOfflinePlayer> toResolve = new LinkedBlockingQueue<UnresolvedOfflinePlayer>(); final static Thread resolverThread = Skript.newThread(new Runnable() { @SuppressWarnings("deprecation") @Override public void run() { while (true) { try { final UnresolvedOfflinePlayer p = toResolve.take(); p.bukkitOfflinePlayer = Bukkit.getOfflinePlayer(p.name); p.callback.run(p); } catch (final InterruptedException e) { break; } } } }, "Skript offline player resolver thread (fetches UUIDs from the minecraft servers)"); static { resolverThread.start(); Skript.closeOnDisable(new Closeable() { @Override public void close() { resolverThread.interrupt(); } }); } final String name; @Nullable OfflinePlayer bukkitOfflinePlayer = null; final Callback<Void, OfflinePlayer> callback; /** * @param name The player's name * @param callback A callback that will be run when the player has been resolved. It will be called on the resolver thread which should not be blocked. */ public UnresolvedOfflinePlayer(final String name, final Callback<Void, OfflinePlayer> callback) { this.name = name; this.callback = callback; toResolve.add(this); } @Override public String getName() { return bukkitOfflinePlayer != null ? bukkitOfflinePlayer.getName() : name; } @Override public boolean isOnline() { return bukkitOfflinePlayer != null ? bukkitOfflinePlayer.isOnline() : getPlayer() != null; } @Override @SuppressWarnings("deprecation") @Nullable public Player getPlayer() { return bukkitOfflinePlayer != null ? bukkitOfflinePlayer.getPlayer() : Bukkit.getPlayerExact(name); } @Override public boolean isOp() { return bukkitOfflinePlayer.isOp(); } @Override public void setOp(final boolean value) { bukkitOfflinePlayer.setOp(value); } @Override public UUID getUniqueId() { return bukkitOfflinePlayer.getUniqueId(); } @Override public Map<String, Object> serialize() { return bukkitOfflinePlayer.serialize(); } @Override public boolean isBanned() { return bukkitOfflinePlayer.isBanned(); } @Override @Deprecated public void setBanned(final boolean banned) { bukkitOfflinePlayer.setBanned(banned); } @Override public boolean isWhitelisted() { return bukkitOfflinePlayer.isWhitelisted(); } @Override public void setWhitelisted(final boolean value) { bukkitOfflinePlayer.setWhitelisted(value); } @Override public long getFirstPlayed() { return bukkitOfflinePlayer.getFirstPlayed(); } @Override public long getLastPlayed() { return bukkitOfflinePlayer.getLastPlayed(); } @Override public boolean hasPlayedBefore() { return bukkitOfflinePlayer.hasPlayedBefore(); } @Override public Location getBedSpawnLocation() { return bukkitOfflinePlayer.getBedSpawnLocation(); } }