Tuesday, July 21, 2015

RCON Client in Haskell

Source RCON is a TCP/IP based communication protocol, which can be used to issue console commands to the server via a remote console. The most common use of it, is to allow the server owners to control their game server properties without physically accessing the server. In order to use this, first one should be authenticated using the server's RCON password. 

Step 1: Setup the Minecraft server

To start off with the developing the RCON client, you should first establish a server to test your client. For this I'm using Minecraft. You can download the Minecraft server here, and run it. When started it creates a file called 'server.properties' in your working directly and shuts down immediately. The first step of configuration is to open the file 'EULA.txt' ( do not use a rich text editor like Wordpad, use Notepad, Gedit, etc ), and change 'eula=false' to 'eula=true'

Then edit your 'server.properties' manually to say 'enable-rcon=true'. Then save it and run the server again. Then edit the 'server.properties' file again to add your 'rcon.password'. After these steps, your 'server.properties' file should look like this;

Step 2: Establish a connection with the Minecraft server

In order to start with the development, first you should establish a connection with the server. In this step we need to identify a way to build a simple connection over the network using sockets.

Here 'Network.Socket' package is being used to create a connection with the server. First a socket is created using 'AF_INET' as the socket family, 'Stream' as the socket type, along with a default protocol.  
When we run this code after starting the Minecraft server, if you have got it correct it prints a log entry in the log file indicating the connection as follows; 

Step 3: Sending data over the network

Understanding the format of the data packets accepted by the server is a crucial part before sending data over the network. To understand this please go through the documentation at this page

According to the documentation we can build a Haskell data constructor to send our data over the network as follows;

First we need to build the data packet encapsulating the data we need to send over the network, and arrange them as a byte array to be sent over the network. In this code I have used 'Network.Socket.ByteString' send and receive data over the network. Since its 'send' method accepts a ByteString, the byte array needs to converted into a ByteString to feed into this method. 

Here the byte array representation of data in Haskell is a [Word8]. I've used 'Data.Bits' package to convert the Int values to [Word8] as follows;

And then this array of Word8 elements is packed into a ByteString using the 'pack' method in 'Data.ByteString' package. 

The complete code can be found at my GitHub repository

No comments:

Post a Comment