A small little update to Kepler.
I've finished the RCON system so I've completely removed the old system and added a new system, included a PHP example of how to send RCON commands to Kepler too.
Changelog
- Added: New RCON system
- Removed old unused libraries which cut down the compiled size of Kepler by 6 megabytes.
Reminder! Do not make RCON listen on anything other than localhost/127.0.01, if you are please make sure you know what you're doing by exposing the RCON port to the outside world. RCON is not the same as the MUS connection which Kepler also uses.
Download: https://github.com/Quackster/Kepler/releases/tag/v1.31
PHP code example for sending RCON commands alongside their valid usages:
PHP Code:
<?php
sendRcon("127.0.0.1", "12309", build("hotel_alert", array(
"message" => "Hello, World!",
"sender" => "Alex"
)));
sendRcon("127.0.0.1", "12309", build("hotel_alert", array(
"message" => "Hello, World!"
)));
sendRcon("127.0.0.1", "12309", build("refresh_looks", array(
"userId" => "1"
)));
sendRcon("127.0.0.1", "12309", build("refresh_hand", array(
"userId" => "1"
)));
sendRcon("127.0.0.1", "12309", build("refresh_club", array(
"userId" => "1"
)));
sendRcon("127.0.0.1", "12309", build("refresh_credits", array(
"userId" => "1"
)));
function build($header, $parameters) {
$message = "";
$message .= pack('N', strlen($header));
$message .= $header;
$message .= pack('N', count($parameters));
foreach ($parameters as $key => $value) {
$message .= pack('N', strlen($key));
$message .= $key;
$message .= pack('N', strlen($value));
$message .= $value;
}
$buffer = "";
$buffer .= pack('N', strlen($message));
$buffer .= $message;
return $buffer;
}
function sendRcon($ip, $port, $command) {
$socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
socket_connect($socket, $ip, $port);
socket_send($socket, $command, strlen($command), MSG_DONTROUTE);
socket_close($socket);
}
?>
Java example:
PHP Code:
public class RconCommand {
private final RconHeader header;
private final Map<String, Object> parameters;
public RconCommand(RconHeader header, Map<String, Object> parameters) {
this.header = header;
this.parameters = parameters;
}
public void send() {
try (Socket socket = new Socket(ServerConfiguration.getString("rcon.ip"), ServerConfiguration.getInteger("rcon.port"))) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream daos = new DataOutputStream(baos);
daos.writeInt(header.getRawHeader().length());
daos.write(header.getRawHeader().getBytes(StringUtil.getCharset()));
daos.writeInt(parameters.size());
for (var entry : parameters.entrySet()) {
daos.writeInt(entry.getKey().length());
daos.write(entry.getKey().getBytes(StringUtil.getCharset()));
daos.writeInt(entry.getValue().toString().length());
daos.write(entry.getValue().toString().getBytes(StringUtil.getCharset()));
}
try (DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream())) {
byte[] message = baos.toByteArray();
dataOutputStream.writeInt(message.length);
dataOutputStream.write(message);
dataOutputStream.flush();
baos.close();
daos.close();
socket.close();
} catch (IOException ignored) {
}
} catch (IOException ignored) {
}
}
}

Originally Posted by
webbanditten
Yesterday I merged your branch into mine and I just want to report back that its works and I couldnt be happier.
I also want thank you for your contributions to the Habbo Retro community this year, its been truly an amazing year and your contributions arent going unnoticed.
I personally hope the community next year will show a more collaborative and supportive spirit so we can continue the retro journey together. Together as a community we can achieve much more.
I'm so glad it worked out well and I agree completely.