Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 82 additions & 44 deletions src/main/java/com/wkaye/jvote/JVoteCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.bukkit.entity.Player;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
Expand All @@ -23,10 +24,15 @@ public class JVoteCommand implements CommandExecutor {
AtomicBoolean isVoteTimePassed;
AtomicInteger countdownTaskId;

private enum VoteValue {
YES, NO, NONE
}

// enum: task ID mapping for cancelling task
ConcurrentHashMap<JVoteEnums, Integer> isOnCooldown;
AtomicInteger totalVotes;
HashSet<Player> playerHasVoted;
HashMap<Player, VoteValue> playerVotes;
HashSet<Player> playerVoteChanged;
JVoteEnums currentVoteType;

private final boolean fundamentalsPresent;
Expand All @@ -37,7 +43,8 @@ public JVoteCommand(JVote plugin) {
voteStarted = new AtomicBoolean(false);
isVoteTimePassed = new AtomicBoolean(false);
totalVotes = new AtomicInteger(0);
playerHasVoted = new HashSet<>();
playerVotes = new HashMap<>();
playerVoteChanged = new HashSet<>();
isOnCooldown = new ConcurrentHashMap<>();
countdownTaskId = new AtomicInteger();

Expand All @@ -56,12 +63,17 @@ End vote after a timer (1 minute will be baseline)
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// there should be two types of votes: one where the vote is initiated, and one where the vote is yes/no
boolean override = false;
if (args.length != 1) {
String msg = JVoteUtils.printMessage("Proper usage is &a/vote <day/night/rain/storm/clear>");
sender.sendMessage(msg);
// invalid usage (should be /vote {type of vote}
plugin.logger(Level.WARNING, "Attempted /vote with invalid number of args");
return true;
if (args.length == 2 && args[1].equalsIgnoreCase("confirm")) {
override = true;
} else {
String msg = JVoteUtils.printMessage("Proper usage is &a/vote <day/night/rain/storm/clear>");
sender.sendMessage(msg);
// invalid usage (should be /vote {type of vote}
plugin.logger(Level.WARNING, "Attempted /vote with invalid number of args");
return true;
}
}
if (!(sender instanceof Player)) {
// command not available to console message
Expand All @@ -79,9 +91,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
try {
JVoteEnums inputVoteType = JVoteEnums.valueOf(args[0].toUpperCase());
// Check if the input vote type matches the current vote type
if (inputVoteType == currentVoteType ||
(inputVoteType == JVoteEnums.CLEAR && currentVoteType == JVoteEnums.SUN) ||
(inputVoteType == JVoteEnums.SUN && currentVoteType == JVoteEnums.CLEAR)) {
if (inputVoteType == currentVoteType || (inputVoteType == JVoteEnums.CLEAR && currentVoteType == JVoteEnums.SUN) || (inputVoteType == JVoteEnums.SUN && currentVoteType == JVoteEnums.CLEAR)) {
isVotingForCurrentType = true;
}
} catch (IllegalArgumentException e) {
Expand All @@ -90,13 +100,13 @@ public boolean onCommand(CommandSender sender, Command command, String label, St

if (isVotingForCurrentType) {
// They're voting for the same type as current vote, treat as "yes"
if (checkVote("yes", player)) {
if (checkVote("yes", player, override)) {
doVote();
return true;
}
} else if ("yes".contains(arg) || "no".contains(arg) || "ok".contains(arg)) {
// Normal yes/no/ok voting
if (checkVote(args[0], player)) {
if (checkVote(args[0], player, override)) {
// vote passed, perform change and reset values
doVote();
return true;
Expand All @@ -121,13 +131,9 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
// TODO: fetch these from some config file. For now, only day/night and clear/rain/storm
// invalid usage, return false
currentVoteType = JVoteEnums.valueOf(args[0].toUpperCase());
String msg = JVoteUtils.printMessage(
"A vote for "
+ JVoteUtils.formatColor(currentVoteType.color())
+ JVoteUtils.formatColor(currentVoteType.toString().toLowerCase())
+ JVoteUtils.formatColor("&7 has started. Vote by doing &a/vote <yes/no/" + currentVoteType.toString().toLowerCase() + ">"));
String msg = JVoteUtils.printMessage("A vote for " + JVoteUtils.formatColor(currentVoteType.color()) + JVoteUtils.formatColor(currentVoteType.toString().toLowerCase()) + JVoteUtils.formatColor("&7 has started. Vote by doing &a/vote <yes/no/" + currentVoteType.toString().toLowerCase() + ">"));
plugin.getServer().broadcastMessage(msg);
if (checkVote("yes", player)) {
if (checkVote("yes", player, false)) {
doVote();
} else {
doVoteTimer();
Expand Down Expand Up @@ -159,22 +165,57 @@ private int getEligiblePlayerCount() {
return count;
}

private boolean checkVote(String arg, CommandSender sender) {
private boolean checkVote(String arg, CommandSender sender, boolean override) {
Player player = (Player) sender;
double currentVotePercentage = 0;
if (playerHasVoted.contains(player)) {
// send message to player that he/she already voted and return
String msg = JVoteUtils.printMessage("You have already voted");
sender.sendMessage(msg);
return false;

VoteValue vote = VoteValue.NONE;
if ("yes".contains(arg.toLowerCase()) || "ok".contains(arg.toLowerCase())) {
vote = VoteValue.YES;
} else if ("no".contains(arg.toLowerCase())) {
vote = VoteValue.NO;
}

if (!playerVotes.containsKey(player)) {
sender.sendMessage(JVoteUtils.printMessage("You have voted"));
} else {
if (playerVoteChanged.contains(player)) {
// send message to player that he/she already voted and return
String msg = JVoteUtils.printMessage("You have already voted");
sender.sendMessage(msg);
return false;
}

if (!override) {
// send message to player to confirm vote change
String msg = JVoteUtils.printMessage("To change your vote, use &a/vote <yes/no> confirm");
sender.sendMessage(msg);
return false;
}

if (vote == playerVotes.get(player)) {
String msg = JVoteUtils.printMessage("You cannot change your vote to the same value");
sender.sendMessage(msg);
return false;
}

sender.sendMessage(JVoteUtils.printMessage("You have changed your vote"));
playerVoteChanged.add(player);

// Undo the player's previous vote
if (playerVotes.get(player) == VoteValue.NO) {
totalVotes.incrementAndGet();
} else if (playerVotes.get(player) == VoteValue.YES) {
totalVotes.decrementAndGet();
}
}
sender.sendMessage(JVoteUtils.printMessage("You have voted"));
playerHasVoted.add(player);

playerVotes.put(player, vote);
int eligible = getEligiblePlayerCount();
if (eligible == 0) return false;
if ("yes".contains(arg.toLowerCase()) || "ok".contains(arg.toLowerCase())) {
if (vote == VoteValue.YES) {
currentVotePercentage = (double) totalVotes.incrementAndGet() / eligible;
} else if ("no".contains(arg.toLowerCase())) {
} else if (vote == VoteValue.NO) {
currentVotePercentage = (double) totalVotes.decrementAndGet() / eligible;
}
if (plugin.getDebugLevel() > 0) {
Expand All @@ -199,34 +240,34 @@ private void doVote() {
} else {
switch (currentVoteType) {
case DAY:
for(World world : Bukkit.getWorlds()){
for (World world : Bukkit.getWorlds()) {
world.setTime(0);
}
break;
case NIGHT:
for(World world : Bukkit.getWorlds()){
for (World world : Bukkit.getWorlds()) {
world.setTime(14000);
}
break;
case SUN:
case CLEAR:
for(World world : Bukkit.getWorlds()){
for (World world : Bukkit.getWorlds()) {
if (world.hasStorm()) {
world.setThundering(false);
world.setWeatherDuration(5);
}
}
break;
case RAIN:
for(World world : Bukkit.getWorlds()){
for (World world : Bukkit.getWorlds()) {
if (!world.hasStorm()) {
world.setWeatherDuration(5);
}
world.setThundering(false);
}
break;
case STORM:
for(World world : Bukkit.getWorlds()){
for (World world : Bukkit.getWorlds()) {
if (!world.hasStorm()) {
world.setWeatherDuration(5);
}
Expand All @@ -248,20 +289,19 @@ private void resetValues(JVoteEnums cmd) {
totalVotes.set(0);
isVoteTimePassed.set(false);
currentVoteType = null;
playerHasVoted.clear();
playerVotes.clear();
playerVoteChanged.clear();
int cooldownTimer = JVoteConfig.getInstance().getConfigInteger("settings.cooldown-timer-ticks");
if (cmd.equals(JVoteEnums.CLEAR) || cmd.equals(JVoteEnums.SUN)) {
isOnCooldown.putIfAbsent(JVoteEnums.SUN, 0);
isOnCooldown.putIfAbsent(JVoteEnums.CLEAR, 0);
Bukkit.getScheduler().scheduleAsyncDelayedTask(plugin, () -> {
isOnCooldown.remove(JVoteEnums.CLEAR);
isOnCooldown.remove(JVoteEnums.SUN);
}, cooldownTimer
);
isOnCooldown.remove(JVoteEnums.CLEAR);
isOnCooldown.remove(JVoteEnums.SUN);
}, cooldownTimer);
} else {
isOnCooldown.putIfAbsent(cmd, 0);
Bukkit.getScheduler().scheduleAsyncDelayedTask(plugin, () -> isOnCooldown.remove(cmd),
cooldownTimer);
Bukkit.getScheduler().scheduleAsyncDelayedTask(plugin, () -> isOnCooldown.remove(cmd), cooldownTimer);
}
}

Expand All @@ -282,10 +322,8 @@ private void doVoteTimer() {
resetValues(currentVoteType);
}
} else {
ArrayList<Integer> frequencies = (ArrayList<Integer>)
JVoteConfig.getInstance().getConfigOption("settings.reminder-frequency");
if (JVoteConfig.getInstance().getConfigBoolean("settings.toggle-timer") &&
frequencies.contains(curr)) {
ArrayList<Integer> frequencies = (ArrayList<Integer>) JVoteConfig.getInstance().getConfigOption("settings.reminder-frequency");
if (JVoteConfig.getInstance().getConfigBoolean("settings.toggle-timer") && frequencies.contains(curr)) {
plugin.getServer().broadcastMessage(JVoteUtils.printMessage(curr + " seconds remaining"));
}
}
Expand Down