requestrestart and cancelrestart

Post various suggestions here, if support is shown for your suggestion a vote will be started
Post Reply
A. Pippenger
in diamond armor
Posts: 364
Joined: Fri Aug 02, 2013 9:55 am

requestrestart and cancelrestart

Post by A. Pippenger »

There were almost 40 people online for a while and I was thinking, if 39 people wanted a restart and 1 person didn't, the 1 guy would be able to cancel a restart and fuck over the whole server, which seems unfair.

So I was wondering if there would be some way to set it up so that multiple people could vote on whether there will be a reset or not instead of giving 1 person veto power. Maybe if there are 10 or fewer people online, it should take only 1 person to /cancel the restart, but if there are 20, it should take 2, 30 should take 3, and so on. Or something like that. What do yall think?
User avatar
DakkaDok
OP
Posts: 301
Joined: Sat Nov 24, 2012 12:23 pm
Location: Terra, Imperial Palace

Re: requestrestart and cancelrestart

Post by DakkaDok »

That would certainly be possible, but someone would have to program it into the plugin. Sounds good, but I can't do that.
A. Pippenger
in diamond armor
Posts: 364
Joined: Fri Aug 02, 2013 9:55 am

Re: requestrestart and cancelrestart

Post by A. Pippenger »

clipchip sent me a link to the code, it's actually more than I expected because it has to stop people voting twice, stop people from voting if they've played under 500 hours, etc...

Code: Select all

package net.simpvp.Misc;

import org.bukkit.ChatColor;
import org.bukkit.Statistic;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.UUID;

public class Restart implements CommandExecutor {
	/* Let's player use the /requestrestart and /cancelrestart commands */

	private static JavaPlugin plugin = Misc.instance;

	private static boolean cancelled = true;
	private static UUID requester = null;
	private static long last_request = System.currentTimeMillis();

	public boolean onCommand(CommandSender sender,
			Command cmd,
			String label,
			String[] args) {

		Player player = null;
		if (sender instanceof Player) {
			player = (Player) sender;

			int played_ticks = player.getStatistic(Statistic.PLAY_ONE_MINUTE);
			int played_hours = played_ticks / (20 * 60 * 60);

			if (played_hours < 500) {
				player.sendMessage(ChatColor.RED + "You need to have played for at least 500 hours on this server to use this command.");
				return true;
			}
		}

		if (cmd.getName().equals("requestrestart")) {
			if (player == null) {
				sender.sendMessage("Only players can use this command");
				return true;
			}

			/* 5 minute waiting period */
			if (System.currentTimeMillis() <
					(5 * 60 * 1000) + last_request) {
				player.sendMessage(ChatColor.RED
						+ "A restart has been requested too recently. Please wait a bit longer before requesting a restart.");
				return true;
			}

			/* All checks completed */


			String msg = "[Announcement] " + player.getName() + " has requested a server restart. If you disagree with this request, type /cancelrestart. If it is not cancelled, the server will restart in 30 seconds.";
			for (Player p : plugin.getServer().getOnlinePlayers()) {
				p.sendMessage(ChatColor.AQUA + msg);
			}
			plugin.getLogger().info(msg);

			last_request = System.currentTimeMillis();
			cancelled = false;
			requester = player.getUniqueId();

			/* What we do now is a create an asynchronous task that
			 * waits 30 seconds and then creates a synchronous task
			 * that calls sync_effect_restart */
			new BukkitRunnable() {
				@Override
				public void run() {
					try {
						Thread.sleep(30000);
					} catch (InterruptedException e) {
						return;
					}
					new BukkitRunnable() {
						@Override
						public void run() {
							sync_effect_restart();
						}
					}.runTaskLater(plugin, 0);
				}
			}.runTaskAsynchronously(plugin);

		} else if (cmd.getName().equals("cancelrestart")) {
			if (cancelled == true) {
				sender.sendMessage("There is no restart for you to cancel.");
			} else if (requester != null && player != null &&
					requester.equals(player.getUniqueId())) {
				sender.sendMessage("You cannot cancel a restart you requested.");
			} else {
				cancelled = true;
				String msg = "[Announcement] " + sender.getName() + " has cancelled the requested server restart. Tip: Ask in chat if anybody minds a restart before initiating one.";
				for (Player p : plugin.getServer().getOnlinePlayers()) {
					p.sendMessage(ChatColor.AQUA + msg);
				}
				plugin.getLogger().info(msg);
			}
		}

		return true;
	}

	/** Effect the restart, i.e. check whether the restart has been
	 * cancelled, and if it hasn't then actually restart.
	 *
	 * This should be called synchronously so it can use Bukkit */
	private void sync_effect_restart() {
		if (cancelled == true) {
			return;
		}

		plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(),
				"stop");
	}

}
I'm gonna try changing it but it probably won't work until we fix it up.

