Jump to content

And now for something completely different


Recommended Posts

Since work was quiet today I ended up making THIS!

 

 

wp000203.jpg

 

I stuck a little LCD display onto an Arduino micro controller so that I could be obsessive compulsive about checking the server is still running and how popular it is without having to constantly be switching windows :D

 

Its still quite rough but it works as a proof of concept, currently there is a PHP script that Rcon's into my jka server and runs a status command then takes in what it gets back and processes it to make it more compact then this is picked up by gobetwino which is used to send the data on down the serial line where it is then displayed by the Arduino. Given the number of buttons I have on the controller the next logical step it seems to me would be to be able to browse through a list of players on the server and use admin commands on them from it as well MWAHAHA

Caelum, therfiles, afi and 1 other like this
Link to comment

Haha im glad you like :D If anyone is interested here is the source code for the various bits :D

 

Micro controller code (Written in C++):

#include <LiquidCrystal.h>
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int lcd_key	 = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP	 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
String data; // shove the raw input into here
String themap; // stick the parsed map data into here
String players; //stick the parsed player data into here
boolean foundsplit; //record if we have found the split in the data
char splitter='|'; //the char used to split the data
char inData[20]; // Allocate some space for the string being read in from the serial interface
char inChar; // Where to store the character read from the serial
byte index = 0; // Index into array; where to store the character

void setup()
{
// start serial port at 9600 bps:
Serial.begin(9600);

//set the time
lcd.begin(16, 2);			 // start the LCD display
lcd.setCursor(0,0); //set the cursor on the lcd display
delay(1000); //wait a bit

}


void loop()
{
getdata();
}

void getdata()
{
Serial.println("#S|GETMESSAGE|[]#"); //request gobetweno downloads the latest server info to the local pc.
delay(1000);//wait a second just to give it time to chill.
Serial.read(); //read in the status code deturned from getmessage so we dont have to bother with it later.
Serial.println("#S|READMESSAG|[1]#"); //request gobetweno sends server info down the serial line
delay(10000);//wait a bit again

while(Serial.available() > 0) // Don't read unless there is data
{
if(index < 19) // One less than the size of the array
{
 inChar = Serial.read(); // Read a character
 inData[index] = inChar; // Store it
 index++; // Increment where to write next
 inData[index] = '\0'; // Null terminate the string
}
}
//Feed the chars into a string, becuase working with Char's is kinda a pain
data = String(inData);
//explode the data into its relevant parts, this bit is kinda rough and needs reworked
for(int i=1; i<int(data.length());i++)
{
if(data[i] == splitter)
{
 foundsplit=true;
}
if(foundsplit)
{
 players= players+data[i+1];
}
else
{
 themap = themap + data[i];
}
}

//output the map and players for debugging purposes
Serial.println(themap);
Serial.println(players);
//now to draw the info onthe display
lcd.setCursor(0,0);
lcd.print(themap); //the map data comes with "map: " at the start of it so we can just display it raw
lcd.setCursor(0,1);//move to the bottom line
lcd.print("Players: "+players); //show the current number of players on the server
//go through and clear all the data from everything, ready for the next read
themap="";
players="";
data="";
index = 0;
foundsplit=false;
for(int i=0;i<20;i++)
{
inData[i]=' ';
}

}

 

Server code (Written in php):

<?php
/*
This script incorporates a file from: http://www.gamefront.com/files/13442800/Ruckman_RCON___Quake_3
In order to provide the raw rcon functionality.
*/
$server="";
$port=0;
$password="";
$q = new mohaa_rcon();
$result = $q -> rcon($server,$port,$password,'status');
$result = str_replace("\n","",$result );
$result = explode("ÿÿÿÿprint",$result);
$output=$result[1]."|".(count($result)-6);

print $output;
# MEDAL OF HONOR AND QUAKE ENGINE RCON CLASS
# BY WILLIAM RUCKMAN (HTTP://RUCKMAN.NET)

class mohaa_rcon
{

function rcon ($IP, $PORT, $PASSWORD, $COMMAND) {

if (!validateIpAddress($IP)) {
$data = "IP Address malformed!";
return $data;
}

if ($PORT < 1 || $PORT > 65535 || $PORT == "") {
$data = "Port range must be between 1-65535!";
return $data;
}

$data = '';
$fp = fsockopen('udp://'.$IP, $PORT, $errno, $errstr, 2);
socket_set_timeout($fp,2);

if (!$fp){
$data = "Unable to Connect! Socket Error!";
return $data;
} else {
$query = "\xFF\xFF\xFF\xFF\x02 rcon \"" . $PASSWORD . "\" " . $COMMAND;
fwrite($fp,$query);
}
$data = '';
while ($d = fread ($fp, 10000)) {
 $data .= $d;
 }
 fclose ($fp);	
 if ($data == "") {
 $data = "Connection failed, No responds from server, or changing maps.";
 return $data;
 }
 $data = preg_replace ("/.....print\n/", "", $data);
 if ($data == "") {
 $data = "Command sent successfully but returned no output. Possible bad command.";
 }

 return $data;
 }

}
function validateIpAddress($IP)
{
if(preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/",$IP))
{
$parts=explode(".",$IP);
foreach($parts as $ip_parts)
{
if(intval($ip_parts)>255 || intval($ip_parts)<0)
return false;
}
return true;
}
else
return false;
}
?>

 

At the moment im trying to get the code on the Arduino that processes the incoming data to be a little more robust since it still falls down alot at the moment :D

Caelum likes this
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...