You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ConditionalExecuteCommand.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * Copyright (c) 2006-2013 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.addons.conditional_execute;
  23. import com.dmdirc.FrameContainer;
  24. import com.dmdirc.WritableFrameContainer;
  25. import com.dmdirc.commandparser.BaseCommandInfo;
  26. import com.dmdirc.commandparser.CommandArguments;
  27. import com.dmdirc.commandparser.CommandType;
  28. import com.dmdirc.commandparser.commands.Command;
  29. import com.dmdirc.commandparser.commands.context.CommandContext;
  30. import java.util.HashMap;
  31. import java.util.Map;
  32. /**
  33. * The ConditionalExecute command allows the user to conditionally execute a
  34. * command based on external and pre-determined conditions.
  35. */
  36. public class ConditionalExecuteCommand extends Command {
  37. /** Store details about current namespaces. */
  38. private final Map<String, ConditionalExecuteNamespace> namespaces = new HashMap<String, ConditionalExecuteNamespace>();
  39. /** A command info object for this command. */
  40. public static final BaseCommandInfo INFO = new BaseCommandInfo("conditionalexecute", "conditionalexecute <args> - Conditionally execute a command", CommandType.TYPE_GLOBAL);
  41. /** {@inheritDoc} */
  42. @Override
  43. public void execute(final FrameContainer origin, final CommandArguments args, final CommandContext context) {
  44. final String cmdname = args.getWordsAsString(0, 0);
  45. ConditionalExecuteNamespace namespace = null;
  46. final String[] arguments = args.getArguments();
  47. boolean manipulated = false;
  48. boolean inverse = false;
  49. for (int i = 0; i < arguments.length; i++) {
  50. final String arg = arguments[i].toLowerCase();
  51. final String nextArg = i + 1 < arguments.length ? arguments[i + 1] : "";
  52. if (arg.equalsIgnoreCase("--help")) {
  53. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Usage:");
  54. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
  55. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, cmdname + " <args>");
  56. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, cmdname + " --namespace <name> <namespace commands>");
  57. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, cmdname + " --namespace <name> [--inverse] </commandToRun <command args>>");
  58. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
  59. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Commands can only be specified if no other non-namespace args are given.");
  60. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
  61. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "When trying to run a command, the namespace will be checked to see if the command can be run.");
  62. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "The checks performed are as follows:");
  63. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " 1) Does the namespace exist? if not, run the command and create the namespace.");
  64. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " 2) Is the namespace inhibited? - Do not run the command.");
  65. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " 3) Is the namespace in forced mode? - Run the command.");
  66. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " 4) If --inverse is specified, are we under the limit time? Run the command");
  67. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " 5) If --inverse is not specified, are we over the limit time? Run the command");
  68. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " 6) Do not run the command.");
  69. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
  70. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "General Arguments.");
  71. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --list - List all current namespaces and their status");
  72. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --help - Print this help.");
  73. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --reset - Remove all namespaces.");
  74. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
  75. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Useful things:");
  76. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --namespace <name> - Namespace to modify. If the namespace does not exist, it will be created. Namespaces are not remembered across sessions.");
  77. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
  78. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Arguments related to a namespace:");
  79. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --settime <time> - Set the limit time on this namespace. Time can be either a time in seconds, 'now' for now, or 'nowifless' to set to now only if it is currently less.");
  80. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --delay <seconds> - Increase the 'limit' time on this namespace by <seconds> seconds");
  81. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --inhibit - Prevent any attempts at running commands in this namespace from executing");
  82. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --force - Any future attempts at running commands in this namespace will always execute");
  83. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --allow - Disable '--force' or '--inhibit' and resume normal operation.");
  84. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --remove - Remove this namespace.");
  85. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --status - Show the status of this namespace.");
  86. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "");
  87. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Arguments when running a command:");
  88. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " --inverse - Inverse the match against the 'limit' time.");
  89. return;
  90. } else if (arg.equalsIgnoreCase("--list")) {
  91. if (namespaces.isEmpty()) {
  92. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "There are currently no known namespaces.");
  93. } else {
  94. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Current namespaces: ");
  95. for (final Map.Entry<String, ConditionalExecuteNamespace> e : namespaces.entrySet()) {
  96. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, " " + e.getValue().toString());
  97. }
  98. }
  99. return;
  100. } else if (arg.equalsIgnoreCase("--reset")) {
  101. namespaces.clear();
  102. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "All namespaces removed.");
  103. return;
  104. } else if (namespace == null) {
  105. if (arg.equalsIgnoreCase("--namespace")) {
  106. if (nextArg.isEmpty()) {
  107. sendLine(origin, args.isSilent(), FORMAT_ERROR, "Error: You must specify a namespace.");
  108. return;
  109. } else {
  110. if (!namespaces.containsKey(nextArg.toLowerCase())) {
  111. namespaces.put(nextArg.toLowerCase(), new ConditionalExecuteNamespace(nextArg.toLowerCase()));
  112. }
  113. namespace = namespaces.get(nextArg.toLowerCase());
  114. // Skip the next argument.
  115. i++;
  116. }
  117. } else {
  118. sendLine(origin, args.isSilent(), FORMAT_ERROR, "Error: You must specify a namespace first.");
  119. return;
  120. }
  121. } else if (arg.equalsIgnoreCase("--inhibit")) {
  122. namespace.inhibit();
  123. manipulated = true;
  124. } else if (arg.equalsIgnoreCase("--force")) {
  125. namespace.force();
  126. manipulated = true;
  127. } else if (arg.equalsIgnoreCase("--allow")) {
  128. namespace.reset();
  129. manipulated = true;
  130. } else if (arg.equalsIgnoreCase("--settime")) {
  131. if (nextArg.isEmpty()) {
  132. sendLine(origin, args.isSilent(), FORMAT_ERROR, "Error: You must provide a time to use.");
  133. return;
  134. } else if (nextArg.equalsIgnoreCase("now")) {
  135. namespace.setLimit(System.currentTimeMillis());
  136. i++;
  137. manipulated = true;
  138. } else if (nextArg.equalsIgnoreCase("nowifless")) {
  139. if (namespace.getLimitTime() < System.currentTimeMillis()) {
  140. namespace.setLimit(System.currentTimeMillis());
  141. }
  142. i++;
  143. manipulated = true;
  144. } else {
  145. try {
  146. namespace.setLimit(Long.parseLong(nextArg) * 1000);
  147. i++;
  148. manipulated = true;
  149. } catch (final NumberFormatException nfe) {
  150. sendLine(origin, args.isSilent(), FORMAT_ERROR, "Error: Invalid time: " + nextArg);
  151. return;
  152. }
  153. }
  154. } else if (arg.equalsIgnoreCase("--delay")) {
  155. if (nextArg.isEmpty()) {
  156. sendLine(origin, args.isSilent(), FORMAT_ERROR, "Error: You must provide a delay to use.");
  157. return;
  158. } else {
  159. try {
  160. namespace.changeLimit(Long.parseLong(nextArg) * 1000);
  161. i++;
  162. manipulated = true;
  163. } catch (final NumberFormatException nfe) {
  164. sendLine(origin, args.isSilent(), FORMAT_ERROR, "Error: Invalid delay: " + nextArg);
  165. return;
  166. }
  167. }
  168. } else if (arg.equalsIgnoreCase("--remove")) {
  169. namespaces.remove(namespace.getName());
  170. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Removed namespace '" + namespace.getName() + "'");
  171. return;
  172. } else if (arg.equalsIgnoreCase("--status")) {
  173. // Show the current status, incase some manipulations occured prior to this.
  174. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, namespaces.get(namespace.getName()));
  175. return;
  176. } else if (arg.equalsIgnoreCase("--inverse")) {
  177. inverse = true;
  178. } else if (manipulated) {
  179. sendLine(origin, args.isSilent(), FORMAT_ERROR, "You can't run commands and manipulate the namespace at the same time, ignored.");
  180. } else {
  181. // Command to run!
  182. if (namespace.canRun(inverse) && origin instanceof WritableFrameContainer) {
  183. ((WritableFrameContainer) origin).getCommandParser().parseCommand(origin, args.getArgumentsAsString(i++));
  184. }
  185. return;
  186. }
  187. }
  188. // If we get here, we either manipulated something, or should show the usage text.
  189. if (manipulated) {
  190. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, "Namespace updated.");
  191. sendLine(origin, args.isSilent(), FORMAT_OUTPUT, namespace.toString());
  192. namespaces.put(namespace.getName(), namespace);
  193. } else {
  194. sendLine(origin, args.isSilent(), FORMAT_ERROR, "Usage:");
  195. sendLine(origin, args.isSilent(), FORMAT_ERROR, "");
  196. sendLine(origin, args.isSilent(), FORMAT_ERROR, cmdname + " <args>");
  197. sendLine(origin, args.isSilent(), FORMAT_ERROR, cmdname + " --namespace <name> <namespace commands>");
  198. sendLine(origin, args.isSilent(), FORMAT_ERROR, cmdname + " --namespace <name> [--inverse] </commandToRun <command args>>");
  199. sendLine(origin, args.isSilent(), FORMAT_ERROR, "");
  200. sendLine(origin, args.isSilent(), FORMAT_ERROR, "For more information, see " + cmdname + " --help");
  201. }
  202. }
  203. }