Add ncp tempkick command + API do deny logins [missing: persist].

This commit is contained in:
asofold 2012-09-10 10:10:45 +02:00
parent 4d0b28606d
commit cd856208d2
6 changed files with 179 additions and 4 deletions

View File

@ -6,8 +6,12 @@ import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@ -16,6 +20,8 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
@ -56,6 +62,64 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
*/
public class NoCheatPlus extends JavaPlugin implements Listener {
/** Lower case player name to milliseconds point of time of release */
private static final Map<String, Long> denyLoginNames = Collections.synchronizedMap(new HashMap<String, Long>());
/**
* Remove expired entries.
*/
private static void checkDenyLoginsNames() {
final long ts = System.currentTimeMillis();
final List<String> rem = new LinkedList<String>();
synchronized (denyLoginNames) {
for (final Entry<String, Long> entry : denyLoginNames.entrySet()){
if (entry.getValue().longValue() < ts) rem.add(entry.getKey());
}
for (final String name : rem){
denyLoginNames.remove(name);
}
}
}
/**
* Deny the player to login. This will also remove expired entries.
* @param playerName
* @param duration Duration from now on, in milliseconds.
*/
public static void denyLogin(String playerName, long duration){
final long ts = System.currentTimeMillis() + duration;
playerName = playerName.trim().toLowerCase();
synchronized (denyLoginNames) {
final Long oldTs = denyLoginNames.get(playerName);
if (oldTs != null && ts < oldTs.longValue()) return;
denyLoginNames.put(playerName, ts);
// TODO: later maybe save these ?
}
checkDenyLoginsNames();
}
/**
* Check if player is denied to login right now.
* @param playerName
* @return
*/
public static boolean isLoginDenied(String playerName){
return isLoginDenied(playerName, System.currentTimeMillis());
}
/**
* Check if a player is denied to login at a certain point of time.
* @param playerName
* @param currentTimeMillis
* @return
*/
public static boolean isLoginDenied(String playerName, long currentTimeMillis) {
playerName = playerName.trim().toLowerCase();
final Long oldTs = denyLoginNames.get(playerName);
if (oldTs == null) return false;
else return System.currentTimeMillis() < oldTs.longValue();
}
/** The event listeners. */
private final List<Listener> listeners = new ArrayList<Listener>();
@ -353,4 +417,20 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
player.sendMessage(message);
}
@EventHandler(priority=EventPriority.HIGHEST)
public void onPlayerLogin(final PlayerLoginEvent event){
// (HGHEST to give other plugins the possibility to add permissions or allow the player).
if (event.getResult() != Result.ALLOWED) return;
final Player player = event.getPlayer();
// Check if login is denied:
checkDenyLoginsNames();
if (player.hasPermission(Permissions.BYPASS_DENY_LOGIN)) return;
if (isLoginDenied(player.getName())){
// TODO: display time for which the player is banned.
event.setResult(Result.KICK_OTHER);
// TODO: Make message configurable.
event.setKickMessage("You are temporarily denied to join server.");
}
}
}

View File

@ -2,7 +2,9 @@ package fr.neatmonster.nocheatplus.command;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
@ -81,11 +83,26 @@ public class CommandHandler implements CommandExecutor {
new BanCommand(plugin),
new InfoCommand(plugin),
new KickCommand(plugin),
new TempKickCommand(plugin),
new ReloadCommand(plugin, notifyReload),
new TellCommand(plugin),
new DelayCommand(plugin),
}){
commands.put(cmd.label, cmd);
addCommand(cmd);
}
}
public void addCommand(NCPCommand command){
Set<String> allLabels = new LinkedHashSet<String>();
allLabels.add(command.label);
if (command.aliases != null){
for (String alias : command.aliases){
allLabels.add(alias);
}
}
for (String label : allLabels){
label = label.trim().toLowerCase(); // future.
if (!commands.containsKey(label)) commands.put(label, command);
}
}

View File

@ -77,7 +77,21 @@ public abstract class DelayableCommand extends NCPCommand {
* @param mustHaveDelay If specifying a delay is obligatory.
*/
public DelayableCommand(NoCheatPlus plugin, String label, String permission, int delayIndex, int delayPreset, boolean mustHaveDelay) {
super(plugin, label, permission);
this(plugin, label, permission, null, delayIndex, delayPreset, mustHaveDelay);
}
/**
*
* @param plugin
* @param label
* @param permission
* @param aliases Sub command label aliases.
* @param delayIndex Index at which to look for the delay spec.
* @param delayPreset Preset if no delay is given.
* @param mustHaveDelay If delay must be specified.
*/
public DelayableCommand(NoCheatPlus plugin, String label, String permission, String[] aliases, int delayIndex, int delayPreset, boolean mustHaveDelay) {
super(plugin, label, permission, aliases);
this.delayIndex = delayIndex;
this.mustHaveDelay = mustHaveDelay;
this.delayPreset = delayPreset;

View File

@ -47,14 +47,20 @@ public abstract class NCPCommand implements CommandExecutor{
/** The sub command label. */
public final String label;
public final String[] aliases;
/** The command permission */
public String permission;
public NCPCommand(NoCheatPlus plugin, String label, String permission){
this(plugin, label, permission, null);
}
public NCPCommand(NoCheatPlus plugin, String label, String permission, String[] aliases){
this.plugin = plugin;
this.label = label;
this.permission = permission;
this.aliases = aliases;
}
/**

View File

@ -0,0 +1,54 @@
package fr.neatmonster.nocheatplus.command;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.players.Permissions;
public class TempKickCommand extends DelayableCommand {
public TempKickCommand(NoCheatPlus plugin) {
super(plugin, "tempkick", Permissions.ADMINISTRATION_TEMPKICK, new String[]{
"tkick", "tempban", "tban",
}, 1, -1, false);
}
@Override
public boolean execute(final CommandSender sender, Command command, String label,
String[] alteredArgs, long delay) {
// Args contains sub command label as first arg.
if (alteredArgs.length < 3) return false;
long base = 60000; // minutes (!)
final String name = alteredArgs[1];
long duration = -1;
try{
// TODO: parse for abbreviations like 30s 30m 30h 30d, and set base...
duration = Integer.parseInt(alteredArgs[2]);
}
catch( NumberFormatException e){};
if (duration <= 0) return false;
final long finalDuration = duration * base;
final String reason;
if (alteredArgs.length > 3) reason = join(alteredArgs, 3);
else reason = "";
schedule(new Runnable() {
@Override
public void run() {
tempKick(sender, name, finalDuration, reason);
}
}, delay);
return true;
}
protected void tempKick(CommandSender sender, String name, long duration, String reason){
Player player = Bukkit.getPlayerExact(name);
NoCheatPlus.denyLogin(name, duration);
if (player == null) return;
player.kickPlayer(reason);
System.out.println("[NoCheatPlus] (" + sender.getName() + ") Kicked " + player.getName() + " for " + duration/60000 +" minutes: " + reason);
}
}

View File

@ -32,6 +32,10 @@ public class Permissions {
public static final String ADMINISTRATION_PLUGINS = ADMINISTRATION + ".plugins";
public static final String ADMINISTRATION_RELOAD = ADMINISTRATION + ".reload";
public static final String ADMINISTRATION_TELL = ADMINISTRATION + ".tell";
public static final String ADMINISTRATION_TEMPKICK = ADMINISTRATION + ".tempkick";
private final static String BYPASS = NOCHEATPLUS + ".bypass";
public static final String BYPASS_DENY_LOGIN = BYPASS + "denylogin";
private static final String CHECKS = NOCHEATPLUS + ".checks";