/*
* CommandBook
* Copyright (C) 2011 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;
import com.sk89q.commandbook.session.PersistentSession;
import com.sk89q.commandbook.session.SessionComponent;
import com.sk89q.commandbook.util.ChatUtil;
import com.sk89q.commandbook.util.InputUtil;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.zachsthings.libcomponents.ComponentInformation;
import com.zachsthings.libcomponents.Depend;
import com.zachsthings.libcomponents.InjectComponent;
import com.zachsthings.libcomponents.bukkit.BukkitComponent;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import java.util.concurrent.TimeUnit;
/**
*
* @author Turtle9598
*/
@Depend(components = SessionComponent.class)
@ComponentInformation(friendlyName = "Freeze", desc = "Blocks a specified player's movement on command")
public class FreezeComponent extends BukkitComponent implements Listener, Runnable {
public static final int MOVE_THRESHOLD = 2;
private static final int MOVE_THRESHOLD_SQ = MOVE_THRESHOLD * MOVE_THRESHOLD;
@InjectComponent private SessionComponent sessions;
@Override
public void enable() {
registerCommands(Commands.class);
CommandBook.registerEvents(this);
CommandBook.server().getScheduler().scheduleSyncRepeatingTask(CommandBook.inst(), this, 20 * 2, 20 * 2);
}
public boolean freezePlayer(Player player) {
FreezeState session = sessions.getSession(FreezeState.class, player);
final boolean previous = session.isFrozen();
session.freeze(player.getLocation());
return previous;
}
public boolean isFrozen(Player player) {
return sessions.getSession(FreezeState.class, player).isFrozen();
}
public boolean unfreezePlayer(Player player) {
FreezeState session = sessions.getSession(FreezeState.class, player);
final boolean previous = session.isFrozen();
session.freeze(null);
return previous;
}
@Override
public void run() {
for (FreezeState frozenState : sessions.getSessions(FreezeState.class).values()) {
if (!frozenState.isFrozen()) {
continue;
}
Player player = frozenState.getOwner();
if (player == null || !player.isOnline()) {
continue;
}
Location loc = player.getLocation();
if (loc.distanceSquared(frozenState.getFreezeLocation()) >= MOVE_THRESHOLD_SQ) {
loc.setX(frozenState.getFreezeLocation().getX());
loc.setY(frozenState.getFreezeLocation().getY());
loc.setZ(frozenState.getFreezeLocation().getZ());
player.sendMessage(ChatColor.RED + "You are frozen.");
player.teleport(loc);
}
}
}
private static class FreezeState extends PersistentSession {
public static final long MAX_AGE = TimeUnit.MINUTES.toMillis(30);
private Location freezeLocation;
protected FreezeState() {
super(MAX_AGE);
}
public boolean isFrozen() {
return freezeLocation != null;
}
public Location getFreezeLocation() {
return freezeLocation;
}
public void freeze(Location loc) {
freezeLocation = loc == null ? null : loc.clone();
}
public Player getOwner() {
CommandSender sender = super.getOwner();
return sender instanceof Player ? (Player) sender : null;
}
}
public class Commands {
@Command(aliases = {"freeze"}, usage = "<target>", desc = "Freeze a player", min = 1, max = 1)
@CommandPermissions({"commandbook.freeze"})
public void freeze(CommandContext args, CommandSender sender) throws CommandException {
Player player = InputUtil.PlayerParser.matchSinglePlayer(sender, args.getString(0));
if (!freezePlayer(player)) {
player.sendMessage(ChatColor.YELLOW + "You've been frozen by "
+ ChatUtil.toColoredName(sender, ChatColor.YELLOW));
sender.sendMessage(ChatColor.YELLOW + "You've frozen "
+ ChatUtil.toColoredName(player, ChatColor.YELLOW));
} else {
player.sendMessage(ChatColor.YELLOW + "Your freeze location has been updated by "
+ ChatUtil.toColoredName(sender, ChatColor.YELLOW));
sender.sendMessage(ChatColor.YELLOW + "You have updated the freeze location of "
+ ChatUtil.toColoredName(player, ChatColor.YELLOW));
}
}
@Command(aliases = {"unfreeze"}, usage = "<target>", desc = "Unfreeze a player", min = 1, max = 1)
@CommandPermissions({"commandbook.freeze"})
public void unfreeze(CommandContext args, CommandSender sender) throws CommandException {
Player player = InputUtil.PlayerParser.matchSinglePlayer(sender, args.getString(0));
if (unfreezePlayer(player)) {
player.sendMessage(ChatColor.YELLOW + "You've been unfrozen by "
+ ChatUtil.toColoredName(sender, ChatColor.YELLOW));
sender.sendMessage(ChatColor.YELLOW + "You've unfrozen "
+ ChatUtil.toColoredName(player, ChatColor.YELLOW));
} else {
throw new CommandException(ChatUtil.toName(player) + " was not frozen");
}
}
}
}