ModCommandManager.java 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. package me.km.permissions;
  2. import com.google.common.collect.Maps;
  3. import com.mojang.brigadier.builder.ArgumentBuilder;
  4. import com.mojang.brigadier.builder.RequiredArgumentBuilder;
  5. import com.mojang.brigadier.tree.CommandNode;
  6. import com.mojang.brigadier.tree.RootCommandNode;
  7. import java.util.ArrayList;
  8. import java.util.HashMap;
  9. import java.util.HashSet;
  10. import java.util.Map;
  11. import me.hammerle.snuviscript.code.ISnuviScheduler;
  12. import me.km.events.CommandEvent;
  13. import me.km.snuviscript.ScriptEvents;
  14. import me.km.snuviscript.Scripts;
  15. import net.minecraft.command.CommandSource;
  16. import net.minecraft.command.Commands;
  17. import net.minecraft.command.ICommandSource;
  18. import net.minecraft.command.ISuggestionProvider;
  19. import net.minecraft.command.arguments.SuggestionProviders;
  20. import net.minecraft.entity.Entity;
  21. import net.minecraft.entity.player.PlayerEntity;
  22. import net.minecraft.entity.player.ServerPlayerEntity;
  23. import net.minecraft.network.play.server.SCommandListPacket;
  24. public class ModCommandManager extends Commands
  25. {
  26. private final HashSet<String> otherCommands = new HashSet<>();
  27. private final HashMap<String, Command> commands = new HashMap<>();
  28. private final PermissionManager perms;
  29. private final ScriptEvents events;
  30. private final Scripts scripts;
  31. private final ArrayList<CommandNode> customNodes = new ArrayList<>();
  32. public ModCommandManager(boolean isDedicatedServer, PermissionManager perms, ScriptEvents events, Scripts scripts, ISnuviScheduler scheduler)
  33. {
  34. super(isDedicatedServer);
  35. getDispatcher().getRoot().getChildren().forEach(c ->
  36. {
  37. otherCommands.add(c.getName());
  38. });
  39. scheduler.scheduleTask(() ->
  40. {
  41. getDispatcher().getRoot().getChildren().forEach(c ->
  42. {
  43. if(otherCommands.add(c.getName()))
  44. {
  45. perms.addOtherGroupPermission(c.getName());
  46. }
  47. });
  48. });
  49. this.perms = perms;
  50. this.events = events;
  51. this.scripts = scripts;
  52. }
  53. public void clearCustomNodes()
  54. {
  55. customNodes.clear();
  56. }
  57. public void addCustomNodes(CommandNode node)
  58. {
  59. customNodes.add(node);
  60. }
  61. public void registerCommand(Command command)
  62. {
  63. commands.put(command.getName(), command);
  64. for(String alias : command.getAliases())
  65. {
  66. commands.put(alias, command);
  67. }
  68. }
  69. private String getCommandName(String rawCommand)
  70. {
  71. if(rawCommand.isEmpty())
  72. {
  73. return "";
  74. }
  75. int index = rawCommand.indexOf(' ');
  76. return rawCommand.substring(rawCommand.charAt(0) == '/' ? 1 : 0, index == -1 ? rawCommand.length() : index);
  77. }
  78. private static String[] getArguments(String rawCommand)
  79. {
  80. int old = rawCommand.indexOf(' ') + 1;
  81. if(old == 0)
  82. {
  83. return new String[0];
  84. }
  85. int pos = old;
  86. ArrayList<String> list = new ArrayList<>();
  87. while(pos < rawCommand.length())
  88. {
  89. char c = rawCommand.charAt(pos);
  90. switch(c)
  91. {
  92. case ' ':
  93. if(pos - old > 0)
  94. {
  95. list.add(rawCommand.substring(old, pos));
  96. }
  97. old = pos + 1;
  98. break;
  99. case '"':
  100. if(pos - old > 0)
  101. {
  102. list.add(rawCommand.substring(old, pos));
  103. }
  104. old = pos + 1;
  105. pos = old;
  106. while(pos < rawCommand.length() && rawCommand.charAt(pos) != '"')
  107. {
  108. pos++;
  109. }
  110. list.add(rawCommand.substring(old, pos));
  111. old = pos + 1;
  112. break;
  113. }
  114. pos++;
  115. }
  116. if(pos - old > 0)
  117. {
  118. list.add(rawCommand.substring(old, pos));
  119. }
  120. return list.toArray(new String[list.size()]);
  121. }
  122. private ICommandSource getSource(CommandSource cs)
  123. {
  124. if(cs.getEntity() != null)
  125. {
  126. return cs.getEntity();
  127. }
  128. return cs.getServer();
  129. }
  130. private String lowerRawCommand(String raw)
  131. {
  132. int index = raw.indexOf(" ");
  133. if(index == -1)
  134. {
  135. return raw.toLowerCase();
  136. }
  137. return raw.substring(0, index).toLowerCase() + raw.substring(index);
  138. }
  139. @Override
  140. public int handleCommand(CommandSource cs, String rawCommand)
  141. {
  142. rawCommand = lowerRawCommand(rawCommand);
  143. String commandName = getCommandName(rawCommand);
  144. Command command = commands.get(commandName);
  145. if(command != null)
  146. {
  147. if(perms.hasPermission(cs, command.getName()))
  148. {
  149. command.execute(getSource(cs), getArguments(rawCommand));
  150. return 1;
  151. }
  152. events.onMissingPermission(getSource(cs), command.getName());
  153. return 0;
  154. }
  155. if(scripts.isRegisteredScriptCommand(commandName))
  156. {
  157. Entity ent = cs.getEntity();
  158. if(ent != null && ent instanceof PlayerEntity)
  159. {
  160. events.onCustomCommand((PlayerEntity) ent, commandName, getArguments(rawCommand));
  161. return 1;
  162. }
  163. events.onCustomCommand(null, commandName, getArguments(rawCommand));
  164. return 0;
  165. }
  166. if(otherCommands.contains(commandName))
  167. {
  168. if(perms.hasPermission(cs, commandName))
  169. {
  170. Entity ent = cs.getEntity();
  171. if(ent != null && ent instanceof PlayerEntity)
  172. {
  173. CommandEvent e = new CommandEvent((PlayerEntity) ent, commandName);
  174. events.onCommand(e);
  175. if(e.isCanceled())
  176. {
  177. return 0;
  178. }
  179. }
  180. return super.handleCommand(cs, rawCommand);
  181. }
  182. events.onMissingPermission(getSource(cs), commandName);
  183. return 0;
  184. }
  185. events.onMissingCommand(getSource(cs), commandName);
  186. return 0;
  187. }
  188. @Override
  189. public void send(ServerPlayerEntity player)
  190. {
  191. Map<CommandNode<CommandSource>, CommandNode<ISuggestionProvider>> map = Maps.newHashMap();
  192. RootCommandNode<ISuggestionProvider> rootcommandnode = new RootCommandNode<>();
  193. map.put(getDispatcher().getRoot(), rootcommandnode);
  194. this.commandSourceNodesToSuggestionNodes(true, getDispatcher().getRoot(), rootcommandnode, player.getCommandSource(), map);
  195. for(CommandNode node : customNodes)
  196. {
  197. rootcommandnode.addChild(node);
  198. }
  199. player.connection.sendPacket(new SCommandListPacket(rootcommandnode));
  200. }
  201. private void commandSourceNodesToSuggestionNodes(boolean first,
  202. CommandNode<CommandSource> node,
  203. CommandNode<ISuggestionProvider> suggestion,
  204. CommandSource source,
  205. Map<CommandNode<CommandSource>, CommandNode<ISuggestionProvider>> map)
  206. {
  207. for(CommandNode<CommandSource> commandnode : node.getChildren())
  208. {
  209. if((first && perms.hasPermission(source, commandnode.getName()) || (!first && commandnode.canUse(source))))
  210. {
  211. ArgumentBuilder<ISuggestionProvider, ?> argumentbuilder = (ArgumentBuilder) commandnode.createBuilder();
  212. argumentbuilder.requires(a -> true);
  213. if(argumentbuilder.getCommand() != null)
  214. {
  215. argumentbuilder.executes(a -> 0);
  216. }
  217. if(argumentbuilder instanceof RequiredArgumentBuilder)
  218. {
  219. RequiredArgumentBuilder<ISuggestionProvider, ?> requiredargumentbuilder = (RequiredArgumentBuilder) argumentbuilder;
  220. if(requiredargumentbuilder.getSuggestionsProvider() != null)
  221. {
  222. requiredargumentbuilder.suggests(SuggestionProviders.ensureKnown(requiredargumentbuilder.getSuggestionsProvider()));
  223. }
  224. }
  225. if(argumentbuilder.getRedirect() != null)
  226. {
  227. argumentbuilder.redirect(map.get(argumentbuilder.getRedirect()));
  228. }
  229. CommandNode<ISuggestionProvider> commandNode = argumentbuilder.build();
  230. map.put(commandnode, commandNode);
  231. suggestion.addChild(commandNode);
  232. if(!commandnode.getChildren().isEmpty())
  233. {
  234. this.commandSourceNodesToSuggestionNodes(false, commandnode, commandNode, source, map);
  235. }
  236. }
  237. }
  238. }
  239. }