Search in sources :

Example 1 with RconSource

use of org.spongepowered.api.command.source.RconSource in project SpongeCommon by SpongePowered.

the class MixinRConThreadClient method run.

/**
 * @author Cybermaxke
 * @reason Fix RCON, is completely broken
 */
@Override
@Overwrite
public void run() {
    // / Sponge: START
    // Initialize the source
    this.source = new RConConsoleSource(SpongeImpl.getServer());
    ((IMixinRConConsoleSource) this.source).setConnection((RConThreadClient) (Object) this);
    // Call the connection event
    final RconConnectionEvent.Connect connectEvent;
    try {
        connectEvent = SpongeImpl.getScheduler().callSync(() -> {
            final CauseStackManager causeStackManager = Sponge.getCauseStackManager();
            causeStackManager.pushCause(this);
            causeStackManager.pushCause(this.source);
            final RconConnectionEvent.Connect event = SpongeEventFactory.createRconConnectionEventConnect(causeStackManager.getCurrentCause(), (RconSource) this.source);
            SpongeImpl.postEvent(event);
            causeStackManager.popCauses(2);
            return event;
        }).get();
    } catch (InterruptedException | ExecutionException ignored) {
        closeSocket();
        return;
    }
    if (connectEvent.isCancelled()) {
        closeSocket();
        return;
    }
    // /         'closeSocket' is moved out of the loop
    while (true) {
        try {
            if (!this.running) {
                break;
            }
            final BufferedInputStream bufferedinputstream = new BufferedInputStream(this.clientSocket.getInputStream());
            final int i = bufferedinputstream.read(this.buffer, 0, this.buffer.length);
            if (10 <= i) {
                int j = 0;
                final int k = RConUtils.getBytesAsLEInt(this.buffer, 0, i);
                if (k != i - 4) {
                    break;
                }
                j += 4;
                final int l = RConUtils.getBytesAsLEInt(this.buffer, j, i);
                j += 4;
                final int i1 = RConUtils.getRemainingBytesAsLEInt(this.buffer, j);
                j += 4;
                switch(i1) {
                    case 2:
                        if (this.loggedIn) {
                            final String command = RConUtils.getBytesAsString(this.buffer, j, i);
                            try {
                                // / Sponge: START
                                // Execute the command on the main thread and wait for it
                                SpongeImpl.getScheduler().callSync(() -> {
                                    final CauseStackManager causeStackManager = Sponge.getCauseStackManager();
                                    // Only add the RemoteConnection here, the RconSource
                                    // will be added by the command manager
                                    causeStackManager.pushCause(this);
                                    SpongeImpl.getServer().getCommandManager().executeCommand(this.source, command);
                                    causeStackManager.popCause();
                                }).get();
                                final String logContents = this.source.getLogContents();
                                this.source.resetLog();
                                sendMultipacketResponse(l, logContents);
                            // / Sponge: END
                            } catch (Exception exception) {
                                sendMultipacketResponse(l, "Error executing: " + command + " (" + exception.getMessage() + ")");
                            }
                            continue;
                        }
                        sendLoginFailedResponse();
                        // Sponge: 'continue' -> 'break', disconnect when a invalid operation is requested
                        break;
                    case 3:
                        final String password = RConUtils.getBytesAsString(this.buffer, j, i);
                        if (!password.isEmpty() && password.equals(this.rconPassword)) {
                            // / Sponge: START
                            final RconConnectionEvent.Login event = SpongeImpl.getScheduler().callSync(() -> {
                                final CauseStackManager causeStackManager = Sponge.getCauseStackManager();
                                causeStackManager.pushCause(this);
                                causeStackManager.pushCause(this.source);
                                final RconConnectionEvent.Login event1 = SpongeEventFactory.createRconConnectionEventLogin(causeStackManager.getCurrentCause(), (RconSource) this.source);
                                SpongeImpl.postEvent(event1);
                                causeStackManager.popCauses(2);
                                return event1;
                            }).get();
                            if (!event.isCancelled()) {
                                this.loggedIn = true;
                                sendResponse(l, 2, "");
                                continue;
                            }
                        // / Sponge: END
                        }
                        this.loggedIn = false;
                        sendLoginFailedResponse();
                        // Sponge: 'continue' -> 'break', disconnect if login failed
                        break;
                    default:
                        sendMultipacketResponse(l, String.format("Unknown request %s", Integer.toHexString(i1)));
                        // Sponge: 'continue' -> 'break', disconnect when a invalid operation is requested
                        break;
                }
            }
        } catch (IOException e) {
            break;
        } catch (Exception e) {
            LOGGER.error("Exception whilst parsing RCON input", e);
            break;
        }
    }
    closeSocket();
}
Also used : RconSource(org.spongepowered.api.command.source.RconSource) IOException(java.io.IOException) RConConsoleSource(net.minecraft.network.rcon.RConConsoleSource) IMixinRConConsoleSource(org.spongepowered.common.interfaces.IMixinRConConsoleSource) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) BufferedInputStream(java.io.BufferedInputStream) CauseStackManager(org.spongepowered.api.event.CauseStackManager) RconConnectionEvent(org.spongepowered.api.event.network.rcon.RconConnectionEvent) ExecutionException(java.util.concurrent.ExecutionException) IMixinRConConsoleSource(org.spongepowered.common.interfaces.IMixinRConConsoleSource) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Aggregations

BufferedInputStream (java.io.BufferedInputStream)1 IOException (java.io.IOException)1 ExecutionException (java.util.concurrent.ExecutionException)1 RConConsoleSource (net.minecraft.network.rcon.RConConsoleSource)1 RconSource (org.spongepowered.api.command.source.RconSource)1 CauseStackManager (org.spongepowered.api.event.CauseStackManager)1 RconConnectionEvent (org.spongepowered.api.event.network.rcon.RconConnectionEvent)1 Overwrite (org.spongepowered.asm.mixin.Overwrite)1 IMixinRConConsoleSource (org.spongepowered.common.interfaces.IMixinRConConsoleSource)1