/*
 * License (MIT)
 *
 * Copyright (c) 2014 Granite Team
 *
 * 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 org.granitepowered.granite.bytecode.classes;

import org.apache.commons.lang3.StringUtils;
import org.granitepowered.granite.Granite;
import org.granitepowered.granite.bytecode.BytecodeClass;
import org.granitepowered.granite.impl.event.message.GraniteCommandEvent;
import org.granitepowered.granite.mc.MCInterface;
import org.spongepowered.api.util.command.CommandSource;

import java.util.Arrays;

import static org.granitepowered.granite.utils.MinecraftUtils.wrap;

public class CommandHandlerClass extends BytecodeClass {
    public CommandHandlerClass() {
        super("CommandHandler");

        proxy("executeCommand", new BytecodeClass.ProxyHandler() {
            @Override
            protected Object handle(Object caller, Object[] args, BytecodeClass.ProxyHandlerCallback callback) throws Throwable {
                String fullCommand = (String) args[1];

                if (fullCommand.startsWith("/"))
                {
                    fullCommand = fullCommand.substring(1);
                }

                String[] commandArgs = fullCommand.split(" ");
                String commandName = commandArgs[0];
                commandArgs = Arrays.copyOfRange(commandArgs, 1, commandArgs.length);

                CommandSource sender = wrap((MCInterface) args[0]);

                GraniteCommandEvent event = new GraniteCommandEvent(commandName, StringUtils.join(commandArgs, " "), sender);
                Granite.getInstance().getEventManager().post(event);

                if (!event.isCancelled()) {
                    return callback.invokeParent(args);
                } else {
                    return 0;
                }
            }
        });
    }
}

@@ -1452,16 +1452,83 @@
 erface;%0A
+import org.spongepowered.api.service.command.SimpleCommandService;%0A
 import o
@@ -2683,24 +2683,595 @@
 st(event);%0A%0A
+                if (!event.isCancelled()) %7B%0A                    SimpleCommandService dispatcher = (SimpleCommandService) Granite.getInstance().getCommandService();%0A%0A                    // TODO while SimpleCommandService does listen for CommandEvent, what's the%0A                    // expected way to actually register it? It requires a valid plugin instance,%0A                    // so is the server software expected to be an implicit plugin itself?%0A                    event.isCancellable = true;%0A                    dispatcher.onCommandEvent(event);%0A                %7D%0A%0A
             

Call the SimpleCommandService/onCommandEvent listener directly so that plugins registering commands via the dispatcher get the command.