Code: Select all

package net.simpvp.Misc;

import org.bukkit.ChatColor;
import org.bukkit.Statistic;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.UUID;

public class Restart implements CommandExecutor {
	/* Let's player use the /requestrestart and /cancelrestart commands */

	private static JavaPlugin plugin = Misc.instance;
	
	private int voteTotal = 0;

	private static boolean cancelled = true;
	private static UUID requester = null;
	private static long last_request = System.currentTimeMillis();

	public boolean onCommand(CommandSender sender,
			Command cmd,
			String label,
			String[] args) {

		Player player = null;
		if (sender instanceof Player) {
			player = (Player) sender;

			int played_ticks = player.getStatistic(Statistic.PLAY_ONE_MINUTE);
			int played_hours = played_ticks / (20 * 60 * 60);

			if (played_hours < 500) {
				player.sendMessage(ChatColor.RED + "You need to have played for at least 500 hours on this server to use this command.");
				return true;
			}
		}

		if (cmd.getName().equals("requestrestart")) {
			if (player == null) {
				sender.sendMessage("Only players can use this command");
				return true;
			}

			/* 5 minute waiting period */
			if (System.currentTimeMillis() <
					(5 * 60 * 1000) + last_request) {
				player.sendMessage(ChatColor.RED
						+ "A restart has been requested too recently. Please wait a bit longer before requesting a restart.");
				return true;
			}

			/* All checks completed */


			String msg = "[Announcement] " + player.getName() + " has requested a server restart. If you disagree with this request, type /cancelrestart. If you agree, type /agreerestart. If it is not cancelled, the server will restart in 30 seconds.";
			for (Player p : plugin.getServer().getOnlinePlayers()) {
				p.sendMessage(ChatColor.AQUA + msg);
			}
			plugin.getLogger().info(msg);

			last_request = System.currentTimeMillis();
			cancelled = false;
			requester = player.getUniqueId();

			/* What we do now is a create an asynchronous task that
			 * waits 30 seconds and then creates a synchronous task
			 * that calls sync_effect_restart */
			new BukkitRunnable() {
				@Override
				public void run() {
					try {
						Thread.sleep(30000);
					} catch (InterruptedException e) {
						return;
					}
					new BukkitRunnable() {
						@Override
						public void run() {
							sync_effect_restart();
						}
					}.runTaskLater(plugin, 0);
				}
			}.runTaskAsynchronously(plugin);

		} else if (cmd.getName().equals("cancelrestart")) {
			if (cancelled == true) {
				sender.sendMessage("There is no restart for you to cancel.");
			} else if (requester != null && player != null &&
					requester.equals(player.getUniqueId())) {
				sender.sendMessage("You cannot cancel a restart you requested.");
			} else {
				voteTotal -=1;
				plugin.getLogger().info(msg);
			}
			
			} else if (cmd.getName().equals("agreerestart")) {
			if (cancelled == true) {
				sender.sendMessage("There is no restart for you to agree with.");
			} else if (requester != null && player != null &&
					requester.equals(player.getUniqueId())) {
				sender.sendMessage("You cannot vote for a restart you requested.");
			} else {
				voteTotal +=1;
				plugin.getLogger().info(msg);
			}
		}

		return true;
	}

	/** Effect the restart, i.e. check whether the restart has been
	 * cancelled, and if it hasn't then actually restart.
	 *
	 * This should be called synchronously so it can use Bukkit */
	 
	 cancelled = false;
	 	if (voteTotal >0) {
	 	cancelled = true;
	 	voteTotal = 0;
	 	}
	 
	private void sync_effect_restart() {
		if (cancelled == true) {
			return;
		}

		plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(),
				"stop");
	}

}
I'm not very skilled at java but basically the idea is to make a new int variable voteTotal and whether or not the reset happens depends on whether that total is greater than zero or not. Hopefully yukar or clipchip can make it actually work, if people think it's a good idea
A. Pippenger
in diamond armor
Posts: 364
Joined: Fri Aug 02, 2013 9:55 am

Re: requestrestart and cancelrestart

Post by A. Pippenger »

People have been complaining today about resets being cancelled by small numbers of people. My idea could fix this problem if Yukarion just copies my code but with less bugs.
Yukar9
Admin
Posts: 3242
Joined: Sat Aug 13, 2011 12:08 pm

Re: requestrestart and cancelrestart

Post by Yukar9 »

I am of the opinion that it is working as intended currently. Yes, sometimes people will cancel restarts just to annoy people, but in some sense that's their right. The idea behind the way /requestrestart works is that everybody online should agree to the server restart, in other words you're not entitled to a restart when other people don't want one.

I think it's working fine because the server does get restarted frequently, it's rare to see it over 10 hours uptime.

I also think people overestimate the benefits of restarts, they're not a magic solution to lag.
Post Reply