From a1fc73715c4b302f418bca4e1be8ce9272b70d78 Mon Sep 17 00:00:00 2001 From: Jon Langseth Date: Tue, 13 Mar 2012 20:27:49 +0100 Subject: [PATCH 1/1] Adding first version of YAVote code to Git repo --- b.sh | 18 +++ plugin.yml | 49 +++++++ src/no/defcon/yavote/Votemanager.java | 181 ++++++++++++++++++++++++++ src/no/defcon/yavote/YAVote.java | 178 +++++++++++++++++++++++++ todo.txt | 4 + 5 files changed, 430 insertions(+) create mode 100644 b.sh create mode 100644 plugin.yml create mode 100644 src/no/defcon/yavote/Votemanager.java create mode 100644 src/no/defcon/yavote/YAVote.java create mode 100644 todo.txt diff --git a/b.sh b/b.sh new file mode 100644 index 0000000..c4e3c39 --- /dev/null +++ b/b.sh @@ -0,0 +1,18 @@ +#!/bin/bash +if [ -d bin/no ]; then + rm -r bin/no 2>/dev/null +fi + +if [ ! -d bin/ ]; then + mkdir bin 2>/dev/null +fi + +rm YAVote*.jar 2>/dev/null + +javac -Werror -Xlint -d bin -s src -sourcepath src -cp .:src:bukkit-1.2.3-R0.2.jar src/no/defcon/yavote/YAVote.java +EX=$? +if [ $EX -ne 0 ]; then + echo Error in build. + exit $EX +fi +jar -cf YAVote.jar -C bin . plugin.yml todo.txt diff --git a/plugin.yml b/plugin.yml new file mode 100644 index 0000000..3eada92 --- /dev/null +++ b/plugin.yml @@ -0,0 +1,49 @@ +name: YAVote +main: no.defcon.yavote.YAVote +version: 1.4 +description: Yet Another Vote plugin for Bukkit +website: http://minecraft.defcon.no/yavote +authors: + - Jon Langseth +commands: + vote: + description: Start or take part in a vote + usage: | + / [parameter] + / sun - Vote for fine weather + / rain - Vote for rainy weather + / day - Vote to set the time to morning + / night - Vote to set the time to night + / yes|no - Respond positive or negative to current vote + / status - Return status of current vote + / cancel - Cancel a running vote. +permissions: + vote.weather.start: + description: Gives access to starting new votes for sun/rain + vote.weather.respond: + description: Gives access to responding to a started sun/rain vote + vote.time.start: + description: Gives access to starting a vote for day/night + vote.time.respond: + description: Gives access to responding to a started nay/night vote + vote.cancel: + description: Gives access to immediately canceling a running vote + vote.status: + description: Gives access to information on running vote + vote.weather.*: + description: Gives vote.weather.start and .respond + children: + vote.weather.start: true + vote.weather.respond: true + vote.time.*: + description: Gives vote.time.start and .respond + children: + vote.time.start: true + vote.time.respond: true + vote.*: + description: Gives access to all vote commands/options. + children: + vote.time.*: true + vote.weather.*: true + vote.cancel: true + vote.status: true \ No newline at end of file diff --git a/src/no/defcon/yavote/Votemanager.java b/src/no/defcon/yavote/Votemanager.java new file mode 100644 index 0000000..cf69d7e --- /dev/null +++ b/src/no/defcon/yavote/Votemanager.java @@ -0,0 +1,181 @@ +package no.defcon.yavote; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +public class Votemanager { + private JavaPlugin plugin; + private boolean voteRunning; + private String voteType; + private int expireTask; + private List yesVoters; + private List noVoters; + + + public Votemanager(JavaPlugin plugin) { + super(); + this.plugin = plugin; + this.voteRunning = false; + } + + public boolean cancelVote( ) + { + if ( voteRunning ) + { + plugin.getServer().broadcastMessage("Currently running vote is being canceled."); + plugin.getServer().getScheduler().cancelTask(expireTask); + clearState(); + return true; + } + return false; + } + + public boolean startVote( String type, Player p ) + { + if ( this.voteRunning ) + return false; + + if ( ! (type.equalsIgnoreCase("sun") || + type.equalsIgnoreCase("rain") || + type.equalsIgnoreCase("day") || + type.equalsIgnoreCase("night") )) + { + plugin.getLogger().info("Tried to start a vote of invalid type. Code error!"); + return false; + } + + voteType = type; + voteRunning = true; + + if ( yesVoters == null ) + yesVoters = new ArrayList(); + else + yesVoters.clear(); + + if ( noVoters == null ) + noVoters = new ArrayList(); + else + noVoters.clear(); + + yesVoters.add(p.getName()); + + if ( checkRatio( ) ) + { + applyVote( voteType ); + return true; + } + + expireTask = plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, new Runnable(){ + @Override + public void run() + { + if ( voteRunning ) + { + plugin.getServer().broadcastMessage("Time expired for voting on " + ((voteType != null) ? voteType : " .. uhm *blush*")); + clearState(); + } + else + { + plugin.getLogger().info("Timer expired but vote was not running :S"); + clearState(); + } + } + }, plugin.getConfig().getLong("vote.timeoutSeconds")*20L ); + + plugin.getServer().broadcastMessage("A vote has started for " + voteType.toLowerCase() ); + return true; + } + + public boolean isVoteRunning() + { + return voteRunning; + } + + public String getVoteType () + { + return voteType; + } + + public boolean addVote(Player player, boolean yes) + { + if ( ! voteRunning || (voteType == null ) ) + return false; + + if( yesVoters.contains(player.getName()) || noVoters.contains(player.getName()) ) + { + player.sendMessage("You have already cast your vote"); + return true; + } + if (yes == true) yesVoters.add(player.getName()); + else noVoters.add(player.getName()); + + if ( (yes == true) && checkRatio( ) ) + { + applyVote( voteType ); + return true; + } + else + { + if ( yesVoters.size() + noVoters.size() >= plugin.getServer().getOnlinePlayers().length ) + { + plugin.getServer().broadcastMessage("Vote failed for " + voteType); + plugin.getServer().getScheduler().cancelTask(expireTask); + clearState(); + return true; + } + player.sendMessage("Vote counted. Thank you."); + return true; + } + } + + private void applyVote(String type) + { + plugin.getServer().getScheduler().cancelTask(expireTask); + if ( ! voteRunning || (voteType == null ) ) + { + plugin.getLogger().info("No vote running, but I was told to apply one. ERRR"); + return; + } + + List worlds = plugin.getServer().getWorlds(); + for ( World w : worlds) + { + if ( voteType.equalsIgnoreCase("sun")) + w.setStorm(false); + else if ( voteType.equalsIgnoreCase("rain")) + w.setStorm(true); + else if ( voteType.equalsIgnoreCase("day")) + w.setTime( plugin.getConfig().getInt("vote.time.dayStart") ); + else if ( voteType.equalsIgnoreCase("night")) + w.setTime( plugin.getConfig().getInt("vote.time.nightStart") ); + } + plugin.getServer().broadcastMessage("Vote succeeded for " + ((voteType != null) ? voteType : " .. uhm *blush*")); + clearState(); + } + + private boolean checkRatio( ) + { + float required = 0.5F; + if ( voteType.equalsIgnoreCase("sun") || voteType.equalsIgnoreCase("rain") ) + required = (float)plugin.getConfig().getInt("vote.weather.requiredPercent") / 100.0F; + else if ( voteType.equalsIgnoreCase("day") || voteType.equalsIgnoreCase("night") ) + required = (float)plugin.getConfig().getInt("vote.time.requiredPercent") / 100.0F; + + float ratio = (float) yesVoters.size() / (float) plugin.getServer().getOnlinePlayers().length; + if ( ratio > required ) return true; + return false; + } + + private void clearState() + { + voteRunning = false; + voteType = null; + yesVoters.clear(); + noVoters.clear(); + } + +} diff --git a/src/no/defcon/yavote/YAVote.java b/src/no/defcon/yavote/YAVote.java new file mode 100644 index 0000000..cdb04f0 --- /dev/null +++ b/src/no/defcon/yavote/YAVote.java @@ -0,0 +1,178 @@ +package no.defcon.yavote; + +import java.io.File; + +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 org.bukkit.plugin.PluginLogger; + +public class YAVote extends JavaPlugin { + public PluginLogger logger; + private Votemanager manager; + + public void onDisable() { + // TODO: Stub. + } + + public void onEnable() { + logger = new PluginLogger(this); + manager = new Votemanager(this); + + // Set up default values for all missing config variables. + if ( ! getConfig().isSet("vote.timeoutSeconds") ) + getConfig().set("vote.timeoutSeconds", 15*60L); + + if ( ! getConfig().isSet("vote.weather.requiredPercent") ) + getConfig().set("vote.weather.requiredPercent", 33); + + if ( ! getConfig().isSet("vote.time.requiredPercent") ) + getConfig().set("vote.time.requiredPercent", 33); + + if ( ! getConfig().isSet("vote.time.dayStart") ) + getConfig().set("vote.time.dayStart", 23500); + + if ( ! getConfig().isSet("vote.time.nightStart") ) + getConfig().set("vote.time.nightStart", 12500); + + // Create config plugin data-dir if missing... + if(!getDataFolder().exists()) + { + logger.info("Creating configuration directory"); + getDataFolder().mkdirs(); + } + + // If config.yml is missing, create it by writing out defaults. + if(!new File(getDataFolder(), "config.yml").exists()) + { + logger.info("Creating configuration file"); + saveConfig(); + } + logger.info("Version " + getDescription().getVersion() + " is enabled!"); + } + + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args){ + if(cmd.getName().equalsIgnoreCase("vote")){ + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.RED + "You must be an online player!"); + return true; + } + Player player = (Player) sender; + + // TODO: Add check to verify that only one option is given. + + String voteCmd = args[0]; + + if ( voteCmd.equalsIgnoreCase("status") ) + { + if ( ! player.hasPermission("vote.status")) + return noPermissionsMessage(player); + + if ( ! manager.isVoteRunning() ) + { + sender.sendMessage("No vote is currently running."); + return true; + } + + return notImplemented(player); + } + + else if ( voteCmd.equalsIgnoreCase("cancel") ) + { + if ( ! player.hasPermission("vote.cancel")) + return noPermissionsMessage(player); + + if ( ! manager.isVoteRunning() ) + { + if (! manager.cancelVote() ) + player.sendMessage("I'm sorry, unable to cancel at this time."); + + return true; + } + + return notImplemented(player); + } + else if ( voteCmd.equalsIgnoreCase("sun") || voteCmd.equalsIgnoreCase("rain") || + voteCmd.equalsIgnoreCase("day") || voteCmd.equalsIgnoreCase("night") ) + { + if ( ! manager.isVoteRunning() ) + { + if ( ! testPermission(voteCmd, "start", player )) + return noPermissionsMessage(player); + + manager.startVote( voteCmd.toLowerCase(), player ); + return true; + } + else + { + if ( ! manager.getVoteType().equalsIgnoreCase( voteCmd ) ) + { + player.sendMessage("A vote for " + manager.getVoteType() + " is already running."); + return true; + } + + else if ( ! testPermission(voteCmd, "respond", player )) + return noPermissionsMessage(player); + + else if ( ! manager.addVote( player, true ) ) + { + player.sendMessage("Oops, I was unable to count your vote!"); + return true; + } + return true; + } + } + + else if ( voteCmd.equalsIgnoreCase("yes") || voteCmd.equalsIgnoreCase("no") ) + { + if ( ! manager.isVoteRunning() ) + { + sender.sendMessage("No vote running. Perhaps you want to start a new one?"); + return true; + } + if ( ! testPermission(manager.getVoteType(), "respond", player )) + return noPermissionsMessage(player); + + if ( ! manager.addVote( player, (voteCmd.equalsIgnoreCase("yes")?true:false)) ) + { + player.sendMessage("Oops, I was unable to count your vote!"); + return true; + } + return true; + } + + + + return notImplemented(player); + } + return false; + } + + private boolean notImplemented(Player p) { + p.sendMessage("It seems I do not know how to do that yet..."); + return true; + } + + private boolean noPermissionsMessage( Player p ){ + p.sendMessage("I'm sorry, " + p.getDisplayName() + ", I'm afraid I can't do that."); + return true; + } + + private boolean testPermission (String cmd, String action, Player p) + { + if ( ( cmd.equalsIgnoreCase("sun") ) || cmd.equalsIgnoreCase("rain") ) + { + if ( p.hasPermission("vote.weather." + action ) ) return true; + else return false; + } + if ( ( cmd.equalsIgnoreCase("day") ) || cmd.equalsIgnoreCase("night") ) + { + if ( p.hasPermission("vote.time." + action ) ) return true; + else return false; + } + return false; + } +} diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..5705553 --- /dev/null +++ b/todo.txt @@ -0,0 +1,4 @@ +Cooldown on commands? +Minimum votes? +Text strings in config or custom-config? +Per-world voting? \ No newline at end of file -- 2.39.2