Add the 'ncp stopwatch' command.

Taken from CG/customplg.
This commit is contained in:
asofold 2016-06-03 21:33:55 +02:00
parent 6e688cc3ff
commit 016d5894de
14 changed files with 792 additions and 0 deletions

View File

@ -0,0 +1,39 @@
/*
* 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 fr.neatmonster.nocheatplus.utilities;
import java.util.concurrent.TimeUnit;
public class Misc {
/**
* Display ms as "[dd:]hh:mm:ss"
*/
public static String millisToShortDHMS(long duration) {
String res = "";
long days = TimeUnit.MILLISECONDS.toDays(duration);
long hours = TimeUnit.MILLISECONDS.toHours(duration) - TimeUnit.DAYS.toHours(TimeUnit.MILLISECONDS.toDays(duration));
long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));
long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));
if (days == 0) {
res = String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
else {
res = String.format("%dd %02d:%02d:%02d", days, hours, minutes, seconds);
}
return res;
}
}

View File

@ -47,6 +47,7 @@ import fr.neatmonster.nocheatplus.command.admin.log.LogCommand;
import fr.neatmonster.nocheatplus.command.admin.notify.NotifyCommand;
import fr.neatmonster.nocheatplus.command.admin.reset.ResetCommand;
import fr.neatmonster.nocheatplus.command.admin.top.TopCommand;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.StopWatchCommand;
import fr.neatmonster.nocheatplus.components.INotifyReload;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
@ -119,6 +120,8 @@ public class NoCheatPlusCommand extends BaseCommand{
new LogCommand(plugin),
new ResetCommand(plugin),
new DebugCommand(plugin),
// Testing:
new StopWatchCommand(access),
}){
addSubCommands(cmd);
rootLabels.add(cmd.label);

View File

@ -0,0 +1,49 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch;
import org.bukkit.Location;
import org.bukkit.entity.Player;
/**
* Just base on the players location at initialization.
* @author mc_dev
*
*/
public abstract class LocationBasedStopWatchData extends StopWatch{
/** For efficient location getting, such as player.getLocation(useLoc), always setWorld(null). */
protected static final Location useLoc = new Location(null, 0, 0, 0);
public final String worldName;
public final double x;
public final double y;
public final double z;
/**
* Makes use of useLoc, only call from the primary thread.
* @param player
*/
public LocationBasedStopWatchData(Player player) {
super(player);
final Location loc = player.getLocation(useLoc);
worldName = loc.getWorld().getName();
x = loc.getX();
y = loc.getY();
z = loc.getZ();
useLoc.setWorld(null);
}
}

View File

@ -0,0 +1,98 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.utilities.Misc;
public abstract class StopWatch {
public final long start;
protected boolean finished = false;
private long duration = 0;
public final Player player;
/** Added as clock description, mind to add spaces/brackets. */
protected String clockDetails = "";
public StopWatch(Player player) {
this.start = System.currentTimeMillis(); // TODO: Monotonic ?
this.player = player;
}
public String getClockDetails() {
return clockDetails;
}
/**
*
* @return Duration in milliseconds.
* @throws RuntimeException if time ran backwards.
*/
public long getTime() {
if (isFinished()) {
return duration;
}
final long time = System.currentTimeMillis();
if (time < start) {
throw new RuntimeException("Time ran backwards.");
}
return time - start;
}
/**
*
* @return Duration in milliseconds.
* @throws RuntimeException if time ran backwards.
*/
public long stop() {
if (!finished) {
duration = getTime();
finished = true;
}
return duration;
}
public boolean isFinished() {
return finished;
}
/**
* Override for more functionality.
* @throws RuntimeException if time ran backwards.
*/
public void sendStatus() {
final long duration = getTime();
final long tenths = (duration % 1000) / 100;
player.sendMessage(ChatColor.AQUA + "Stopwatch" + clockDetails + ": " + (finished ? ChatColor.RED : ChatColor.GREEN) + Misc.millisToShortDHMS(duration) + "." + tenths);
}
/**
* Check if and indicate if the conditions for stopping have been reached + do stop the clock if reached. isFinished should be checked before calling this.
* @return If stopped.
*/
public abstract boolean checkStop();
/**
* Does checkStop need to be called every tick?
* @return
*/
public abstract boolean needsTick();
}

View File

@ -0,0 +1,82 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import fr.neatmonster.nocheatplus.command.BaseCommand;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.distance.DistanceCommand;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.returnmargin.ReturnCommand;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.start.StartCommand;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.stop.StopCommand;
/**
* Root command. <br>
* Intended features: current time with /stopwatch, sub commands: start+stop, distance, return to location<br>
* TODO: countdown
* @author mc_dev
*
*/
public class StopWatchCommand extends BaseCommand {
private final StopWatchRegistry registry = new StopWatchRegistry();
public StopWatchCommand(final JavaPlugin access) {
super(access, "stopwatch", "nocheatplus.command.stopwatch", new String[]{"sw"});
access.getServer().getScheduler().scheduleSyncDelayedTask(access, new Runnable() {
@Override
public void run() {
registry.setup(access);
}
});
// Register sub commands.
addSubCommands(
new StopCommand(registry),
new StartCommand(registry),
new DistanceCommand(registry),
new ReturnCommand(registry)
);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
if (!(sender instanceof Player)) {
// TODO: Implement checking others clocks!
sender.sendMessage("Stopwatch functionality is only available to players.");
return true;
}
if (args.length == 0) {
StopWatch clock = registry.getClock((Player) sender);
sender.sendMessage(ChatColor.GRAY + "Use tab completion for stopwatch options.");
if (clock != null) {
clock.sendStatus();
}
return true;
} else {
return super.onCommand(sender, command, alias, args);
}
}
}

View File

@ -0,0 +1,166 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import fr.neatmonster.nocheatplus.utilities.OnDemandTickListener;
/**
* Registers stop-watches for players.
* @author mc_dev
*
*/
public class StopWatchRegistry {
// TODO: Make its own plugin + no NCP dependency.
/** Currently by player name. */
private Map<String, StopWatch> clocks = new LinkedHashMap<String, StopWatch>(20);
private final OnDemandTickListener tickListener = new OnDemandTickListener() {
@Override
public boolean delegateTick(int tick, long timeLast) {
return tickClocks(); // true: stay registered
}
};
protected void setup(Plugin plugin) {
plugin.getServer().getPluginManager().registerEvents(new Listener() {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) {
removeClocks(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerKick(PlayerKickEvent event) {
removeClocks(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onWorldChange(PlayerChangedWorldEvent event) {
checkWorldChange(event.getPlayer());
}
}, plugin);
}
public StopWatch getClock(Player player) {
return clocks.get(player.getName());
}
protected void removeClocks(Player player) {
clocks.remove(player.getName());
}
protected void checkWorldChange(Player player) {
StopWatch sw = getClock(player);
try {
if (sw != null && !sw.isFinished() && sw.checkStop()) {
sw.sendStatus();
}
} catch (RuntimeException e) {
timeBackwards(player);
}
}
protected void timeBackwards(Player player) {
removeClocks(player);
player.sendMessage(ChatColor.RED + "Stopwatch finished due to system time running backwards.");
}
/**
* Check if having a tick listener registered is necessary.
* @return If to stay registered.
*/
protected boolean tickClocks() {
if (clocks.isEmpty()) {
return false;
}
boolean needsTick = false;
Iterator<Entry<String, StopWatch>> it = clocks.entrySet().iterator();
while (it.hasNext()) {
final StopWatch sw = it.next().getValue();
try {
if (sw.needsTick()) {
if (sw.isFinished()) {
// Ignore.
} else if (sw.checkStop()) {
sw.sendStatus();
// Do not remove the clock.
} else {
needsTick = true;
}
} // else: ignore.
} catch (RuntimeException e) {
it.remove();
timeBackwards(sw.player);
}
}
return needsTick;
}
public void setClock(Player player, StopWatch clock) {
StopWatch oldClock = getClock(player);
if (oldClock != null && !oldClock.isFinished()) {
// TODO: Might add a more descriptive message.
oldClock.stop();
oldClock.sendStatus();
}
clocks.put(player.getName(), clock);
if (clock.needsTick()) {
tickListener.register();
}
}
/**
*
* @param player
* @return If a clock was running (note that a stopped clock is not running).
*/
public boolean stopClock(Player player) {
StopWatch oldClock = getClock(player);
boolean wasRunning = false;
if (oldClock != null) {
wasRunning = !oldClock.isFinished();
// TODO: Might add a more descriptive message.
oldClock.stop();
oldClock.sendStatus();
}
return wasRunning;
}
public void tellClock(Player player) {
StopWatch oldClock = getClock(player);
if (oldClock != null) {
// TODO: Might add a more descriptive message.
oldClock.sendStatus();
} else {
// TODO: Might tell "no clock running".
}
}
}

View File

@ -0,0 +1,52 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch.distance;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.command.AbstractCommand;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.StopWatch;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.StopWatchRegistry;
public class DistanceCommand extends AbstractCommand<StopWatchRegistry> {
public DistanceCommand(StopWatchRegistry access) {
super(access, "distance", null);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
Double distance = null;
if (args.length != 3) {
return false;
}
try {
distance = Double.parseDouble(args[2]);
} catch (NumberFormatException e) {}
if (distance == null || distance.isNaN() || distance.isInfinite() || distance.doubleValue() < 0.0) {
sender.sendMessage(ChatColor.RED + "Bad distance: " + args[2]);
return true;
}
StopWatch clock = new DistanceStopWatch((Player) sender, distance.doubleValue());
access.setClock((Player) sender, clock);
sender.sendMessage(ChatColor.GREEN + "New stopwatch started " + clock.getClockDetails() + ".");
return true;
}
}

View File

@ -0,0 +1,58 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch.distance;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.LocationBasedStopWatchData;
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
/**
* Stops at the distance of the player.
* @author mc_dev
*
*/
public class DistanceStopWatch extends LocationBasedStopWatchData{
protected final double distance;
protected final double distanceSq;
public DistanceStopWatch(Player player, double distance) {
super(player);
this.distance = distance;
this.distanceSq = distance * distance;
clockDetails = "(distance " + distance + " meters)";
}
@Override
public boolean checkStop() {
final Location loc = player.getLocation(useLoc);
if (!worldName.equals(loc.getWorld().getName()) || TrigUtil.distanceSquared(x, y, z, loc.getX(), loc.getY(), loc.getZ()) >= distanceSq) {
stop();
useLoc.setWorld(null);
return true;
} else {
useLoc.setWorld(null);
return false;
}
}
@Override
public boolean needsTick() {
return true;
}
}

View File

@ -0,0 +1,51 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch.returnmargin;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.command.AbstractCommand;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.StopWatch;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.StopWatchRegistry;
public class ReturnCommand extends AbstractCommand<StopWatchRegistry> {
public ReturnCommand(StopWatchRegistry access) {
super(access, "return", null);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
Double distance = null;
if (args.length != 3) {
return false;
}
try {
distance = Double.parseDouble(args[2]);
} catch (NumberFormatException e) {}
if (distance == null || distance.isNaN() || distance.isInfinite() || distance.doubleValue() < 0.0) {
sender.sendMessage(ChatColor.RED + "Bad distance: " + args[2]);
return true;
}
StopWatch clock = new ReturnStopWatch((Player) sender, distance.doubleValue());
access.setClock((Player) sender, clock);
sender.sendMessage(ChatColor.GREEN + "New stopwatch started " + clock.getClockDetails() + ".");
return true;
}
}

View File

@ -0,0 +1,68 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch.returnmargin;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.LocationBasedStopWatchData;
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
public class ReturnStopWatch extends LocationBasedStopWatchData{
protected final double marginDistance;
protected final double marginDistanceSq;
protected boolean started = false;
public ReturnStopWatch(Player player, double marginDistance) {
super(player);
this.marginDistance = marginDistance;
this.marginDistanceSq = marginDistance * marginDistance;
clockDetails = "(return to " + Location.locToBlock(x) + "," +Location.locToBlock(y) + "," + Location.locToBlock(z) + "/+-" + marginDistance + ")";
}
@Override
public boolean checkStop() {
final Location loc = player.getLocation(useLoc);
if (!worldName.equals(loc.getWorld().getName())) {
stop();
useLoc.setWorld(null);
return true;
}
final double distSq = TrigUtil.distanceSquared(x, y, z, loc.getX(), loc.getY(), loc.getZ());
useLoc.setWorld(null);
if (!started) {
// Skip until the player made it out of the margin.
if (distSq > marginDistanceSq) {
started = true;
}
return false;
} else {
// Check if the player returned to within the margin.
if (distSq < marginDistanceSq) {
stop();
return true;
} else {
return false;
}
}
}
@Override
public boolean needsTick() {
return true;
}
}

View File

@ -0,0 +1,37 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch.start;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.StopWatch;
public class SimpleStopWatch extends StopWatch{
public SimpleStopWatch(Player player) {
super(player);
}
@Override
public boolean checkStop() {
return isFinished();
}
@Override
public boolean needsTick() {
return false;
}
}

View File

@ -0,0 +1,39 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch.start;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.command.AbstractCommand;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.StopWatchRegistry;
public class StartCommand extends AbstractCommand<StopWatchRegistry> {
public StartCommand(StopWatchRegistry access) {
super(access, "start", null);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
access.setClock((Player) sender, new SimpleStopWatch((Player) sender));
sender.sendMessage(ChatColor.GREEN + "New stopwatch started.");
return true;
}
}

View File

@ -0,0 +1,47 @@
/*
* 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 fr.neatmonster.nocheatplus.command.testing.stopwatch.stop;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.command.AbstractCommand;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.StopWatch;
import fr.neatmonster.nocheatplus.command.testing.stopwatch.StopWatchRegistry;
public class StopCommand extends AbstractCommand<StopWatchRegistry>{
public StopCommand(StopWatchRegistry registry) {
super(registry, "stop", null);
}
@Override
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args)
{
StopWatch clock = access.getClock((Player) sender);
if (clock == null || clock.isFinished()) {
sender.sendMessage(ChatColor.RED + "No stopwatch active.");
} else {
clock.stop();
clock.sendStatus();
}
return true;
}
}

View File

@ -330,6 +330,8 @@ permissions:
description: Reset statistics or debugging counters.
nocheatplus.command.debug:
description: Start logging debug information for a player (lots of output, log file).
nocheatplus.command.stopwatch:
description: Stop watch functionality. See tab-completion and feedback.
# Legacy:
nocheatplus.command.tempkick:
description: Obsolete, use nocheatplus.command.denylogin instead.
@ -360,6 +362,7 @@ permissions:
nocheatplus.command.exemptions: true
nocheatplus.command.denylist: true
nocheatplus.command.commands: true
nocheatplus.command.stopwatch: true
# TODO: Put lag here ?
nocheatplus.shortcut.monitor:
description: All monitoring commands such as player and system info (including plugins).