Use PHP (and Python) to relaunch DreamDaemon

Now, if you're like me and you have a server capable of running BYOND but a host that likes to kill processes once they get over a specific amount CPU usage, you'll know the tiresome pain that is relaunching games when you wake up in the morning (or if you're like me... afternoon).

Not only is this a repetitive and tiresome process, but it also kills your players morale. Your server starts getting popular, players are having a good time and BAM, no more server. This especially kicks in if you're limited on funds and can't afford a server where you have more control.

Well, a small solution is to relaunch DreamDaemon automatically. And here is a small script I whipped up to do so.

<?
    $port_num = 55678; //The port in which you want to host the game on.
    
    $a = shell_exec("netstat -nlt | grep $port_num"); //Check to see if that port is already in use. Or DreamDaemon is still running.
    if(!$a) { //If it isn't, relaunch DreamDaemon.
        popen("DreamDaemon path/to/your/game.dmb $port_num -trusted &", "r");
    }
?>


Now that works all fine and dandy, but what about automating that script for a set time limit. I attempted to do this using a Cron Job. But it didn't work. (Audeuro has an untested script to make it work, and once I've tested that, I'll post it here.)

Automating the script needed a finer approach. Seeing as CronDaemon wasn't successfully doing it, I needed something else to kick in. And that's where I sought assistance from BYOND's local Python Guru, Crashed.

With a little script he whipped up (able to work with Python 2.2 and onwards) we were able to automate it.

from time import sleep 
import os 
while True:  
  os.popen('php my_php_file.php')  
  sleep(1800) #seconds


To execute the script, open up your command line client (in my case, PuTtY) and execute it like so: python my_python_file.py &
If the BYOND server isn't running, you'll receive DreamDaemon's execution message. Then type exit and logout.

Now, that script there will run your PHP script every half an hour to check up on your DreamDaemon. Ever looking to improve it, I'll be revising this script at a later date to check on it all. But at the moment, that should do the trick (it's working so far for me).

I should also say, that script will only work provided both the python and php script are inside your root folder (that is, the one before public_html).

Posted by Tiberath (Guildmaster) on Tuesday, March 11, 2008 09:45PM - 0 comments / Members say: yea +0, nay -0

Online Games (Updated!)

Ever wanted to display the join URL, Players in the game and the server Status on a PHP-enabled website? Now you can!

In addition to my previous post, this little function will grab all the information on hosted servers you need. To use it is pretty simple too, Grab the data using a variable: $servers = hub_get_contents('enigmaster2002.iconultima'); then just put it inside a for($i = 0; $i < count($servers); $i++) loop and display the data with $servers[$i]['url'].

