/*
* CommandBook
* Copyright (C) 2012 sk89q <http://www.sk89q.com>
*
* This program 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.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.commandbook.locations;
import com.sk89q.commandbook.session.PersistentSession;
import com.sk89q.minecraft.util.commands.CommandException;
import com.zachsthings.libcomponents.config.Setting;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author zml2008
*/
public class TeleportSession extends PersistentSession {
private static final long MAX_AGE = TimeUnit.DAYS.toMillis(10);
private static final long BRINGABLE_TIME = TimeUnit.MINUTES.toMillis(5);
private static final long TP_REQUEST_WAIT_TIME = TimeUnit.SECONDS.toMillis(30);
private static final long RECONNECT_GRACE = TimeUnit.MINUTES.toMillis(1);
private static final int LOCATION_HISTORY_SIZE = 10;
private final TeleportComponent component;
@Setting("teleport.bringable") private Map<String, Long> bringable = new HashMap<String, Long>();
@Setting("teleport.requests") private final Map<String, Long> teleportRequests = new HashMap<String, Long>();
private final LinkedList<Location> locationHistory = new LinkedList<Location>();
private Location ignoreTeleportLocation;
public TeleportSession(TeleportComponent component) {
super(MAX_AGE);
this.component = component;
}
@Override
public void handleReconnect(CommandSender player) {
if (getGoneTime() >= RECONNECT_GRACE) {
bringable = new HashMap<String, Long>();
}
}
public void addBringable(Player player) {
bringable.put(player.getName(), System.currentTimeMillis());
}
public void removeBringable(Player player) {
bringable.put(player.getName(), System.currentTimeMillis());
}
public boolean isBringable(Player player) {
long now = System.currentTimeMillis();
Long time = bringable.remove(player.getName());
return (time != null && (now - time) < BRINGABLE_TIME);
}
public void checkLastTeleportRequest(Player target) throws CommandException {
long now = System.currentTimeMillis();
Long time = teleportRequests.remove(target.getName());
if (time != null && (now - time) < TP_REQUEST_WAIT_TIME) {
throw new CommandException(component.getConfig().callMessageTooSoon);
}
teleportRequests.put(target.getName(), now);
}
public void rememberLocation(Location location) {
if (location == null) {
return;
}
// Skip locations which are essentially teleport jitter
if (locationHistory.size() > 0) {
Location lastLoc = locationHistory.peek().clone();
if (lastLoc.getWorld().equals(location.getWorld()) && lastLoc.distanceSquared(location) <= 2) {
return;
}
}
locationHistory.add(0, location);
while (locationHistory.size() > LOCATION_HISTORY_SIZE) {
locationHistory.pollLast();
}
}
public void rememberLocation(Player player) {
rememberLocation(player.getLocation());
}
public Location popLastLocation() {
return locationHistory.poll();
}
public void setIgnoreLocation(Location loc) {
this.ignoreTeleportLocation = loc;
}
public Location getIgnoreLocation() {
return ignoreTeleportLocation;
}
}