Search in sources :

Example 1 with RconConsoleSourceBridge

use of org.spongepowered.common.bridge.server.rcon.RconConsoleSourceBridge in project SpongeCommon by SpongePowered.

the class RconClientMixin method run.

/**
 * @author Cybermaxke
 * @reason Fix RCON, is completely broken
 */
@SuppressWarnings("ConstantConditions")
@Override
@Overwrite
public void run() {
    // / Sponge: START
    // Initialize the source
    this.impl$source = new RconConsoleSource(SpongeCommon.server());
    ((RconConsoleSourceBridge) this.impl$source).bridge$setClient((RconClient) (Object) this);
    // Call the connection event
    final RconConnectionEvent.Connect connectEvent;
    try {
        connectEvent = SpongeCommon.serverScheduler().execute(() -> {
            final CauseStackManager causeStackManager = PhaseTracker.getCauseStackManager();
            causeStackManager.pushCause(this);
            causeStackManager.pushCause(this.impl$source);
            final RconConnectionEvent.Connect event = SpongeEventFactory.createRconConnectionEventConnect(causeStackManager.currentCause(), (RconConnection) this.impl$source);
            SpongeCommon.post(event);
            causeStackManager.popCauses(2);
            return event;
        }).get();
    } catch (final InterruptedException | ExecutionException ignored) {
        this.closeSocket();
        return;
    }
    if (connectEvent.isCancelled()) {
        this.closeSocket();
        return;
    }
    // /         'closeSocket' is moved out of the loop
    while (true) {
        try {
            if (!this.running) {
                break;
            }
            final BufferedInputStream bufferedinputstream = new BufferedInputStream(this.client.getInputStream());
            final int i = bufferedinputstream.read(this.buf, 0, this.buf.length);
            // / Sponge: START
            if (i == -1) {
                // continue to return EOF until we manually exit the loop.
                break;
            }
            if (10 <= i) {
                int j = 0;
                final int k = PktUtils.intFromByteArray(this.buf, 0, i);
                if (k != i - 4) {
                    break;
                }
                j += 4;
                final int l = PktUtils.intFromByteArray(this.buf, j, i);
                j += 4;
                final int i1 = PktUtils.intFromByteArray(this.buf, j);
                j += 4;
                switch(i1) {
                    case 2:
                        if (this.authed) {
                            final String command = PktUtils.stringFromByteArray(this.buf, j, i);
                            try {
                                // / Sponge: START
                                // Execute the command on the main thread and wait for it
                                SpongeCommon.serverScheduler().execute(() -> {
                                    final CauseStackManager causeStackManager = PhaseTracker.getCauseStackManager();
                                    // Only add the RemoteConnection here, the RconSource
                                    // will be added by the command manager
                                    causeStackManager.pushCause(this);
                                    SpongeCommon.server().getCommands().performCommand(this.impl$source.createCommandSourceStack(), command);
                                    causeStackManager.popCause();
                                }).get();
                                final String logContents = this.impl$source.getCommandResponse();
                                this.impl$source.prepareForCommand();
                                this.shadow$sendCmdResponse(l, logContents);
                            // / Sponge: END
                            } catch (final Exception exception) {
                                this.shadow$sendCmdResponse(l, "Error executing: " + command + " (" + exception.getMessage() + ")");
                            }
                            continue;
                        }
                        this.shadow$sendAuthFailure();
                        // Sponge: 'continue' -> 'break', disconnect when a invalid operation is requested
                        break;
                    case 3:
                        final String password = PktUtils.stringFromByteArray(this.buf, j, i);
                        if (!password.isEmpty() && password.equals(this.rconPassword)) {
                            // / Sponge: START
                            final RconConnectionEvent.Auth event = SpongeCommon.serverScheduler().execute(() -> {
                                final CauseStackManager causeStackManager = PhaseTracker.getCauseStackManager();
                                causeStackManager.pushCause(this);
                                causeStackManager.pushCause(this.impl$source);
                                final RconConnectionEvent.Auth event1 = SpongeEventFactory.createRconConnectionEventAuth(causeStackManager.currentCause(), (RconConnection) this.impl$source);
                                SpongeCommon.post(event1);
                                causeStackManager.popCauses(2);
                                return event1;
                            }).get();
                            if (!event.isCancelled()) {
                                this.authed = true;
                                this.shadow$send(l, 2, "");
                                continue;
                            }
                        // / Sponge: END
                        }
                        this.authed = false;
                        this.shadow$sendAuthFailure();
                        // Sponge: 'continue' -> 'break', disconnect if login failed
                        break;
                    default:
                        this.shadow$sendCmdResponse(l, String.format("Unknown request %s", Integer.toHexString(i1)));
                        // Sponge: 'continue' -> 'break', disconnect when a invalid operation is requested
                        break;
                }
            }
        } catch (final IOException e) {
            break;
        } catch (final Exception e) {
            RconClientMixin.LOGGER.error("Exception whilst parsing RCON input", e);
            break;
        }
    }
    this.closeSocket();
}
Also used : RconConsoleSource(net.minecraft.server.rcon.RconConsoleSource) IOException(java.io.IOException) RconConsoleSourceBridge(org.spongepowered.common.bridge.server.rcon.RconConsoleSourceBridge) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) BufferedInputStream(java.io.BufferedInputStream) CauseStackManager(org.spongepowered.api.event.CauseStackManager) RconConnection(org.spongepowered.api.network.RconConnection) RconConnectionEvent(org.spongepowered.api.event.network.rcon.RconConnectionEvent) ExecutionException(java.util.concurrent.ExecutionException) 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.server.rcon.RconConsoleSource)1 CauseStackManager (org.spongepowered.api.event.CauseStackManager)1 RconConnectionEvent (org.spongepowered.api.event.network.rcon.RconConnectionEvent)1 RconConnection (org.spongepowered.api.network.RconConnection)1 Overwrite (org.spongepowered.asm.mixin.Overwrite)1 RconConsoleSourceBridge (org.spongepowered.common.bridge.server.rcon.RconConsoleSourceBridge)1