(An example of the script in action can be found: here. Just change the ?hub= in the address bar to your game and see how it works.

function hub_get_contents($hub) {
    $hub_page = file_get_contents("http://www.byond.com/games/" . $hub . "&format=text");
    $servers = array();

    $i = strpos($hub_page,"world/1");
    $disabledline_server = explode('world/', substr($hub_page, $i+9, strlen($hub_page)));
    foreach($online_server as $game) {
        $server = array(
            'url'		=> '',
            'status'	=> '',
            'users'		=> '',
        );
        
        $start = strpos($game, 'url');
        if($start) {
            $a = strpos($game, '"', $start)+1;
            $b = strpos($game, '"', $a);
            $server['url'] = substr($game, $a, $b - $a);
        }
        
        $start = strpos($game, 'status');
        if($start) {
            $a = strpos($game, '"', $start) +1;
            $b = strpos($game, '"', $a);
            $server['status'] = substr($game, $a, $b - $a);
        }
        
        $start = strpos($game, 'users');
        if($start) {
            $start = $start+13;
            $end = strpos($game, ')', $start);
            $result = str_replace('"', '', substr($game, $start, $end - ($start)));
            $server['users'] = $result;
        }
                    
        $servers[] = $server;
    }
    
    return $servers;
}


[Update]
One or two people sent me a page because they were having trouble getting the function to work. So I'll give you a complete working script to go with it.

$servers = hub_get_contents('enigmaster2002.iconultima');
for($i = 0; $i < count($servers); $i++) {
    echo("<b>URL:</b> " . $servers[$i]['url'] . "<br>");
    echo("<b>Status:</b> " . $servers[$i]['status'] . "<br>");
    echo("<b>Users:</b> " . $servers[$i]['users'] . "<br><br>");
}

function hub_get_contents($hub) {
    $hub_page = file_get_contents("<a href="http://www.byond.com/games/">http://www.byond.com/games/</a>" . $hub . "&format=text");
    $servers = array();

    $i = strpos($hub_page,"world/1");
    $online_server = explode('world/', substr($hub_page, $i+9, strlen($hub_page)));
    foreach($online_server as $game) {
        $server = array(
            'url'		=> '',
            'status'	=> '',
            'users'		=> '',
        );
        
        $start = strpos($game, 'url');
        if($start) {
            $a = strpos($game, '"', $start)+1;
            $b = strpos($game, '"', $a);
            $server['url'] = substr($game, $a, $b - $a);
        }
        
        $start = strpos($game, 'status');
        if($start) {
            $a = strpos($game, '"', $start) +1;
            $b = strpos($game, '"', $a);
            $server['status'] = substr($game, $a, $b - $a);
        }
        
        $start = strpos($game, 'users');
        if($start) {
            $start = $start+13;
            $end = strpos($game, ')', $start);
            $result = str_replace('"', '', substr($game, $start, $end - ($start)));
            $server['users'] = $result;
        }
                    
        $servers[] = $server;
    }
    
    return $servers;
}

Posted by Tiberath (Guildmaster) on Sunday, February 17, 2008 01:24AM - 2 comments / Members say: yea +0, nay -0
(Edited on Tuesday, March 18, 2008 09:08PM)

hub_get_contents()

Due to the lack of activity this guild has been experiencing. I've decided to release three quarters of a PHP function I wrote a while ago.

A lot of people tend to ask how to grab hub page information. The best way is PHP and the BYOND Hub Page text format. With this in mind, I wrote a function some time ago which did it. But it was a crap function.

Since then, I've rewritten it twice. And even released one to a select few of BYOND Users. Now I'm going to release part of that function (after it was revised) to everyone.

And here it is: [Due to a bug inside the DM parser in BYOND Members pages, you'll have to remove the anchor tags inside the file_get_contents() function.]
<?
    //Using the standard world/hub format. Just type in the key and the game name as shown below.
    $hub = @hub_get_contents('tiberath.storytelling');

    function hub_get_contents($hub_page) {
        //We use the file_get_contents() function to grab the text information off the BYOND Hub page.
        $hub_page = @file_get_contents('<a href="http://games.byond.com/hub/hub.cgi?qd=hub;hub=">http://games.byond.com/hub/hub.cgi?qd=hub;hub=</a>' . $hub_page . ';format=text');
        
        //We use an array to store the information we wish to return back to the $hub variable. You can remove anything you think you wont need. 
        //But if you look, you'll notice the words match exactly what is displayed on the text format of a hub page. It has to be that way.
        //Bare in mind,  I haven't included the 'subscription_price' option yet. That'll probably come in a later release.
        $game_info = array("title" => "", "icon" => "", "small_icon" => "", "short_desc" => "", "long_desc" => "", "author" => "", "registered" => "", "version" => "", "status" => "", "byond_rank" => "");
        
        //I used to use a while() loop here. But I later learned this makes the code more compact and probably works better.
        foreach($game_info as $key => $value) {
            $start = strpos($hub_page, $key);
            
            //Because BYOND's text format is a pain, it sometimes doesn't enclose it's values in quotation marks. When it doesn't,
            //it breaks my function. So we have to distinguish when it does and doesn't. Luckily, it only doesn't once.
            //We also have to make sure there is a start value. If the value we're looking for isn't present, there's no sense running
            //a function to find it's contents.
            if($start) {
                if($key == 'byond_rank') {
                    $start += 3; 
                    $end = strpos($hub_page, (chr(10)), $start);
                } else {
                    $start += 4;
                    $end = strpos($hub_page, ('"' . chr(10)), $start);
                }
                
                //To remove the key from the start, we add it's length to the start variable.
                $start += strlen($key);
                
                //I used to use Mobius' substring() function here. But I decided there wasn't going to be a need when there wouldn't be an end variable.
                //So I just did the logical thing. Take the start from the end. Beautiful no?
                $game_info[$key] = stripslashes(str_replace("\\n", "<br>", substr($hub_page, $start, $end - $start)));
            }
        }
        
        //Return the game_info array so you can use the hub variable as an array.
        return $game_info;
    }
?>


The full function includes server information (who's logged into what server and all that). But I'm not in the mood to give away all my secrets.

(This could probably be done better using Regular Expressions, but because I don't know them, I'm not going to use them.)

To use the function, just call your hub variable like an array: echo $hub['title'];
Easy done.

--

If you're already PHP compliant, I'm also including a copy of the function without the comments.

<?
    $hub = @hub_get_contents('tiberath.storytelling');

    function hub_get_contents($hub_page) {
        $hub_page = @file_get_contents('<a href="http://games.byond.com/hub/hub.cgi?qd=hub;hub=">http://games.byond.com/hub/hub.cgi?qd=hub;hub=</a>' . $hub_page . ';format=text');
        $game_info = array("title" => "", "icon" => "", "small_icon" => "", "short_desc" => "", "long_desc" => "", "author" => "", "registered" => "", "version" => "", "status" => "", "byond_rank" => "");
        foreach($game_info as $key => $value) {
            $start = strpos($hub_page, $key);
            if($start) {
                if($key == 'byond_rank') {
                    $start += 3; 
                    $end = strpos($hub_page, (chr(10)), $start);
                } else {
                    $start += 4;
                    $end = strpos($hub_page, ('"' . chr(10)), $start);
                }
                $start += strlen($key);
                $game_info[$key] = stripslashes(str_replace("\\n", "<br>", substr($hub_page, $start, $end - $start)));
            }
        }
        return $game_info;
    }
?>

Posted by Tiberath (Guildmaster) on Monday, December 17, 2007 09:48PM - 3 comments / Members say: yea +0, nay -0
(Edited on Monday, December 17, 2007 09:53PM)

PHP -> PHP Communication Function

This function is used to communicate with a PHP script on another webserver.

function export($addr, $extra_dir, $get_data = '')
{
        if(!$addr) error('export(), ' . __LINE__ . ': No server address provided');
        $fp = fsockopen($addr, 80);
        if(isset($get_data) && !is_null($get_data)) $extra_dir .= "?{$get_data}";
        if($fp)
        {
                $out = "GET /{$extra_dir} HTTP/1.1\r\n";
                $out .= "Host: {$addr}\r\n";
                $out .= "Connection: Close\r\n\r\n";
                fwrite($fp, $out);
                fclose($fp);
        }
}


$addr is a simple subdomain + domain.
$extra_dir is any directories added on to the domain.
$get_data is any GET data you'd like to pass.

Example:

I have a script at http://www.sineful.com/my_scripts/script.php, and I want to pass it "action=reload&data=1"

export('www.sineful.com', 'my_scripts/script.php', 'action=reload&data=1');

Posted by Audeuro (Guildmaster) on Friday, July 27, 2007 11:03PM - 0 comments / Members say: yea +0, nay -0
(Edited on Thursday, September 20, 2007 08:13PM)

PHP -> DM Communication Function

This is a function to make PHP communicate with DM, courtesy of Mobius Evalon and Crispy!

function export($addr,$port,$str)
{
    if($str{0} != "?") $str = ("?" . $str);
    $query = "\x00\x83" . pack("n",strlen($str)+6) . "\x00\x00\x00\x00\x00" . $str . "\x00";
    $server = socket_create(AF_INET,SOCK_STREAM,SOL_TCP) or exit('Unable to create export socket; ' . socket_strerror(socket_last_error()));
    socket_connect($server,$addr,$port) or exit('Unable to establish socket connection; ' . socket_strerror(socket_last_error()));
    $bytessent = 0;
    while($bytessent < strlen($query))
    {
        $result = socket_write($server,substr($query,$bytessent),strlen($query)-$bytessent);
        if($result === FALSE) exit('Unable to transfer requested data; ' . socket_strerror(socket_last_error()));
        $bytessent += $result;
    }
    socket_close($server);
}


And for an example:

export("127.0.0.1",1766,"dothisaction");


This will send 127.0.0.1:1766 a message saying "dothisaction," which it will receive via world/Topic.

Posted by Audeuro (Guildmaster) on Friday, July 27, 2007 10:44PM - 0 comments / Members say: yea +0, nay -0

 

 

Blog Calendar

March 2008
Su Mo Tu We Th Fr Sa
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
«Feb  

My favorite blogs

Blog Keywords