use of org.spongepowered.common.interfaces.IMixinRConConsoleSource 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();
}
Aggregations