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();
}
Aggregations