Merge branch 'master' of github.com:essentials/Essentials into essmaster

This commit is contained in:
KHobbits 2011-10-27 05:48:45 +01:00
commit 32cc1b66a4
33 changed files with 1087 additions and 556 deletions

View File

@ -1,12 +1,11 @@
package com.earth2me.essentials.update;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public abstract class WorkListener
public abstract class AbstractWorkListener
{
public WorkListener(final Plugin plugin, final VersionInfo newVersionInfo)
public AbstractWorkListener(final Plugin plugin, final VersionInfo newVersionInfo)
{
this.plugin = plugin;
this.newVersionInfo = newVersionInfo;

View File

@ -1,16 +1,16 @@
package com.earth2me.essentials.update;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import com.earth2me.essentials.update.chat.Command;
import com.earth2me.essentials.update.chat.ConfigCommand;
import com.earth2me.essentials.update.chat.ErrorsCommand;
import com.earth2me.essentials.update.chat.HelpCommand;
import com.earth2me.essentials.update.chat.IrcBot;
import com.earth2me.essentials.update.chat.ListCommand;
import com.earth2me.essentials.update.chat.StartupCommand;
import com.earth2me.essentials.update.chat.UsernameUtil;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -21,7 +21,6 @@ import org.bukkit.event.player.PlayerListener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.jibble.pircbot.User;
public class EssentialsHelp extends PlayerListener
@ -29,14 +28,19 @@ public class EssentialsHelp extends PlayerListener
private transient Player chatUser;
private final transient Server server;
private final transient Plugin plugin;
private final static Charset UTF8 = Charset.forName("utf-8");
private transient IrcBot ircBot;
private final transient Map<String, Command> commands = new HashMap<String, Command>();
public EssentialsHelp(final Plugin plugin)
{
super();
this.plugin = plugin;
this.server = plugin.getServer();
commands.put("!help", new HelpCommand());
commands.put("!list", new ListCommand());
commands.put("!startup", new StartupCommand(plugin));
commands.put("!errors", new ErrorsCommand(plugin));
commands.put("!config", new ConfigCommand(plugin));
}
public void registerEvents()
@ -46,7 +50,7 @@ public class EssentialsHelp extends PlayerListener
pluginManager.registerEvent(Type.PLAYER_CHAT, this, Priority.Low, plugin);
}
public void onCommand(CommandSender sender)
public void onCommand(final CommandSender sender)
{
if (sender instanceof Player && sender.hasPermission("essentials.helpchat"))
{
@ -74,11 +78,7 @@ public class EssentialsHelp extends PlayerListener
public void onDisable()
{
if ( ircBot != null)
{
ircBot.quit();
ircBot = null;
}
closeConnection();
}
private boolean sendChatMessage(final Player player, final String message)
@ -90,35 +90,19 @@ public class EssentialsHelp extends PlayerListener
}
if (ircBot == null)
{
if (messageCleaned.equalsIgnoreCase("yes"))
{
player.sendMessage("Connecting...");
connectToIRC(player);
return true;
}
if (messageCleaned.equalsIgnoreCase("no") || message.equalsIgnoreCase("!quit"))
{
chatUser = null;
return true;
}
return false;
return handleAnswer(messageCleaned, player);
}
else
{
if (ircBot.isKicked()) {
chatUser = null;
ircBot.quit();
ircBot = null;
if (ircBot.isKicked())
{
closeConnection();
return false;
}
final String lowMessage = messageCleaned.toLowerCase();
final String lowMessage = messageCleaned.toLowerCase(Locale.ENGLISH);
if (lowMessage.startsWith("!quit"))
{
chatUser = null;
if (ircBot != null) {
ircBot.quit();
ircBot = null;
}
closeConnection();
player.sendMessage("Connection closed.");
return true;
}
@ -126,52 +110,8 @@ public class EssentialsHelp extends PlayerListener
{
return false;
}
if (lowMessage.startsWith("!list"))
if (handleCommands(lowMessage, player))
{
final User[] members = ircBot.getUsers();
final StringBuilder sb = new StringBuilder();
for (User user : members)
{
if (sb.length() > 0)
{
sb.append("§f, ");
}
if (user.isOp() || user.hasVoice())
{
sb.append("§6");
}
else
{
sb.append("§7");
}
sb.append(user.getPrefix()).append(user.getNick());
}
player.sendMessage(sb.toString());
return true;
}
if (lowMessage.startsWith("!help"))
{
player.sendMessage("Commands: (Note: Files send to the chat will be public viewable.)");
player.sendMessage("!errors - Send the last server errors to the chat.");
player.sendMessage("!startup - Send the last startup messages to the chat.");
player.sendMessage("!config - Sends your Essentials config to the chat.");
player.sendMessage("!list - List all players in chat.");
player.sendMessage("!quit - Leave chat.");
return true;
}
if (lowMessage.startsWith("!errors"))
{
sendErrors();
return true;
}
if (lowMessage.startsWith("!startup"))
{
sendStartup();
return true;
}
if (lowMessage.startsWith("!config"))
{
sendConfig();
return true;
}
ircBot.sendMessage(messageCleaned);
@ -180,300 +120,62 @@ public class EssentialsHelp extends PlayerListener
}
}
private String buildIrcName()
private void closeConnection()
{
final StringBuilder nameBuilder = new StringBuilder();
nameBuilder.append(chatUser.getName());
final Matcher versionMatch = Pattern.compile("git-Bukkit-([0-9]+).([0-9]+).([0-9]+)-[0-9]+-[0-9a-z]+-b([0-9]+)jnks.*").matcher(server.getVersion());
if (versionMatch.matches())
chatUser = null;
if (ircBot != null)
{
nameBuilder.append(" CB");
nameBuilder.append(versionMatch.group(4));
ircBot.quit();
ircBot = null;
}
}
final Plugin essentials = server.getPluginManager().getPlugin("Essentials");
if (essentials != null)
private boolean handleAnswer(final String message, final Player player)
{
if (message.equalsIgnoreCase("yes"))
{
nameBuilder.append(" ESS");
nameBuilder.append(essentials.getDescription().getVersion());
player.sendMessage("Connecting...");
connectToIRC(player);
return true;
}
final Plugin groupManager = server.getPluginManager().getPlugin("GroupManager");
if (groupManager != null)
if (message.equalsIgnoreCase("no") || message.equalsIgnoreCase("!quit"))
{
nameBuilder.append(" GM");
if (!groupManager.isEnabled())
{
nameBuilder.append('!');
}
chatUser = null;
return true;
}
return false;
}
final Plugin pex = server.getPluginManager().getPlugin("PermissionsEx");
if (pex != null)
private boolean handleCommands(final String lowMessage, final Player player)
{
final String[] parts = lowMessage.split(" ");
if (commands.containsKey(parts[0]))
{
nameBuilder.append(" PEX");
if (!pex.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(pex.getDescription().getVersion());
commands.get(parts[0]).run(ircBot, player);
return true;
}
final Plugin pb = server.getPluginManager().getPlugin("PermissionsBukkit");
if (pb != null)
{
nameBuilder.append(" PB");
if (!pb.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(pb.getDescription().getVersion());
}
final Plugin bp = server.getPluginManager().getPlugin("bPermissions");
if (bp != null)
{
nameBuilder.append(" BP");
if (!bp.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(bp.getDescription().getVersion());
}
final Plugin perm = server.getPluginManager().getPlugin("Permissions");
if (perm != null)
{
nameBuilder.append(" P");
if (!perm.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(perm.getDescription().getVersion());
}
return nameBuilder.toString();
return false;
}
private void connectToIRC(final Player player)
{
ircBot = new IrcBot(player, "Ess_" + player.getName(), buildIrcName());
}
private void sendErrors()
{
BufferedReader page = null;
try
{
File bukkitFolder = plugin.getDataFolder().getAbsoluteFile().getParentFile().getParentFile();
if (bukkitFolder == null || !bukkitFolder.exists())
{
chatUser.sendMessage("Bukkit folder not found.");
return;
}
File logFile = new File(bukkitFolder, "server.log");
if (!logFile.exists())
{
chatUser.sendMessage("Server log not found.");
return;
}
FileInputStream fis = new FileInputStream(logFile);
if (logFile.length() > 1000000)
{
fis.skip(logFile.length() - 1000000);
}
page = new BufferedReader(new InputStreamReader(fis));
final StringBuilder input = new StringBuilder();
String line;
Pattern pattern = Pattern.compile("^[0-9 :-]+\\[INFO\\].*");
while ((line = page.readLine()) != null)
{
if (!pattern.matcher(line).matches())
{
input.append(line).append("\n");
}
}
if (input.length() > 10000)
{
input.delete(0, input.length() - 10000);
}
final PastieUpload pastie = new PastieUpload();
final String url = pastie.send(input.toString());
String message = "Errors: " + url;
chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + message);
ircBot.sendMessage(message);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
chatUser.sendMessage(ex.getMessage());
}
finally
{
try
{
if (page != null)
{
page.close();
}
}
catch (IOException ex)
{
Logger.getLogger(EssentialsHelp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void sendStartup()
{
BufferedReader page = null;
try
{
File bukkitFolder = plugin.getDataFolder().getAbsoluteFile().getParentFile().getParentFile();
if (bukkitFolder == null || !bukkitFolder.exists())
{
chatUser.sendMessage("Bukkit folder not found.");
return;
}
File logFile = new File(bukkitFolder, "server.log");
if (!logFile.exists())
{
chatUser.sendMessage("Server log not found.");
return;
}
FileInputStream fis = new FileInputStream(logFile);
if (logFile.length() > 1000000)
{
fis.skip(logFile.length() - 1000000);
}
page = new BufferedReader(new InputStreamReader(fis));
final StringBuilder input = new StringBuilder();
String line;
Pattern patternStart = Pattern.compile("^[0-9 :-]+\\[INFO\\] Starting minecraft server version.*");
Pattern patternEnd = Pattern.compile("^[0-9 :-]+\\[INFO\\] Done \\([0-9.,]+s\\)! For help, type \"help\".*");
boolean log = false;
while ((line = page.readLine()) != null)
{
if (patternStart.matcher(line).matches())
{
if (input.length() > 0)
{
input.delete(0, input.length());
}
log = true;
}
if (log)
{
input.append(line).append("\n");
}
if (patternEnd.matcher(line).matches())
{
log = false;
}
}
if (input.length() > 10000)
{
input.delete(0, input.length() - 10000);
}
final PastieUpload pastie = new PastieUpload();
final String url = pastie.send(input.toString());
String message = "Startup: " + url;
chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + message);
ircBot.sendMessage(message);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
chatUser.sendMessage(ex.getMessage());
}
finally
{
try
{
if (page != null)
{
page.close();
}
}
catch (IOException ex)
{
Logger.getLogger(EssentialsHelp.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void sendConfig()
{
BufferedReader page = null;
try
{
File configFolder = new File(plugin.getDataFolder().getParentFile(), "Essentials");
if (!configFolder.exists())
{
chatUser.sendMessage("Essentials plugin folder not found.");
return;
}
File configFile = new File(configFolder, "config.yml");
if (!configFile.exists())
{
chatUser.sendMessage("Essentials config file not found.");
return;
}
page = new BufferedReader(new InputStreamReader(new FileInputStream(configFile), UTF8));
final StringBuilder input = new StringBuilder();
String line;
while ((line = page.readLine()) != null)
{
input.append(line).append("\n");
}
final PastieUpload pastie = new PastieUpload();
final String url = pastie.send(input.toString());
String message = "Essentials config.yml: " + url;
chatUser.sendMessage("§6" + ircBot.getNick() + ": §7" + message);
ircBot.sendMessage(message);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
chatUser.sendMessage(ex.getMessage());
}
finally
{
try
{
if (page != null)
{
page.close();
}
}
catch (IOException ex)
{
Logger.getLogger(EssentialsHelp.class.getName()).log(Level.SEVERE, null, ex);
}
}
ircBot = new IrcBot(player, "Ess_" + player.getName(), UsernameUtil.createUsername(player));
}
@Override
public void onPlayerChat(PlayerChatEvent event)
public void onPlayerChat(final PlayerChatEvent event)
{
if (event.getPlayer() == chatUser)
{
boolean success = sendChatMessage(event.getPlayer(), event.getMessage());
final boolean success = sendChatMessage(event.getPlayer(), event.getMessage());
event.setCancelled(success);
return;
}
}
@Override
public void onPlayerQuit(PlayerQuitEvent event)
public void onPlayerQuit(final PlayerQuitEvent event)
{
chatUser = null;
if (ircBot != null) {
ircBot.quit();
ircBot = null;
}
return;
closeConnection();
}
}

View File

@ -1,6 +1,7 @@
package com.earth2me.essentials.update;
import com.earth2me.essentials.update.UpdateCheck.CheckResult;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -16,26 +17,20 @@ public class EssentialsUpdate extends JavaPlugin
public void onEnable()
{
if (!getDataFolder().exists() && !getDataFolder().mkdirs() ) {
Bukkit.getLogger().severe("Could not create data folder:"+getDataFolder().getPath());
Bukkit.getLogger().log(Level.SEVERE, "Could not create data folder: {0}", getDataFolder().getPath());
}
essentialsHelp = new EssentialsHelp(this);
essentialsHelp.registerEvents();
final UpdateCheck updateCheck = new UpdateCheck(this);
updateCheck.checkForUpdates();
updateProcess = new UpdateProcess(this, updateCheck);
updateProcess.registerEvents();
Bukkit.getLogger().info("EssentialsUpdate " + getDescription().getVersion() + " loaded.");
Bukkit.getLogger().log(Level.INFO, "EssentialsUpdate {0} loaded.", getDescription().getVersion());
if (updateCheck.isEssentialsInstalled())
{
updateCheck.checkForUpdates();
final Version myVersion = new Version(getDescription().getVersion());
if (updateCheck.getResult() == CheckResult.NEW_ESS && myVersion.equals(updateCheck.getNewVersion()))
{
Bukkit.getLogger().info("Versions of EssentialsUpdate and Essentials do not match. Starting automatic update.");
updateProcess.doAutomaticUpdate();
}
updateCheck.scheduleUpdateTask();
}
else

View File

@ -12,7 +12,8 @@ import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Logger;
import java.util.logging.Level;
import org.bukkit.Bukkit;
public class GetFile
@ -53,7 +54,7 @@ public class GetFile
}
catch (NoSuchAlgorithmException ex)
{
// Ignore because the code is never called
throw new RuntimeException(ex);
}
}
@ -101,7 +102,7 @@ public class GetFile
}
if (brokenFile && !file.delete())
{
Logger.getLogger("Minecraft").severe("Could not delete file " + file.getPath());
Bukkit.getLogger().log(Level.SEVERE, "Could not delete file {0}", file.getPath());
}
}
finally

View File

@ -3,7 +3,6 @@ package com.earth2me.essentials.update;
import java.io.File;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
@ -22,7 +21,7 @@ public class UpdateCheck
private final transient Plugin plugin;
private transient boolean essentialsInstalled;
public UpdateCheck(Plugin plugin)
public UpdateCheck(final Plugin plugin)
{
this.plugin = plugin;
updateFile = new UpdateFile(plugin);
@ -31,21 +30,20 @@ public class UpdateCheck
private void checkForEssentials()
{
PluginManager pm = plugin.getServer().getPluginManager();
Plugin essentials = pm.getPlugin("Essentials");
if (essentials == null)
final PluginManager pluginManager = plugin.getServer().getPluginManager();
final Plugin essentials = pluginManager.getPlugin("Essentials");
essentialsInstalled = essentials != null;
if (essentialsInstalled)
{
currentVersion = new Version(essentials.getDescription().getVersion());
}
else
{
essentialsInstalled = false;
if (new File(plugin.getDataFolder().getParentFile(), "Essentials.jar").exists())
{
Bukkit.getLogger().severe("Essentials.jar found, but not recognized by Bukkit. Broken download?");
}
}
else
{
essentialsInstalled = true;
currentVersion = new Version(essentials.getDescription().getVersion());
}
}
public void scheduleUpdateTask()
@ -71,16 +69,17 @@ public class UpdateCheck
return result;
}
int getNewBukkitVersion()
public int getNewBukkitVersion()
{
return bukkitResult;
}
VersionInfo getNewVersionInfo()
public VersionInfo getNewVersionInfo()
{
return updateFile.getVersions().get(newVersion);
}
public enum CheckResult
{
NEW_ESS, NEW_ESS_BUKKIT, NEW_BUKKIT, OK, UNKNOWN

View File

@ -14,13 +14,14 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.configuration.file.YamlConfiguration;
public class UpdateFile
{
private final static Logger LOGGER = Logger.getLogger("Minecraft");
private final static Logger LOGGER = Bukkit.getLogger();
private final static String UPDATE_URL = "http://goo.gl/67jev";
private final static BigInteger PUBLIC_KEY = new BigInteger("5ha6a2d4qdy17ttkg8evh74sl5a87djojwenu12k1lvy8ui6003e6l06rntczpoh99mhc3txj8mqlxw111oyy9yl7s7qpyluyzix3j1odxrxx4u52gxvyu6qiteapczkzvi7rxgeqsozz7b19rdx73a7quo9ybwpz1cr82r7x5k0pg2a73pjjsv2j1awr13azo7klrcxp9y5xxwf5qv1s3tw4zqftli18u0ek5qkbzfbgk1v5n2f11pkwwk6p0mibrn26wnjbv11vyiqgu95o7busmt6vf5q7grpcenl637w83mbin56s3asj1131b2mscj9xep3cbj7la9tgsxl5bj87vzy8sk2d34kzwqdqgh9nry43nqqus12l1stmiv184r8r3jcy8w43e8h1u1mzklldb5eytkuhayqik8l3ns04hwt8sgacvw534be8sx26qrn5s1", 36);
private final transient File file;

View File

@ -1,10 +1,14 @@
package com.earth2me.essentials.update;
import com.earth2me.essentials.update.states.InstallationFinishedEvent;
import com.earth2me.essentials.update.states.StateMachine;
import java.util.List;
import com.earth2me.essentials.update.tasks.SelfUpdate;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.CustomEventListener;
import org.bukkit.event.Event;
import org.bukkit.event.Event.Priority;
import org.bukkit.event.Event.Type;
import org.bukkit.event.player.PlayerChatEvent;
@ -23,6 +27,7 @@ public class UpdateProcess extends PlayerListener
public UpdateProcess(final Plugin plugin, final UpdateCheck updateCheck)
{
super();
this.plugin = plugin;
this.updateCheck = updateCheck;
}
@ -32,6 +37,77 @@ public class UpdateProcess extends PlayerListener
final PluginManager pluginManager = plugin.getServer().getPluginManager();
pluginManager.registerEvent(Type.PLAYER_QUIT, this, Priority.Low, plugin);
pluginManager.registerEvent(Type.PLAYER_CHAT, this, Priority.Lowest, plugin);
pluginManager.registerEvent(Type.PLAYER_JOIN, this, Priority.Normal, plugin);
pluginManager.registerEvent(Type.CUSTOM_EVENT, new CustomEventListener()
{
@Override
public void onCustomEvent(final Event event)
{
if (event instanceof InstallationFinishedEvent)
{
UpdateProcess.this.currentPlayer = null;
}
}
}, Priority.Normal, plugin);
}
public boolean selfUpdate()
{
if (new Version(plugin.getDescription().getVersion()).compareTo(updateCheck.getNewVersion()) < 0)
{
if (currentPlayer != null)
{
currentPlayer.sendMessage("A newer version of EssentialsUpdate is found. Downloading new file and reloading server.");
}
Bukkit.getLogger().log(Level.INFO, "A newer version of EssentialsUpdate is found. Downloading new file and reloading server.");
new SelfUpdate(new AbstractWorkListener(plugin, updateCheck.getNewVersionInfo())
{
@Override
public void onWorkAbort(final String message)
{
if (message != null && !message.isEmpty()
&& UpdateProcess.this.currentPlayer != null
&& UpdateProcess.this.currentPlayer.isOnline())
{
UpdateProcess.this.currentPlayer.sendMessage(message);
}
if (message != null && !message.isEmpty())
{
Bukkit.getLogger().log(Level.SEVERE, message);
}
UpdateProcess.this.currentPlayer = null;
}
@Override
public void onWorkDone(final String message)
{
if (message != null && !message.isEmpty()
&& UpdateProcess.this.currentPlayer != null
&& UpdateProcess.this.currentPlayer.isOnline())
{
UpdateProcess.this.currentPlayer.sendMessage(message);
}
if (message != null && !message.isEmpty())
{
Bukkit.getLogger().log(Level.INFO, message);
}
UpdateProcess.this.currentPlayer = null;
}
}).start();
return true;
}
if (updateCheck.getResult() == UpdateCheck.CheckResult.NEW_ESS_BUKKIT)
{
final String message = "Please update bukkit to version " + updateCheck.getNewBukkitVersion() + " before updating Essentials.";
if (currentPlayer != null)
{
currentPlayer.sendMessage(message);
}
Bukkit.getLogger().log(Level.INFO, message);
currentPlayer = null;
return true;
}
return false;
}
@Override
@ -58,6 +134,14 @@ public class UpdateProcess extends PlayerListener
public void onPlayerJoin(final PlayerJoinEvent event)
{
final Player player = event.getPlayer();
if (currentPlayer.getName().equals(player.getName()))
{
currentPlayer = player;
player.sendMessage("You quit the game, while the installation wizard was running.");
player.sendMessage("The installation wizard will now resume.");
player.sendMessage("You can exit the wizard by typing quit into the chat.");
stateMachine.resumeInstallation(player);
}
if (player.hasPermission("essentials.update") && !updateCheck.isEssentialsInstalled())
{
player.sendMessage("Hello " + player.getDisplayName());
@ -82,48 +166,22 @@ public class UpdateProcess extends PlayerListener
}
}
public void doAutomaticUpdate()
{
final VersionInfo info = updateCheck.getNewVersionInfo();
final List<String> changelog = info.getChangelog();
Bukkit.getLogger().info("Essentials changelog " + updateCheck.getNewVersion().toString());
for (String line : changelog)
{
Bukkit.getLogger().info(" - " + line);
}
final UpdatesDownloader downloader = new UpdatesDownloader(plugin, info);
downloader.start();
}
public void doManualUpdate()
{
}
public void onCommand(final CommandSender sender)
{
if (sender instanceof Player && sender.hasPermission("essentials.install"))
if (sender instanceof Player && sender.hasPermission("essentials.update"))
{
if (currentPlayer == null)
{
currentPlayer = (Player)sender;
if (updateCheck.isEssentialsInstalled())
if (selfUpdate())
{
doManualUpdate();
return;
}
else
stateMachine = new StateMachine(plugin, currentPlayer, updateCheck);
final StateMachine.MachineResult result = stateMachine.askQuestion();
if (result == StateMachine.MachineResult.DONE)
{
sender.sendMessage("Thank you for choosing Essentials.");
sender.sendMessage("The following installation wizard will guide you through the installation of Essentials.");
sender.sendMessage("Your answers will be saved for a later update.");
sender.sendMessage("Please answer the messages with yes or no, if not otherwise stated.");
sender.sendMessage("Write bye/exit/quit if you want to exit the wizard at anytime.");
stateMachine = new StateMachine(plugin, currentPlayer, updateCheck.getNewVersionInfo());
final StateMachine.MachineResult result = stateMachine.askQuestion();
if (result == StateMachine.MachineResult.DONE)
{
startWork();
}
startWork();
}
}
if (!currentPlayer.equals(sender))

View File

@ -1,28 +0,0 @@
package com.earth2me.essentials.update;
import org.bukkit.plugin.Plugin;
public class UpdatesDownloader extends WorkListener
{
public UpdatesDownloader(final Plugin plugin, final VersionInfo newVersionInfo)
{
super(plugin, newVersionInfo);
}
public void start()
{
}
@Override
public void onWorkAbort(String message)
{
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void onWorkDone(String message)
{
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@ -147,7 +147,7 @@ public class Version implements Comparable<Version>
hash = 71 * hash + this.major;
hash = 71 * hash + this.minor;
hash = 71 * hash + this.build;
hash = 71 * hash + (this.type != null ? this.type.hashCode() : 0);
hash = 71 * hash + (this.type == null ? 0 : this.type.hashCode());
return hash;
}

View File

@ -0,0 +1,77 @@
package com.earth2me.essentials.update.chat;
import com.earth2me.essentials.update.PastieUpload;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import org.bukkit.plugin.Plugin;
public abstract class AbstractFileCommand implements Command
{
private final transient Plugin plugin;
private final static Charset UTF8 = Charset.forName("utf-8");
public AbstractFileCommand(final Plugin plugin)
{
this.plugin = plugin;
}
protected BufferedReader getServerLogReader() throws IOException
{
final File bukkitFolder = plugin.getDataFolder().getAbsoluteFile().getParentFile().getParentFile();
if (bukkitFolder == null || !bukkitFolder.exists())
{
throw new IOException("Bukkit folder not found.");
}
final File logFile = new File(bukkitFolder, "server.log");
if (!logFile.exists())
{
throw new IOException("Server log not found.");
}
final FileInputStream fis = new FileInputStream(logFile);
try
{
if (logFile.length() > 1000000)
{
fis.skip(logFile.length() - 1000000);
}
return new BufferedReader(new InputStreamReader(fis));
}
catch (IOException ex)
{
fis.close();
throw ex;
}
}
protected BufferedReader getPluginConfig(final String pluginName, final String fileName) throws IOException
{
final File configFolder = new File(plugin.getDataFolder().getAbsoluteFile().getParentFile(), pluginName);
if (!configFolder.exists())
{
throw new IOException(pluginName + " plugin folder not found.");
}
final File configFile = new File(configFolder, fileName);
if (!configFile.exists())
{
throw new IOException(pluginName + " plugin file " + fileName + " not found.");
}
return new BufferedReader(new InputStreamReader(new FileInputStream(configFile), UTF8));
}
protected String uploadToPastie(final StringBuilder input) throws IOException
{
if (input.length() > 15000)
{
input.delete(0, input.length() - 15000);
input.append("## Cropped after 15000 bytes");
}
final PastieUpload pastie = new PastieUpload();
return pastie.send(input.toString());
}
}

View File

@ -0,0 +1,9 @@
package com.earth2me.essentials.update.chat;
import org.bukkit.entity.Player;
public interface Command
{
void run(final IrcBot ircBot, final Player player);
}

View File

@ -0,0 +1,62 @@
package com.earth2me.essentials.update.chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class ConfigCommand extends AbstractFileCommand implements Command
{
public ConfigCommand(final Plugin plugin)
{
super(plugin);
}
@Override
public void run(final IrcBot ircBot, final Player player)
{
BufferedReader page = null;
try
{
page = getPluginConfig("Essentials", "config.yml");
final StringBuilder input = new StringBuilder();
do
{
final String line = page.readLine();
if (line == null) {
break;
} else {
input.append(line).append("\n");
}
} while (true);
page.close();
final String message = "Essentials config.yml: " + uploadToPastie(input);
player.sendMessage("§6" + ircBot.getNick() + ": §7" + message);
ircBot.sendMessage(message);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
player.sendMessage(ex.getMessage());
}
finally
{
try
{
if (page != null)
{
page.close();
}
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
player.sendMessage(ex.getMessage());
}
}
}
}

View File

@ -0,0 +1,71 @@
package com.earth2me.essentials.update.chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class ErrorsCommand extends AbstractFileCommand implements Command
{
private final transient Pattern pattern = Pattern.compile("^[0-9 :-]+\\[INFO\\].*");
public ErrorsCommand(final Plugin plugin)
{
super(plugin);
}
@Override
public void run(final IrcBot ircBot, final Player player)
{
BufferedReader page = null;
try
{
page = getServerLogReader();
final StringBuilder input = new StringBuilder();
do
{
final String line = page.readLine();
if (line == null)
{
break;
}
else
{
if (!pattern.matcher(line).matches())
{
input.append(line).append("\n");
}
}
}
while (true);
page.close();
final String message = "Errors: " + uploadToPastie(input);
player.sendMessage("§6" + ircBot.getNick() + ": §7" + message);
ircBot.sendMessage(message);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
player.sendMessage(ex.getMessage());
}
finally
{
try
{
if (page != null)
{
page.close();
}
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
player.sendMessage(ex.getMessage());
}
}
}
}

View File

@ -0,0 +1,18 @@
package com.earth2me.essentials.update.chat;
import org.bukkit.entity.Player;
public class HelpCommand implements Command
{
@Override
public void run(final IrcBot ircBot, final Player player)
{
player.sendMessage("Commands: (Note: Files send to the chat will be public viewable.)");
player.sendMessage("!errors - Send the last server errors to the chat.");
player.sendMessage("!startup - Send the last startup messages to the chat.");
player.sendMessage("!config - Sends your Essentials config to the chat.");
player.sendMessage("!list - List all players in chat.");
player.sendMessage("!quit - Leave chat.");
}
}

View File

@ -1,4 +1,4 @@
package com.earth2me.essentials.update;
package com.earth2me.essentials.update.chat;
import java.io.IOException;
import java.util.logging.Level;
@ -95,7 +95,9 @@ public class IrcBot extends PircBot
}
@Override
protected void onKick(String channel, String kickerNick, String kickerLogin, String kickerHostname, String recipientNick, String reason)
protected void onKick(final String channel, final String kickerNick,
final String kickerLogin, final String kickerHostname,
final String recipientNick, final String reason)
{
if (recipientNick.equals(getNick()))
{
@ -111,25 +113,33 @@ public class IrcBot extends PircBot
}
@Override
protected void onMessage(String channel, String sender, String login, String hostname, String message)
protected void onMessage(final String channel, final String sender,
final String login, final String hostname,
final String message)
{
player.sendMessage(formatChatMessage(sender, message, false));
}
@Override
protected void onAction(String sender, String login, String hostname, String target, String action)
protected void onAction(final String sender, final String login,
final String hostname, final String target,
final String action)
{
player.sendMessage(formatChatMessage(sender, action, true));
}
@Override
protected void onNotice(String sourceNick, String sourceLogin, String sourceHostname, String target, String notice)
protected void onNotice(final String sourceNick, final String sourceLogin,
final String sourceHostname, final String target,
final String notice)
{
player.sendMessage(formatChatMessage(sourceNick, notice, false));
}
@Override
protected void onTopic(String channel, String topic, String setBy, long date, boolean changed)
protected void onTopic(final String channel, final String topic,
final String setBy, final long date,
final boolean changed)
{
player.sendMessage(formatChatMessage(channel, topic, false));
}

View File

@ -0,0 +1,32 @@
package com.earth2me.essentials.update.chat;
import org.bukkit.entity.Player;
import org.jibble.pircbot.User;
public class ListCommand implements Command
{
@Override
public void run(final IrcBot ircBot, final Player player)
{
final User[] members = ircBot.getUsers();
final StringBuilder message = new StringBuilder();
for (User user : members)
{
if (message.length() > 0)
{
message.append("§f, ");
}
if (user.isOp() || user.hasVoice())
{
message.append("§6");
}
else
{
message.append("§7");
}
message.append(user.getPrefix()).append(user.getNick());
}
player.sendMessage(message.toString());
}
}

View File

@ -0,0 +1,77 @@
package com.earth2me.essentials.update.chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class StartupCommand extends AbstractFileCommand implements Command
{
private final transient Pattern patternStart = Pattern.compile("^[0-9 :-]+\\[INFO\\] Starting minecraft server version.*");
private final transient Pattern patternEnd = Pattern.compile("^[0-9 :-]+\\[INFO\\] Done \\([0-9.,]+s\\)! For help, type \"help\".*");
public StartupCommand(final Plugin plugin)
{
super(plugin);
}
@Override
public void run(final IrcBot ircBot, final Player player)
{
BufferedReader page = null;
try
{
page = getServerLogReader();
final StringBuilder input = new StringBuilder();
String line;
boolean log = false;
while ((line = page.readLine()) != null)
{
if (patternStart.matcher(line).matches())
{
if (input.length() > 0)
{
input.delete(0, input.length());
}
log = true;
}
if (log)
{
input.append(line).append("\n");
}
if (patternEnd.matcher(line).matches())
{
log = false;
}
}
page.close();
final String message = "Startup: " + uploadToPastie(input);
player.sendMessage("§6" + ircBot.getNick() + ": §7" + message);
ircBot.sendMessage(message);
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
player.sendMessage(ex.getMessage());
}
finally
{
try
{
if (page != null)
{
page.close();
}
}
catch (IOException ex)
{
Bukkit.getLogger().log(Level.SEVERE, null, ex);
player.sendMessage(ex.getMessage());
}
}
}
}

View File

@ -0,0 +1,124 @@
package com.earth2me.essentials.update.chat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public final class UsernameUtil
{
private static final Pattern CB_PATTERN = Pattern.compile("git-Bukkit-([0-9]+).([0-9]+).([0-9]+)-[0-9]+-[0-9a-z]+-b([0-9]+)jnks.*");
private UsernameUtil()
{
}
public static String createUsername(final Player player)
{
final StringBuilder nameBuilder = new StringBuilder();
final Server server = Bukkit.getServer();
nameBuilder.append(player.getName());
addCraftBukkitVersion(server, nameBuilder);
addEssentialsVersion(server, nameBuilder);
addGroupManagerVersion(server, nameBuilder);
addPermissionsExVersion(server, nameBuilder);
addPermissionsBukkitVersion(server, nameBuilder);
addBPermissionsVersion(server, nameBuilder);
addPermissionsVersion(server, nameBuilder);
return nameBuilder.toString();
}
private static void addPermissionsVersion(final Server server, final StringBuilder nameBuilder)
{
final Plugin perm = server.getPluginManager().getPlugin("Permissions");
if (perm != null)
{
nameBuilder.append(" P");
if (!perm.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(perm.getDescription().getVersion());
}
}
private static void addBPermissionsVersion(final Server server, final StringBuilder nameBuilder)
{
final Plugin bperm = server.getPluginManager().getPlugin("bPermissions");
if (bperm != null)
{
nameBuilder.append(" BP");
if (!bperm.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(bperm.getDescription().getVersion());
}
}
private static void addPermissionsBukkitVersion(final Server server, final StringBuilder nameBuilder)
{
final Plugin permb = server.getPluginManager().getPlugin("PermissionsBukkit");
if (permb != null)
{
nameBuilder.append(" PB");
if (!permb.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(permb.getDescription().getVersion());
}
}
private static void addPermissionsExVersion(final Server server, final StringBuilder nameBuilder)
{
final Plugin pex = server.getPluginManager().getPlugin("PermissionsEx");
if (pex != null)
{
nameBuilder.append(" PEX");
if (!pex.isEnabled())
{
nameBuilder.append('!');
}
nameBuilder.append(pex.getDescription().getVersion());
}
}
private static void addGroupManagerVersion(final Server server, final StringBuilder nameBuilder)
{
final Plugin groupManager = server.getPluginManager().getPlugin("GroupManager");
if (groupManager != null)
{
nameBuilder.append(" GM");
if (!groupManager.isEnabled())
{
nameBuilder.append('!');
}
}
}
private static void addEssentialsVersion(final Server server, final StringBuilder nameBuilder)
{
final Plugin essentials = server.getPluginManager().getPlugin("Essentials");
if (essentials != null)
{
nameBuilder.append(" ESS");
nameBuilder.append(essentials.getDescription().getVersion());
}
}
private static void addCraftBukkitVersion(final Server server, final StringBuilder nameBuilder)
{
final Matcher versionMatch = CB_PATTERN.matcher(server.getVersion());
if (versionMatch.matches())
{
nameBuilder.append(" CB");
nameBuilder.append(versionMatch.group(4));
}
}
}

View File

@ -1,6 +1,6 @@
package com.earth2me.essentials.update.states;
import com.earth2me.essentials.update.WorkListener;
import com.earth2me.essentials.update.AbstractWorkListener;
import org.bukkit.entity.Player;
@ -14,9 +14,26 @@ public abstract class AbstractState
this.stateMap = stateMap;
}
public AbstractState getState(final Class<? extends AbstractState> stateClass)
public <T extends AbstractState> T getState(final Class<? extends T> stateClass)
{
return stateMap.get(stateClass);
if (!stateMap.containsKey(stateClass))
{
try
{
final AbstractState state = stateClass.getConstructor(StateMap.class).newInstance(stateMap);
stateMap.put(stateClass, state);
}
catch (Exception ex)
{
/*
* This should never happen.
* All states that are added to the map automatically,
* have to have a Constructor that accepts the StateMap.
*/
throw new RuntimeException(ex);
}
}
return (T)stateMap.get(stateClass);
}
public abstract AbstractState getNextState();
@ -49,19 +66,29 @@ public abstract class AbstractState
final String trimmedAnswer = answer.trim();
if (trimmedAnswer.equalsIgnoreCase("quit")
|| trimmedAnswer.equalsIgnoreCase("bye")
|| trimmedAnswer.equalsIgnoreCase("abort"))
|| trimmedAnswer.equalsIgnoreCase("abort")
|| trimmedAnswer.equalsIgnoreCase("cancel")
|| trimmedAnswer.equalsIgnoreCase("exit"))
{
abort();
return null;
}
final boolean found = reactOnAnswer(trimmedAnswer);
if (found)
try
{
return getNextState();
final boolean found = reactOnAnswer(trimmedAnswer);
if (found)
{
return getNextState();
}
else
{
sender.sendMessage("Answer not recognized.");
return this;
}
}
else
catch (RuntimeException ex)
{
sender.sendMessage("Answer not recognized.");
sender.sendMessage(ex.toString());
return this;
}
}
@ -69,7 +96,10 @@ public abstract class AbstractState
/**
* Do something based on the answer, that the user gave.
*/
public abstract void doWork(WorkListener workListener);
public void doWork(final AbstractWorkListener listener)
{
listener.onWorkDone();
}
public boolean isAbortion()
{

View File

@ -0,0 +1,20 @@
package com.earth2me.essentials.update.states;
import org.bukkit.entity.Player;
public class AdvancedMode extends AbstractYesNoState
{
public AdvancedMode(final StateMap states)
{
super(states, EssentialsChat.class);
}
@Override
public void askQuestion(final Player sender)
{
sender.sendMessage("This installation mode has a lot of options.");
sender.sendMessage("Do you want use the advanced mode to see all questions?");
sender.sendMessage("Otherwise the default values will be used.");
}
}

View File

@ -0,0 +1,91 @@
package com.earth2me.essentials.update.states;
import com.earth2me.essentials.update.UpdateCheck;
import com.earth2me.essentials.update.VersionInfo;
import java.util.List;
import org.bukkit.entity.Player;
public class Changelog extends AbstractState
{
private static final int CHANGES_PER_PAGE = 5;
private transient int page = 0;
private transient boolean confirmed = false;
private transient final List<String> changes;
private transient final int pages;
public Changelog(final StateMap stateMap)
{
super(stateMap);
changes = getChanges();
pages = changes.size() / CHANGES_PER_PAGE + (changes.size() % CHANGES_PER_PAGE > 0 ? 1 : 0);
}
@Override
public AbstractState getNextState()
{
return confirmed ? getState(EssentialsChat.class) : this;
}
@Override
public boolean guessAnswer()
{
if (pages == 0)
{
confirmed = true;
}
return confirmed;
}
private List<String> getChanges()
{
final UpdateCheck updateCheck = getState(UpdateOrInstallation.class).getUpdateCheck();
final VersionInfo versionInfo = updateCheck.getNewVersionInfo();
return versionInfo.getChangelog();
}
@Override
public void askQuestion(final Player sender)
{
if (pages > 1)
{
sender.sendMessage("Changelog, page " + page + " of " + pages + ":");
}
else
{
sender.sendMessage("Changelog:");
}
for (int i = page * CHANGES_PER_PAGE; i < Math.min(page * CHANGES_PER_PAGE + CHANGES_PER_PAGE, changes.size()); i++)
{
sender.sendMessage(changes.get(i));
}
if (pages > 1)
{
sender.sendMessage("Select a page by typing the numbers 1 to " + pages + " to view all changes and then type confirm or abort.");
}
else
{
sender.sendMessage("Type confirm to update Essentials or abort to cancel the update.");
}
}
@Override
public boolean reactOnAnswer(final String answer)
{
if (answer.equalsIgnoreCase("confirm"))
{
confirmed = true;
return true;
}
if (answer.matches("[0-9]+"))
{
final int page = Integer.parseInt(answer);
if (page <= pages && page > 0)
{
this.page = page - 1;
return true;
}
}
return false;
}
}

View File

@ -1,6 +1,6 @@
package com.earth2me.essentials.update.states;
import com.earth2me.essentials.update.WorkListener;
import com.earth2me.essentials.update.AbstractWorkListener;
import com.earth2me.essentials.update.tasks.InstallModule;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -35,7 +35,7 @@ public class EssentialsChat extends AbstractYesNoState
}
@Override
public void doWork(final WorkListener listener)
public void doWork(final AbstractWorkListener listener)
{
if (getAnswer())
{

View File

@ -1,10 +1,6 @@
package com.earth2me.essentials.update.states;
import com.earth2me.essentials.update.WorkListener;
import com.earth2me.essentials.update.tasks.InstallModule;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class EssentialsChatSettings extends AbstractYesNoState
@ -14,21 +10,20 @@ public class EssentialsChatSettings extends AbstractYesNoState
super(states, EssentialsSpawn.class);
}
@Override
public boolean guessAnswer()
{
if (getState(AdvancedMode.class).getAnswer())
{
setAnswer(false);
return true;
}
return false;
}
@Override
public void askQuestion(final Player sender)
{
sender.sendMessage("Would you like to configure EssentialsChat to prefix ingame messages with their group?");
}
@Override
public void doWork(final WorkListener listener)
{
if (getAnswer())
{
//TODO: Configure plugin
return;
}
listener.onWorkDone();
}
}

View File

@ -1,6 +1,6 @@
package com.earth2me.essentials.update.states;
import com.earth2me.essentials.update.WorkListener;
import com.earth2me.essentials.update.AbstractWorkListener;
import com.earth2me.essentials.update.tasks.InstallModule;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -35,7 +35,7 @@ public class EssentialsGeoIP extends AbstractYesNoState
}
@Override
public void doWork(final WorkListener listener)
public void doWork(final AbstractWorkListener listener)
{
if (getAnswer())
{

View File

@ -1,6 +1,6 @@
package com.earth2me.essentials.update.states;
import com.earth2me.essentials.update.WorkListener;
import com.earth2me.essentials.update.AbstractWorkListener;
import com.earth2me.essentials.update.tasks.InstallModule;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -35,7 +35,7 @@ public class EssentialsProtect extends AbstractYesNoState
}
@Override
public void doWork(final WorkListener listener)
public void doWork(final AbstractWorkListener listener)
{
if (getAnswer())
{

View File

@ -1,6 +1,6 @@
package com.earth2me.essentials.update.states;
import com.earth2me.essentials.update.WorkListener;
import com.earth2me.essentials.update.AbstractWorkListener;
import com.earth2me.essentials.update.tasks.InstallModule;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -35,7 +35,7 @@ public class EssentialsSpawn extends AbstractYesNoState
}
@Override
public void doWork(final WorkListener listener)
public void doWork(final AbstractWorkListener listener)
{
if (getAnswer())
{

View File

@ -0,0 +1,12 @@
package com.earth2me.essentials.update.states;
import org.bukkit.event.Event;
public class InstallationFinishedEvent extends Event
{
public InstallationFinishedEvent()
{
super(Type.CUSTOM_EVENT);
}
}

View File

@ -1,82 +1,113 @@
package com.earth2me.essentials.update.states;
import com.earth2me.essentials.update.WorkListener;
import com.earth2me.essentials.update.VersionInfo;
import com.earth2me.essentials.update.UpdateCheck;
import com.earth2me.essentials.update.AbstractWorkListener;
import java.util.Iterator;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class StateMachine extends WorkListener
public class StateMachine extends AbstractWorkListener implements Runnable
{
public enum MachineResult
{
ABORT, WAIT, DONE
ABORT, WAIT, DONE, NONE
}
private final transient StateMap states = new StateMap();
private transient AbstractState current;
private final transient Player player;
private transient Player player;
private transient MachineResult result = MachineResult.NONE;
public StateMachine(final Plugin plugin, final Player player, final VersionInfo newVersionInfo)
public StateMachine(final Plugin plugin, final Player player, final UpdateCheck updateCheck)
{
super(plugin, newVersionInfo);
super(plugin, updateCheck.getNewVersionInfo());
this.player = player;
states.clear();
states.add(new EssentialsChat(states));
states.add(new EssentialsSpawn(states));
states.add(new EssentialsProtect(states));
states.add(new EssentialsGeoIP(states));
current = states.values().iterator().next();
final UpdateOrInstallation state = new UpdateOrInstallation(states, updateCheck);
current = states.put(UpdateOrInstallation.class, state);
}
public MachineResult askQuestion()
{
while (current.guessAnswer())
try
{
current = current.getNextState();
if (current == null)
while (current.guessAnswer())
{
return MachineResult.DONE;
current = current.getNextState();
if (current == null)
{
result = MachineResult.DONE;
break;
}
}
if (current != null)
{
if (player.isOnline())
{
current.askQuestion(player);
}
result = MachineResult.WAIT;
}
}
current.askQuestion(player);
return MachineResult.WAIT;
catch (RuntimeException ex)
{
player.sendMessage(ex.getMessage());
finish();
result = MachineResult.ABORT;
}
return result;
}
public MachineResult reactOnMessage(final String message)
{
result = MachineResult.NONE;
final AbstractState next = current.reactOnAnswer(player, message);
if (next == null)
{
if (current.isAbortion())
{
return MachineResult.ABORT;
finish();
result = MachineResult.ABORT;
}
else
{
return MachineResult.DONE;
result = MachineResult.DONE;
}
}
current = next;
return askQuestion();
else
{
current = next;
askQuestion();
}
return result;
}
private transient Iterator<AbstractState> iterator;
public void startWork()
{
iterator = states.values().iterator();
callStateWork();
Bukkit.getScheduler().scheduleAsyncDelayedTask(getPlugin(), this);
}
private void callStateWork()
@Override
public void run()
{
if (!iterator.hasNext())
{
if (player.isOnline())
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable()
{
player.sendMessage("Installation done.");
}
@Override
public void run()
{
if (StateMachine.this.player.isOnline())
{
StateMachine.this.player.sendMessage("Installation done. Reloading server.");
}
finish();
Bukkit.getServer().reload();
}
});
return;
}
final AbstractState state = iterator.next();
@ -86,6 +117,7 @@ public class StateMachine extends WorkListener
@Override
public void onWorkAbort(final String message)
{
finish();
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable()
{
@Override
@ -111,8 +143,41 @@ public class StateMachine extends WorkListener
{
StateMachine.this.player.sendMessage(message);
}
StateMachine.this.callStateWork();
Bukkit.getScheduler().scheduleAsyncDelayedTask(getPlugin(), StateMachine.this);
}
});
}
private void finish()
{
current = null;
iterator = null;
states.clear();
getPlugin().getServer().getPluginManager().callEvent(new InstallationFinishedEvent());
}
public void resumeInstallation(final Player player)
{
this.player = player;
if (result == MachineResult.WAIT)
{
if (current == null)
{
throw new RuntimeException("State is WAIT, but current state is null!");
}
current.askQuestion(player);
}
if (result == MachineResult.DONE && iterator != null)
{
player.sendMessage("Installation is still running.");
}
if (result == MachineResult.ABORT)
{
throw new RuntimeException("Player should not be able to resume an aborted installation.");
}
if (result == MachineResult.NONE)
{
throw new RuntimeException("State machine in an undefined state.");
}
}
}

View File

@ -7,11 +7,6 @@ public class StateMap extends LinkedHashMap<Class<? extends AbstractState>, Abst
{
public StateMap()
{
super();
}
public AbstractState add(AbstractState state)
{
return put(state.getClass(), state);
super(50);
}
}

View File

@ -0,0 +1,59 @@
package com.earth2me.essentials.update.states;
import com.earth2me.essentials.update.UpdateCheck;
import org.bukkit.entity.Player;
public class UpdateOrInstallation extends AbstractState
{
private final transient UpdateCheck updateCheck;
private transient boolean update = false;
public UpdateOrInstallation(final StateMap stateMap, final UpdateCheck updateCheck)
{
super(stateMap);
this.updateCheck = updateCheck;
}
@Override
public boolean guessAnswer()
{
if (getUpdateCheck().isEssentialsInstalled()) {
update = true;
}
return update;
}
@Override
public AbstractState getNextState()
{
return update ? getState(Changelog.class) : getState(EssentialsChat.class);
}
@Override
public void askQuestion(final Player sender)
{
sender.sendMessage("Thank you for choosing Essentials.");
sender.sendMessage("The following installation wizard will guide you through the installation of Essentials.");
sender.sendMessage("Your answers will be saved for a later update.");
sender.sendMessage("Please answer the messages with yes or no, if not otherwise stated.");
sender.sendMessage("Write bye/exit/quit if you want to exit the wizard at anytime.");
sender.sendMessage("Type ok to continue...");
}
@Override
public boolean reactOnAnswer(final String answer)
{
return answer.equalsIgnoreCase("ok") || answer.equalsIgnoreCase("k") || answer.equalsIgnoreCase("continue");
}
public UpdateCheck getUpdateCheck()
{
return updateCheck;
}
public boolean isUpdate()
{
return update;
}
}

View File

@ -3,7 +3,7 @@ package com.earth2me.essentials.update.tasks;
import com.earth2me.essentials.update.GetFile;
import com.earth2me.essentials.update.ModuleInfo;
import com.earth2me.essentials.update.VersionInfo;
import com.earth2me.essentials.update.WorkListener;
import com.earth2me.essentials.update.AbstractWorkListener;
import java.io.File;
import java.net.URL;
import java.util.logging.Level;
@ -12,16 +12,16 @@ import org.bukkit.Bukkit;
public class InstallModule implements Runnable, Task
{
protected final transient WorkListener listener;
protected final transient AbstractWorkListener listener;
private final transient String moduleName;
private final transient String fileName;
public InstallModule(final WorkListener listener, final String moduleName)
public InstallModule(final AbstractWorkListener listener, final String moduleName)
{
this(listener, moduleName, moduleName + ".jar");
}
public InstallModule(final WorkListener listener, final String moduleName, final String fileName)
public InstallModule(final AbstractWorkListener listener, final String moduleName, final String fileName)
{
this.listener = listener;
this.moduleName = moduleName;

View File

@ -0,0 +1,57 @@
package com.earth2me.essentials.update.tasks;
import com.earth2me.essentials.update.AbstractWorkListener;
import org.bukkit.Bukkit;
public class SelfUpdate extends AbstractWorkListener implements Task, Runnable
{
private final transient AbstractWorkListener listener;
public SelfUpdate(final AbstractWorkListener listener)
{
super(listener.getPlugin(), listener.getNewVersionInfo());
this.listener = listener;
}
@Override
public void onWorkAbort(final String message)
{
listener.onWorkAbort(message);
}
@Override
public void onWorkDone(final String message)
{
listener.onWorkDone(message);
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable()
{
@Override
public void run()
{
Bukkit.getServer().reload();
}
});
}
@Override
public void start()
{
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), this);
}
@Override
public void run()
{
Bukkit.getScheduler().scheduleAsyncDelayedTask(getPlugin(), new Runnable() {
@Override
public void run()
{
new InstallModule(SelfUpdate.this, "EssentialsUpdate").start();
}
});
}
}

View File

@ -49,39 +49,39 @@ public class VersionTest extends TestCase
@Test
public void testCompareTo()
{
Version a = new Version("1.1.1");
Version b = new Version("Dev1.1.2");
Version c = new Version("1.1.2");
Version d = new Version("1.2.0");
Version e = new Version("2.0.0");
Version f = new Version("Pre1.1.1.1");
Version g = new Version("Dev1.2.2");
assertTrue("Testing dev", a.compareTo(b) < 0);
assertTrue("Testing dev", b.compareTo(a) > 0);
assertTrue("Testing build", a.compareTo(c) < 0);
assertTrue("Testing build", c.compareTo(a) > 0);
assertTrue("Testing minor", a.compareTo(d) < 0);
assertTrue("Testing minor", d.compareTo(a) > 0);
assertTrue("Testing major", a.compareTo(e) < 0);
assertTrue("Testing major", e.compareTo(a) > 0);
assertTrue("Testing pre", f.compareTo(a) < 0);
assertTrue("Testing pre", a.compareTo(f) > 0);
assertTrue("Testing dev vs dev", b.compareTo(g) < 0);
assertTrue("Testing dev vs dev", g.compareTo(b) > 0);
final Version verA = new Version("1.1.1");
final Version verB = new Version("Dev1.1.2");
final Version verC = new Version("1.1.2");
final Version verD = new Version("1.2.0");
final Version verE = new Version("2.0.0");
final Version verF = new Version("Pre1.1.1.1");
final Version verG = new Version("Dev1.2.2");
assertTrue("Testing dev", verA.compareTo(verB) < 0);
assertTrue("Testing dev", verB.compareTo(verA) > 0);
assertTrue("Testing build", verA.compareTo(verC) < 0);
assertTrue("Testing build", verC.compareTo(verA) > 0);
assertTrue("Testing minor", verA.compareTo(verD) < 0);
assertTrue("Testing minor", verD.compareTo(verA) > 0);
assertTrue("Testing major", verA.compareTo(verE) < 0);
assertTrue("Testing major", verE.compareTo(verA) > 0);
assertTrue("Testing pre", verF.compareTo(verA) < 0);
assertTrue("Testing pre", verA.compareTo(verF) > 0);
assertTrue("Testing dev vs dev", verB.compareTo(verG) < 0);
assertTrue("Testing dev vs dev", verG.compareTo(verB) > 0);
final TreeSet<Version> set = new TreeSet<Version>();
set.add(a);
set.add(b);
set.add(c);
set.add(d);
set.add(e);
set.add(f);
set.add(g);
assertEquals("Testing sorting", f, set.pollFirst());
assertEquals("Testing sorting", a, set.pollFirst());
assertEquals("Testing sorting", c, set.pollFirst());
assertEquals("Testing sorting", d, set.pollFirst());
assertEquals("Testing sorting", e, set.pollFirst());
assertEquals("Testing sorting", b, set.pollFirst());
assertEquals("Testing sorting", g, set.pollFirst());
set.add(verA);
set.add(verB);
set.add(verC);
set.add(verD);
set.add(verE);
set.add(verF);
set.add(verG);
assertEquals("Testing sorting", verF, set.pollFirst());
assertEquals("Testing sorting", verA, set.pollFirst());
assertEquals("Testing sorting", verC, set.pollFirst());
assertEquals("Testing sorting", verD, set.pollFirst());
assertEquals("Testing sorting", verE, set.pollFirst());
assertEquals("Testing sorting", verB, set.pollFirst());
assertEquals("Testing sorting", verG, set.pollFirst());
}
}