Minecraft Random Item Game Plugin using rcon

By Hawkee on Jul 27, 2012

This is a command line script that interfaces with Minecraft via rcon. It gives all the players on your server a chance to win a random item by typing "join". Here are the different modes:

block - random blocks
item - random items
record - random music disk
passive - random passive mob egg
hostile - random hostile mob egg
junk - random junky item
good - random good item

I've removed a few items that players just shouldn't have like mob spawners, nether portals and end portals, but there are still some tiles that might seem a bit odd, but they shouldn't do any harm.

This requires mcrcon in order to connect to the rcon server. You can install the pre-compiled version or build it from source.

Next you need to enable rcon in your server.properties:

rcon.password=password
enable-rcon=true
rcon.port=23456

Next you need to save this script into the same directory as your server.log because it needs to tail it in order to respond to the players. The command to run it is:

tail -f -n 1 server.log | php random_item.php <type> <quantity>

You can shorten this by creating a shell script and calling it random.sh:

tail -f -n 1 server.log | php random_item.php $1 $2

Then you run the game by typing:

./random.sh junk 24
./random.sh good 1
./random.sh item 5

There is a bug in Prerelease 1.3 that sometimes causes your server to crash when issuing rcon commands, so be aware of this.

<?php

$rcon_ip = '1.1.1.1';
$rcon_port = '23456';
$rcon_password = 'password';
$rcon = "./mcrcon -c -H $rcon_ip -P $rcon_port -p $rcon_password ";

$exclude = array(8,9,10,11,26,34,36,43,51,52,55,63,64,68,71,74,75,76,78,83,90,93,94,95,97,117,118,119,120,124,125,132);
$hostile_exclude = array(53,56,61);

$junk = array(32,58,367,336,290,270,269,4,3,37,38,6,13,60,324,87,288);
$good = array(56,57,19,42,110,116,122,130,133,264,276,277,278,279,310,311,312,313,324,347,354,388,384,368,381);

/********************************************************************************/
// Recursive function that doesn't return an item that's in the exclusion list.

function rand_exclude($first, $last, $exclude) {
    $num = rand($first,$last);
    if(in_array($num, $exclude)) return rand_exclude($first, $last, $exclude);
    return $num;
}

@system($rcon."'say Let us play the random item game! Type \"join\" to play.' >> rcon_output.txt");
@system($rcon."'list'");

$mode = $argv[1];
$quantity = $argv[2];

if(!$mode) {
    $no_mode = true;
    $quantity = 1;
}

$fulltimer = time()+microtime();

$stdin = fopen ('php://stdin', 'r');
ob_implicit_flush (true);
while($line = fgets ($stdin))
{
    preg_match("/\<([^\>]*)\>/", $line, $matches);
    $username = $matches[1];

    if($username && preg_match("/join/", $line) and !$done[$username]) {
        $done[$username] = true;

        if($no_mode) {
            $mode = rand(1,18);
            switch(true) {
                case (in_array($mode, range(1,5))): $mode = 'item'; break;
                case (in_array($mode, range(6,10))): $mode = 'block'; break;
                case (in_array($mode, range(11,15))): $mode = 'junk'; break;
                case ($mode == 16): $mode = 'record'; break;
                case ($mode == 17): $mode = 'passive'; break;
                case ($mode == 18): $mode = 'hostile'; break;
            }
        }

    if($mode == 'item') {
            $item = rand(256,388);
            // Always discard a good item the first time to make them more rare.
            if(in_array($item, $good)) $item = rand(256,388);
            system($rcon."'give $username $item $quantity' >> rcon_output.txt");
        }
        else if($mode == 'block') {
            $item = rand_exclude(1,136,$exclude);
            // Always discard a good item the first time to make them more rare.
            if(in_array($item, $good)) $item = rand_exclude(1,136,$exclude);
            system($rcon."'give $username $item $quantity' >> rcon_output.txt");
        }
        else if($mode == 'record') {
            $item = rand(2256,2266);
            system($rcon."'give $username $item $quantity' >> rcon_output.txt");
        }
        else if($mode == 'passive') {
            $item = rand(90,99);
            system($rcon."'give $username 383 $quantity $item' >> rcon_output.txt");
        }
        else if($mode == 'hostile') {
            $item = rand_exclude(50,62,$hostile_exclude);
            system($rcon."'give $username 383 $quantity $item' >> rcon_output.txt");
        }
        else if($mode == 'junk') {
            $item = array_rand($junk, 1);
            $item = $junk[$item];
            system($rcon."'give $username $item $quantity' >> rcon_output.txt");
        }
        else if($mode == 'good') {
            $item = array_rand($good, 1);
            $item = $good[$item];
            system($rcon."'give $username $item $quantity' >> rcon_output.txt");
        }
    }

    if(preg_match("/\[Rcon: (Given[^\]]*)\]/", $line, $matches)) {
        $result = addslashes($matches[1]);
        @system($rcon."'say $result' >> rcon_output.txt");
        $result = "/************************************************************\\"."\n".$result."\n\************************************************************/\n";
        print $result;
        $message .= $result;
        $count++;
    }
    else if(!preg_match('/Rcon connection from/', $line)) {
        print $line;
        $message .= $line;
    }   

    $stoptimer = time()+microtime();
    $timer = number_format(round($stoptimer-$fulltimer,3) / 60, 0);
    if($timer > 1) break;
}

