Start of Sponge support (#41)

This commit is contained in:
kashike
2017-06-05 08:25:00 -07:00
committed by Daniel Ennis
parent 99a89b2826
commit cd892fccd4
11 changed files with 586 additions and 2 deletions
@@ -32,7 +32,7 @@ import java.util.Map;
public class CommandCompletionContext {
private final RegisteredCommand command;
private final CommandIssuer issuer;
protected final CommandIssuer issuer;
private final String input;
private final String config;
private final Map<String, String> configs = Maps.newHashMap();
+1 -1
View File
@@ -100,6 +100,6 @@
<module>bukkit</module>
<module>paper</module>
<!--module>bungee</module-->
<!--module>sponge</module-->
<module>sponge</module>
</modules>
</project>
+63
View File
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
~
~ Permission is hereby granted, free of charge, to any person obtaining
~ a copy of this software and associated documentation files (the
~ "Software"), to deal in the Software without restriction, including
~ without limitation the rights to use, copy, modify, merge, publish,
~ distribute, sublicense, and/or sell copies of the Software, and to
~ permit persons to whom the Software is furnished to do so, subject to
~ the following conditions:
~
~ The above copyright notice and this permission notice shall be
~ included in all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
~ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
~ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
~ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
~ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
~ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
~ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>co.aikar</groupId>
<artifactId>acf-parent</artifactId>
<version><!--VERSION-->0.5.0-SNAPSHOT<!--VERSION--></version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>acf-sponge</artifactId>
<version><!--VERSION-->0.5.0-SNAPSHOT<!--VERSION--></version>
<name>ACF (Sponge)</name>
<repositories>
<repository>
<id>spongepowered</id>
<url>https://repo.spongepowered.org/maven/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>co.aikar</groupId>
<artifactId>acf-core</artifactId>
<version><!--VERSION-->0.5.0-SNAPSHOT<!--VERSION--></version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>spongeapi</artifactId>
<version>5.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import org.spongepowered.api.command.CommandSource;
@SuppressWarnings("WeakerAccess")
public class SpongeCommandCompletionContext extends CommandCompletionContext {
SpongeCommandCompletionContext(final RegisteredCommand command, final CommandIssuer issuer, final String input, final String config, final String[] args) {
super(command, issuer, input, config, args);
}
public CommandSource getSource() {
return this.issuer.getIssuer();
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import org.spongepowered.api.command.CommandSource;
@SuppressWarnings("WeakerAccess")
public class SpongeCommandCompletions extends CommandCompletions<CommandSource, SpongeCommandCompletionContext> {
public SpongeCommandCompletions(final SpongeCommandManager manager) {
super(manager);
}
}
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
@SuppressWarnings("WeakerAccess")
public class SpongeCommandContexts extends CommandContexts<SpongeCommandExecutionContext> {
public SpongeCommandContexts(final SpongeCommandManager manager) {
super(manager);
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import org.spongepowered.api.command.CommandSource;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Map;
public class SpongeCommandExecutionContext extends CommandExecutionContext<SpongeCommandExecutionContext> {
SpongeCommandExecutionContext(RegisteredCommand cmd, Parameter param, CommandIssuer sender, List<String> args,
int index, Map<String, Object> passedArgs) {
super(cmd, param, sender, args, index, passedArgs);
}
public CommandSource getSource() {
return this.issuer.getIssuer();
}
}
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.text.serializer.TextSerializers;
public class SpongeCommandIssuer implements CommandIssuer {
private final CommandSource source;
SpongeCommandIssuer(final CommandSource source) {
this.source = source;
}
@Override
public boolean isPlayer() {
return this.source instanceof Player;
}
@Override
public <T> T getIssuer() {
//noinspection unchecked
return (T) this.source;
}
@Override
public void sendMessage(final String message) {
this.source.sendMessage(TextSerializers.FORMATTING_CODE.deserialize(message));
}
@Override
public boolean hasPermission(final String permission) {
return this.source.hasPermission(permission);
}
}
@@ -0,0 +1,122 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import co.aikar.timings.Timing;
import co.aikar.timings.Timings;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.plugin.PluginContainer;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SuppressWarnings("WeakerAccess")
public class SpongeCommandManager extends CommandManager {
protected final PluginContainer plugin;
protected Map<String, SpongeRootCommand> registeredCommands = new HashMap<>();
protected SpongeCommandContexts contexts;
protected SpongeCommandCompletions completions;
public SpongeCommandManager(PluginContainer plugin) {
this.plugin = plugin;
}
@Override
public boolean isCommandIssuer(Class<?> type) {
return CommandSource.class.isAssignableFrom(type);
}
@Override
public synchronized CommandContexts<SpongeCommandExecutionContext> getCommandContexts() {
if (this.contexts == null) {
this.contexts = new SpongeCommandContexts(this);
}
return contexts;
}
@Override
public synchronized CommandCompletions<CommandSource, SpongeCommandCompletionContext> getCommandCompletions() {
if (this.completions == null) {
this.completions = new SpongeCommandCompletions(this);
}
return completions;
}
@Override
public boolean hasRegisteredCommands() {
return !registeredCommands.isEmpty();
}
@Override
public void registerCommand(BaseCommand command) {
command.onRegister(this);
for (Map.Entry<String, RootCommand> entry : command.registeredCommands.entrySet()) {
String key = entry.getKey().toLowerCase();
SpongeRootCommand value = (SpongeRootCommand) entry.getValue();
if (!value.isRegistered) {
Sponge.getCommandManager().register(this.plugin, value, value.name);
}
value.isRegistered = true;
registeredCommands.put(key, value);
}
}
public Timing createTiming(final SpongeRegisteredCommand command) {
return Timings.of(this.plugin, "Command: " + command.command);
}
@Override
public RootCommand createRootCommand(String cmd) {
return new SpongeRootCommand(this, cmd);
}
@Override
public CommandIssuer getCommandIssuer(Object issuer) {
if (!(issuer instanceof CommandSource)) {
throw new IllegalArgumentException(issuer.getClass().getName() + " is not a Command Issuer.");
}
return new SpongeCommandIssuer((CommandSource) issuer);
}
@Override
public <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
return (R) new SpongeCommandExecutionContext(command, parameter, sender, args, i, passedArgs);
}
@Override
public CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) {
return new SpongeCommandCompletionContext(command, sender, input, config, args);
}
@Override
public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) {
return new RegisteredCommand(command, cmdName, method, prefSubCommand);
}
}
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import co.aikar.timings.Timing;
import java.lang.reflect.Method;
public class SpongeRegisteredCommand extends RegisteredCommand<SpongeCommandExecutionContext> {
private final Timing timing;
SpongeRegisteredCommand(BaseCommand scope, String command, Method method, String prefSubCommand) {
super(scope, command, method, prefSubCommand);
this.timing = ((SpongeCommandManager) scope.manager).createTiming(this);
}
@Override
public void preCommand() {
this.timing.startTiming();
super.preCommand();
}
@Override
public void postCommand() {
super.postCommand();
this.timing.stopTiming();
}
}
@@ -0,0 +1,145 @@
/*
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package co.aikar.commands;
import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil;
import org.spongepowered.api.command.CommandCallable;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.command.CommandMapping;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nullable;
public class SpongeRootCommand implements CommandCallable, RootCommand {
private final SpongeCommandManager manager;
final String name;
private BaseCommand defCommand;
private Map<String, BaseCommand> subCommands = new HashMap<>();
private List<BaseCommand> children = new ArrayList<>();
boolean isRegistered = false;
SpongeRootCommand(SpongeCommandManager manager, String name) {
this.manager = manager;
this.name = name;
}
@Override
public CommandResult process(CommandSource source, String arguments) throws CommandException {
if(this.execute(new SpongeCommandIssuer(source), this.name, arguments.split(" "))) {
return CommandResult.success();
}
return CommandResult.empty();
}
@Override
public List<String> getSuggestions(CommandSource source, String arguments, @Nullable Location<World> location) throws CommandException {
return tabComplete(new SpongeCommandIssuer(source), this.name, arguments.split(" "));
}
@Override
public boolean testPermission(CommandSource source) {
return true;
}
@Override
public Optional<Text> getShortDescription(CommandSource source) {
return Optional.empty();
}
@Override
public Optional<Text> getHelp(CommandSource source) {
return Optional.empty();
}
@Override
public Text getUsage(CommandSource source) {
return Text.of();
}
private List<String> tabComplete(CommandIssuer sender, String alias, String[] args) throws IllegalArgumentException {
Set<String> completions = new HashSet<>();
this.children.forEach(child -> completions.addAll(child.tabComplete(sender, alias, args)));
return new ArrayList<>(completions);
}
private boolean execute(CommandIssuer sender, String commandLabel, String[] args) {
for (int i = args.length; i >= 0; i--) {
String checkSub = ApacheCommonsLangUtil.join(args, " ", 0, i).toLowerCase();
BaseCommand subHandler = this.subCommands.get(checkSub);
if (subHandler != null) {
if (!subHandler.testPermission(sender)) {
return true;
}
subHandler.execute(sender, commandLabel, args);
return false;
}
}
if (!this.defCommand.testPermission(sender)) {
return true;
}
this.defCommand.execute(sender, commandLabel, args);
return false;
}
public void addChild(BaseCommand command) {
if (this.defCommand == null || !command.subCommands.get("__default").isEmpty()) {
this.defCommand = command;
//this.setDescription(command.getDescription());
//this.setUsage(command.getUsage());
//this.setAliases(command.getAliases());
}
command.subCommands.keySet().forEach(key -> {
if (key.equals(BaseCommand.DEFAULT) || key.equals(BaseCommand.UNKNOWN)) {
return;
}
BaseCommand regged = this.subCommands.get(key);
if (regged != null) {
ACFLog.severe("ACF Error: " + command.getName() + " registered subcommand " + key + " for root command " + this.name + " - but it is already defined in " + regged.getName());
ACFLog.severe("2 subcommands of the same prefix may not be spread over 2 different classes. Ignoring this.");
return;
}
this.subCommands.put(key, command);
});
this.children.add(command);
}
@Override
public CommandManager getManager() {
return manager;
}
}