Add the Jail Vote feature back in, with lots of unit testing. Closes #8

This commit is contained in:
graywolf336
2015-02-12 21:29:09 -06:00
parent b23bdaa89b
commit d205a35d0a
19 changed files with 813 additions and 21 deletions

View File

@ -40,6 +40,7 @@ public class JailMain extends JavaPlugin {
private JailPayManager jpm;
private JailStickManager jsm;
private JailTimer jt;
private JailVoteManager jvm;
private PrisonerManager pm;
private ScoreBoardManager sbm;
private MoveProtectionListener mpl;
@ -84,6 +85,13 @@ public class JailMain extends JavaPlugin {
cmdHand = new CommandHandler(this);
jh = new JailHandler(this);
pm = new PrisonerManager(this);
try {
jvm = new JailVoteManager(this);
}catch(Exception e) {
e.printStackTrace();
getLogger().severe("Failed to load the Jail Vote system, please see the stacktrace above (you probably misconfigured the time).");
}
PluginManager plm = this.getServer().getPluginManager();
plm.registerEvents(new CacheListener(this), this);
@ -132,6 +140,7 @@ public class JailMain extends JavaPlugin {
getServer().getScheduler().cancelTasks(this);
update = null;
jvm = null;
jt = null;
sbm = null;
jpm = null;
@ -213,11 +222,7 @@ public class JailMain extends JavaPlugin {
}
}
/**
* Reloads the {@link JailPayManager}.
*
* @throws Exception If we couldn't successfully create a new Jail Pay Manager instance.
*/
/** Reloads the {@link JailPayManager}. */
public void reloadJailPayManager() {
this.jpm = null;
@ -230,6 +235,21 @@ public class JailMain extends JavaPlugin {
}
}
}
/** Reloads the {@link JailVoteManager}. */
public void reloadJailVoteManager() throws Exception {
if(this.jvm != null) {
for(Integer i : this.jvm.getRunningTasks().values()) {
this.getServer().getScheduler().cancelTask(i);
}
this.jvm.getRunningTasks().clear();
this.jvm.getVotes().clear();
}
this.jvm = null;
this.jvm = new JailVoteManager(this);
}
/** Reloads the update checker, in case they changed a setting about it. */
public void reloadUpdateCheck() {
@ -283,6 +303,11 @@ public class JailMain extends JavaPlugin {
public ScoreBoardManager getScoreBoardManager() {
return this.sbm;
}
/** Gets the {@link JailVoteManager} instance. */
public JailVoteManager getJailVoteManager() {
return this.jvm;
}
/** Gets the {@link Update} instance. */
public Update getUpdate() {

View File

@ -111,6 +111,8 @@ public class JailManager {
* @return The nearest {@link Jail} to the sender if it is a player or else the first jail defined.
*/
public Jail getNearestJail(CommandSender sender) {
if(jails.isEmpty()) return null;
if(sender instanceof Player) {
Location loc = ((Player) sender).getLocation();

View File

@ -0,0 +1,217 @@
package com.graywolf336.jail;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import com.graywolf336.jail.beans.Jail;
import com.graywolf336.jail.beans.JailVote;
import com.graywolf336.jail.beans.Prisoner;
import com.graywolf336.jail.enums.JailVoteResult;
import com.graywolf336.jail.enums.Lang;
import com.graywolf336.jail.enums.Settings;
import com.graywolf336.jail.events.PrePrisonerJailedEvent;
/**
* Manages all the votes to jail players.
*
* @author graywolf336
* @since 3.0.0
* @version 1.0.0
*/
public class JailVoteManager {
private JailMain pl;
private HashMap<String, JailVote> votes;
private HashMap<String, Integer> tasks;
private String timerDesc, reason;
private long timerTicks, jailTime;
private int minYes;
/**
* Creates a new instance of this Jail Vote manager.
*
* @throws Exception When it can't load the time correctly
*/
public JailVoteManager(JailMain plugin) throws Exception {
this.pl = plugin;
this.votes = new HashMap<String, JailVote>();
this.tasks = new HashMap<String, Integer>();
this.reason = plugin.getConfig().getString(Settings.JAILVOTEREASON.getPath());
String timer = plugin.getConfig().getString(Settings.JAILVOTETIMER.getPath());
this.timerDesc = Util.getDurationBreakdown(Util.getTime(timer));
this.timerTicks = Util.getTime(timer, TimeUnit.SECONDS) * 20;
this.jailTime = Util.getTime(plugin.getConfig().getString(Settings.JAILVOTETIME.getPath()));
this.minYes = plugin.getConfig().getInt(Settings.JAILMINYESVOTES.getPath());
}
/** Gets all the votes to jail someone. */
public HashMap<String, JailVote> getVotes() {
return this.votes;
}
/**
* Gets the jail vote for the given player name, returning null if it doesn't exist.
*
* @param name of the player to get the jail vote for
* @return {@link JailVote} for the player
*/
public JailVote getVoteForPlayer(String name) {
return this.votes.get(name);
}
/**
* Adds a vote to jail someone.
*
* @param v the {@link JailVote} to add.
* @return true if the vote was added, false if a vote already exists for that player name.
*/
public boolean addVote(JailVote v) {
if(this.votes.containsKey(v.getPlayerName())) {
return false;
}else {
this.votes.put(v.getPlayerName(), v);
return true;
}
}
/**
* Adds a vote for the given player's name.
*
* @param name the name of the player the vote is for.
* @param id the uuid of the player voting.
* @param which whether they are voting yes or no, true if yes false if no.
* @return True if the vote was successful, false if it was unsuccessful.
*/
public boolean addVote(String name, UUID id, boolean which) {
if(this.votes.containsKey(name)) {
pl.debug(id.toString() + " voted " + (which ? "yes" : "no") + " to jail " + name);
if(which) {
return this.votes.get(name).voteYes(id);
}else {
return this.votes.get(name).voteNo(id);
}
}else {
return false;
}
}
public boolean hasVotedAlready(String name, UUID id) {
if(this.votes.containsKey(name)) {
return this.votes.get(name).hasVoted(id);
}else {
return false;
}
}
/**
* Checks if a player is voted for or not.
*
* @param name of the player to check for.
* @return true if they were voted for, false if not.
*/
public boolean isVotedFor(String name) {
return this.votes.containsKey(name);
}
/** Returns the nice formatted time of how long a vote is open. */
public String getTimerLengthDescription() {
return this.timerDesc;
}
/** Returns the minimum amount of yes votes required to jail someone. */
public int getMinimumYesVotes() {
return this.minYes;
}
/** Gets the current running tasks ids. */
public HashMap<String, Integer> getRunningTasks() {
return this.tasks;
}
/**
* Schedules the calculation of whether a jail vote should jail or not jail.
*
* @param name the name of the person who is being voted to be jailed
*/
public void scheduleCalculating(final String name) {
int taskId = pl.getServer().getScheduler().runTaskLater(pl, new Runnable() {
public void run() {
doTheVoteCalculation(votes.get(name));
tasks.remove(name);
}
}, timerTicks).getTaskId();
this.tasks.put(name, taskId);
}
/**
* Calculates the votes, determining whether there are enough votes to jail the person or not.
*
* @param v the {@link JailVote} to do the calculation of.
*/
public JailVoteResult doTheVoteCalculation(JailVote v) {
JailVoteResult result;
if(v.getPlayer() == null) {
pl.getServer().broadcastMessage(Lang.VOTEPLAYERNOLONGERONLINE.get(v.getPlayerName()));
result = JailVoteResult.NOTONLINE;
}else {
if(v.getYesVotes() > v.getNoVotes()) {
if(v.getYesVotes() >= getMinimumYesVotes()) {
Prisoner p = new Prisoner(v.getPlayer().getUniqueId().toString(), v.getPlayerName(), pl.getConfig().getBoolean(Settings.AUTOMATICMUTE.getPath()), jailTime, "[JailVote]", reason);
//Get the jail name, check for the nearest one
String jailName = pl.getConfig().getString(Settings.DEFAULTJAIL.getPath());
if(jailName.equalsIgnoreCase("nearest")) {
Jail j = pl.getJailManager().getNearestJail(v.getPlayer());
if(j != null) {
jailName = j.getName();
}
}
//Get the jail instance from the name of jail in the params.
Jail j = pl.getJailManager().getJail(jailName);
if(j == null) {
pl.getLogger().warning("Jail Vote Failed: no jail was found?");
result = JailVoteResult.NOJAIL;
}else if(!j.isEnabled()) {
pl.getLogger().warning("Jail Vote Failed: " + Lang.WORLDUNLOADED.get(j.getName()));
result = JailVoteResult.JAILNOTENABLED;
}else {
//call the event
PrePrisonerJailedEvent event = new PrePrisonerJailedEvent(j, null, p, v.getPlayer(), v.getPlayer() == null, p.getJailer());
pl.getServer().getPluginManager().callEvent(event);
//check if the event is cancelled
if(event.isCancelled()) {
pl.getLogger().warning("Jail Vote Failed: The PrePrisonerJailedEvent was cancelled for some reason.");
result = JailVoteResult.EVENTCANCELLED;
}else {
try {
pl.getPrisonerManager().prepareJail(j, null, v.getPlayer(), p);
result = JailVoteResult.YES;
} catch (Exception e) {
e.printStackTrace();
pl.getLogger().warning("Jail Vote Failed: The preparing the jail failed.");
result = JailVoteResult.JAILEDEXCEPTION;
}
}
}
}else {
pl.getServer().broadcastMessage(Lang.VOTESNOTENOUGHYES.get(new String[] { v.getPlayerName(), String.valueOf(v.getYesVotes()), String.valueOf(minYes) }));
result = JailVoteResult.NOTENOUGHYESVOTES;
}
}else if(v.getYesVotes() == v.getNoVotes()) {
pl.getServer().broadcastMessage(Lang.VOTESTIED.get(v.getPlayerName()));
result = JailVoteResult.TIED;
}else {
pl.getServer().broadcastMessage(Lang.VOTESSAIDNO.get(v.getPlayerName()));
result = JailVoteResult.NO;
}
}
votes.remove(v.getPlayerName());
return result;
}
}

View File

@ -48,4 +48,14 @@ public class JailsAPI {
public static HandCuffManager getHandCuffManager() {
return pl.getHandCuffManager();
}
/**
* The instance of the {@link JailVoteManager} which handles all the voting to jail players.
*
* @return instance of the {@link JailVoteManager}
* @see JailVoteManager
*/
public static JailVoteManager getJailVoteManager() {
return pl.getJailVoteManager();
}
}

View File

@ -0,0 +1,94 @@
package com.graywolf336.jail.beans;
import java.util.ArrayList;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
/**
* Represents a vote to jail someone.
*
* @author graywolf336
* @since 3.0.0
* @version 1.0.0
*/
public class JailVote {
private String name;
private ArrayList<UUID> voters;
private int yes, no;
/**
* Initiates a vote to jail someone, with the vote being for the given player.
*
* @param player the name of the player the vote is for
*/
public JailVote(String player) {
this.name = player;
this.voters = new ArrayList<UUID>();
this.yes = 0;
this.no = 0;
}
/** The name of the player the vote is for. */
public String getPlayerName() {
return this.name;
}
/**
* Gets the player who the vote is for, from the player name.
*
* @return the player who the vote is for to jail
*/
@SuppressWarnings("deprecation")
public Player getPlayer() {
return Bukkit.getPlayer(name);
}
/** Checks if the player with the given id has voted already. */
public boolean hasVoted(UUID id) {
return this.voters.contains(id);
}
/**
* Method to vote yes, providing the uuid of the person doing the voting.
*
* @param id the uuid of the voter
* @return true if it was success, false if they already voted
*/
public boolean voteYes(UUID id) {
if(this.voters.contains(id)) {
return false;
}else {
this.voters.add(id);
this.yes++;
return true;
}
}
/**
* Method to vote no, providing the uuid of the person doing the voting.
*
* @param id the uuid of the voter
* @return true if it was success, false if they already voted
*/
public boolean voteNo(UUID id) {
if(this.voters.contains(id)) {
return false;
}else {
this.voters.add(id);
this.no++;
return true;
}
}
/** Get the amount of yes votes. */
public int getYesVotes() {
return this.yes;
}
/** Get the amount of no votes. */
public int getNoVotes() {
return this.no;
}
}

View File

@ -35,6 +35,7 @@ import com.graywolf336.jail.command.subcommands.JailTimeCommand;
import com.graywolf336.jail.command.subcommands.JailTransferAllCommand;
import com.graywolf336.jail.command.subcommands.JailTransferCommand;
import com.graywolf336.jail.command.subcommands.JailVersionCommand;
import com.graywolf336.jail.command.subcommands.JailVoteCommand;
import com.graywolf336.jail.enums.Lang;
public class JailHandler {
@ -199,6 +200,7 @@ public class JailHandler {
load(JailTransferAllCommand.class);
load(JailTransferCommand.class);
load(JailVersionCommand.class);
load(JailVoteCommand.class);
}
private void load(Class<? extends Command> c) {

View File

@ -25,11 +25,13 @@ public class JailReloadCommand implements Command {
jm.getPlugin().reloadScoreBoardManager();
jm.getPlugin().reloadJailSticks();
jm.getPlugin().reloadJailPayManager();
jm.getPlugin().reloadJailVoteManager();
jm.getPlugin().reloadUpdateCheck();
sender.sendMessage(Lang.PLUGINRELOADED.get());
}catch (Exception e) {
sender.sendMessage(ChatColor.RED + "Failed to reload due to: " + e.getMessage());
e.printStackTrace();
sender.sendMessage(ChatColor.RED + "Failed to reload due to (see the console): " + e.getMessage());
}
return true;

View File

@ -10,11 +10,11 @@ import com.graywolf336.jail.command.CommandInfo;
maxArgs = 0,
minimumArgs = 0,
needsPlayer = false,
pattern = "version|ver|v",
pattern = "version|ver",
permission = "jail.command.jailversion",
usage = "/jail version"
)
public class JailVersionCommand implements Command{
public class JailVersionCommand implements Command {
public boolean execute(JailManager jm, CommandSender sender, String... args) {
// Sends the version number to the sender

View File

@ -0,0 +1,91 @@
package com.graywolf336.jail.command.subcommands;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.graywolf336.jail.JailManager;
import com.graywolf336.jail.JailVoteManager;
import com.graywolf336.jail.beans.JailVote;
import com.graywolf336.jail.command.Command;
import com.graywolf336.jail.command.CommandInfo;
import com.graywolf336.jail.enums.Lang;
import com.graywolf336.jail.enums.Settings;
@CommandInfo(
maxArgs = 2,
minimumArgs = 1,
needsPlayer = true,
pattern = "vote|v",
permission = "jail.usercmd.jailvote",
usage = "/jail vote [player] (yes|no)"
)
public class JailVoteCommand implements Command {
public boolean execute(JailManager jm, CommandSender sender, String... args) {
if(jm.getPlugin().getConfig().getBoolean(Settings.JAILVOTEENABLED.getPath()) && jm.getPlugin().getJailVoteManager() != null && !jm.getJails().isEmpty()) {
Player p = (Player) sender;
JailVoteManager jvm = jm.getPlugin().getJailVoteManager();
switch(args.length) {
case 2:
if(jvm.isVotedFor(args[1])) {
if(jvm.hasVotedAlready(args[1], p.getUniqueId())) {
sender.sendMessage(Lang.VOTEALREADYVOTEDFOR.get(args[1]));
}else {
if(jvm.addVote(args[1], p.getUniqueId(), true)) {
sender.sendMessage(Lang.VOTEYESSUCCESS.get(args[1]));
}else {
sender.sendMessage(Lang.VOTEUNSUCCESSFUL.get());
}
}
}else if(sender.hasPermission("jail.vote.start")) {
jvm.addVote(new JailVote(args[1]));
jvm.addVote(args[1], p.getUniqueId(), true);
jm.getPlugin().getServer().broadcastMessage(Lang.VOTEBROADCASTHEADER.get());
jm.getPlugin().getServer().broadcastMessage(Lang.VOTEBROADCASTLINE1.get(new String[] { sender.getName(), args[1] }));
jm.getPlugin().getServer().broadcastMessage(Lang.VOTEBROADCASTLINE2.get(args[1]));
jm.getPlugin().getServer().broadcastMessage(Lang.VOTEBROADCASTLINE3.get(args[1]));
jm.getPlugin().getServer().broadcastMessage(Lang.VOTEBROADCASTLINE4.get(jvm.getTimerLengthDescription()));
jm.getPlugin().getServer().broadcastMessage(Lang.VOTEBROADCASTFOOTER.get());
jvm.scheduleCalculating(args[1]);
}else {
jm.getPlugin().debug(sender.getName() + " tried to start a vote to jail someone but didn't have permission, jail.vote.start");
sender.sendMessage(Lang.VOTENOPERMISSIONTOSTART.get(args[1]));
}
break;
case 3:
String name = args[1];
if(jvm.isVotedFor(name)) {
if(jvm.hasVotedAlready(args[1], p.getUniqueId())) {
sender.sendMessage(Lang.VOTEALREADYVOTEDFOR.get(args[1]));
}else {
if(args[2].equalsIgnoreCase("yes")) {
jvm.addVote(args[1], p.getUniqueId(), true);
sender.sendMessage(Lang.VOTEYESSUCCESS.get(args[1]));
}else {
jvm.addVote(args[1], p.getUniqueId(), false);
sender.sendMessage(Lang.VOTENOSUCCESS.get(args[1]));
}
}
}else {
sender.sendMessage(Lang.VOTENOVOTEFORTHATPLAYER.get(name));
}
break;
default:
return false;
}
}else {
sender.sendMessage(Lang.VOTENOTENABLED.get());
if(jm.getPlugin().getJailVoteManager() == null) {
jm.getPlugin().getLogger().severe("Jail Vote Manager didn't load correctly, it is null.");
}else if(jm.getJails().isEmpty()) {
jm.getPlugin().getLogger().severe("There are no jails, Jail Vote needs a Jail to work.");
}
}
return true;
}
}

View File

@ -0,0 +1,22 @@
package com.graywolf336.jail.enums;
public enum JailVoteResult {
/** The result when the PrePrisonerJailedEvent is cancelled. */
EVENTCANCELLED,
/** The result when the jailing results in an exception for some reason. */
JAILEDEXCEPTION,
/** The result when the jail which is picked is not enabled. */
JAILNOTENABLED,
/** The result when the player who the vote is for is no longer online. */
NOTONLINE,
/** The result when there aren't enough yes votes as configured. */
NOTENOUGHYESVOTES,
/** The result when there are no jails. */
NOJAIL,
/** The result when there are more no votes than yes votes. */
NO,
/** The result when the votes are tied, resulting in no jailing. */
TIED,
/** The result when there are enough yes votes over no votes for the vote to be successful. */
YES
}

View File

@ -201,6 +201,42 @@ public enum Lang {
PAYPAIDLOWEREDTIME("jailpay", "paidloweredtime"),
/** The message sent when they pay and lower someone else's time. */
PAYPAIDLOWEREDTIMEELSE("jailpay", "paidloweredtimeelse"),
// Jail vote
/** The header sent when broadcasting a new jail vote. */
VOTEBROADCASTHEADER("jailvote.broadcast", "header"),
/** The footer sent when broadcasting a new jail vote. */
VOTEBROADCASTFOOTER("jailvote.broadcast", "footer"),
/** Line1 of the broadcast message sent when a new jail vote is happening. */
VOTEBROADCASTLINE1("jailvote.broadcast", "line1"),
/** Line2 of the broadcast message sent when a new jail vote is happening. */
VOTEBROADCASTLINE2("jailvote.broadcast", "line2"),
/** Line3 of the broadcast message sent when a new jail vote is happening. */
VOTEBROADCASTLINE3("jailvote.broadcast", "line3"),
/** Line4 of the broadcast message sent when a new jail vote is happening. */
VOTEBROADCASTLINE4("jailvote.broadcast", "line4"),
/** The message sent when someone tries to vote for a player when a vote isn't running. */
VOTENOVOTEFORTHATPLAYER("jailvote", "novotegoingforthatplayer"),
/** The message sent to a player who tries to start a vote to jail someone and doesn't have permission. */
VOTENOPERMISSIONTOSTART("jailvote", "nopermissiontostartvote"),
/** The message sent when jail vote is not enabled. */
VOTENOTENABLED("jailvote", "notenabled"),
/** The message sent whenever someone's vote is not successful. */
VOTEUNSUCCESSFUL("jailvote", "voteunsuccessful"),
/** The message sent whenever a player successfully votes no. */
VOTENOSUCCESS("jailvote", "votenosuccessful"),
/** The message sent whenever a player successfully votes yes. */
VOTEYESSUCCESS("jailvote", "voteyessuccessful"),
/** The message broadcasted whenever a vote is tied. */
VOTESTIED("jailvote", "votestied"),
/** The message broadcasted whenever there are more no votes. */
VOTESSAIDNO("jailvote", "morenovotes"),
/** The message broadcasted whenever there aren't the minimum yes votes. */
VOTESNOTENOUGHYES("jailvote", "notenoughyes"),
/** The message broadcasted whenever the player the vote is for is no longer online. */
VOTEPLAYERNOLONGERONLINE("jailvote", "playernolongeronline"),
/** The message sent when a player tries to vote again for someone. */
VOTEALREADYVOTEDFOR("jailvote", "alreadyvotedfor"),
// Confirming action messages.
/** The message sent when the sender is already confirming something. */

View File

@ -43,6 +43,11 @@ public enum Settings {
JAILPAYITEM("jailpay.item"),
JAILPAYPRICEPERMINUTE ("jailpay.pricePerMinute"),
JAILPAYPRICEINFINITE ("jailpay.priceInfinite"),
JAILVOTEENABLED ("jailvote.enabled"),
JAILVOTETIMER ("jailvote.voteTimer"),
JAILMINYESVOTES ("jailvote.minimumYes"),
JAILVOTEREASON ("jailvote.reason"),
JAILVOTETIME ("jailvote.time"),
LANGUAGE("system.language"),
LOGJAILINGTOCONSOLE("jailing.jail.log.console"),
LOGJAILINGTOPROFILE("jailing.jail.log.profile"),