@system($rcon."'say Thank you for playing the random item game! ($count Players)' >> rcon_output.txt");
exit;
?>

Comments

Sign in to comment.
TMFKSOFT   -  Dec 02, 2013

Well trying it with 1.7.2 dont work pretty much. Its more a case of. Variables dont even exist.

PHP Notice: Undefined variable: done in /home/mc/vanilla/mc_items.php on line 47
PHP Notice: Undefined variable: no_mode in /home/mc/vanilla/mc_items.php on line 50

and so on :P

Hawkee  -  Dec 03, 2013

Those sound like innocuous PHP errors. They shouldn't affect anything. You just need to make sure rcon still works. I haven't tested this on the latest version of Minecraft.

TMFKSOFT  -  Dec 03, 2013

Theyre variables that dont exist. After guessing what their values should be I got it working fine with 1.7.2
The log is now in logs/latest.log

Hawkee  -  Dec 03, 2013

You may have your PHP configured too strictly. A quick fix would be to define those variables with a null value. I really should have pre-defined them anyway.

Hawkee  -  Dec 03, 2013

Are you running a Minecraft server? What type?

TMFKSOFT  -  Dec 03, 2013

running Two atm. Creative and Survival. Was running Vanilla but now using something else that allows to switch between servers. I might adapt your script into a relay system.

Hawkee  -  Dec 03, 2013

This is very rudimentary. If you want to get into more advanced scripts you should try bukkit. I only used this when bukkit wasn't available.

Sign in to comment

TMFKSOFT   -  Oct 01, 2012

dribbles
Looks good. I'll try it sometime.
I hope to at one point write a Minecraft Client in PHP to load BMP images in or arrays to build Pixel art or something.
:P

 Respond  
[Plornt]   -  Aug 16, 2012

I dont know how mcmyadmin does it but it is able to inject right into the server for pretty much ANY version of minecraft including snapshots... Ill see if I can find out how they did it since its pretty awesome.

 Respond  
Hawkee   -  Jul 28, 2012

I updated the way items are excluded and added a more comprehensive exclusion list to stop broken tiles from spawning.

 Respond  
Sorasyn   -  Jul 28, 2012

I play it on occasion, in offline mode mostly, last time I played on a server it was a small local server. I saw something about Mojang, and 1.3 I might give it a try if it's available. It comes out on August 1st as the official release I believe.

I installed SinglePlayer Commands for Offline mode, it's basically server command mode for single player, which is nice.

 Respond  
Hawkee   -  Jul 28, 2012

@Sorasyn Do you play? I've been playing 1.3 snapshots lately.

 Respond  
Hawkee   -  Jul 28, 2012

I didn't want to play with Bukkit because they just haven't released it for 1.3 yet. This is really the only way to code for the snapshots.

 Respond  
Sorasyn   -  Jul 27, 2012

Neat little snippet! I was kind of tinkering with the idea of using Java to access Minecraft's class files for in-game custom commands.

 Respond  
Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.