diff options
Diffstat (limited to 'EssentialsUpdate/src/com/earth2me/essentials/update/states')
10 files changed, 282 insertions, 50 deletions
diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractState.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractState.java index 3f0c4c233..7478d81b7 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractState.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractState.java @@ -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; @@ -66,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; } } @@ -86,7 +96,7 @@ public abstract class AbstractState /** * Do something based on the answer, that the user gave. */ - public void doWork(final WorkListener listener) + public void doWork(final AbstractWorkListener listener) { listener.onWorkDone(); } diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/Changelog.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/Changelog.java new file mode 100644 index 000000000..10a4f33c5 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/Changelog.java @@ -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; + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsChat.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsChat.java index ef560bdc3..6aaed634a 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsChat.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsChat.java @@ -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()) { diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsGeoIP.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsGeoIP.java index b96f17c02..a91a44787 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsGeoIP.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsGeoIP.java @@ -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()) { diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsProtect.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsProtect.java index 7ffb61268..ca0337d30 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsProtect.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsProtect.java @@ -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()) { diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsSpawn.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsSpawn.java index 95cc6599b..2a87638ba 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsSpawn.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsSpawn.java @@ -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()) { diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/InstallationFinishedEvent.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/InstallationFinishedEvent.java new file mode 100644 index 000000000..cb88cc642 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/InstallationFinishedEvent.java @@ -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); + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMachine.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMachine.java index 77fb9ce20..6db8734e7 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMachine.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMachine.java @@ -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; + } + } + catch (RuntimeException ex) + { + player.sendMessage(ex.getMessage()); + finish(); + result = MachineResult.ABORT; } - current.askQuestion(player); - return MachineResult.WAIT; + 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."); + } + } } diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMap.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMap.java index a2cf7b719..cca4223d6 100644 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMap.java +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMap.java @@ -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); } } diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/UpdateOrInstallation.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/UpdateOrInstallation.java new file mode 100644 index 000000000..5671275f0 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/UpdateOrInstallation.java @@ -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; + } +} |