Initial commit

This commit is contained in:
Mikko Ahlroth 2013-09-28 22:14:52 +03:00
commit 80503205b0
5 changed files with 288 additions and 0 deletions

48
main.php Normal file
View file

@ -0,0 +1,48 @@
<?php
declare(ticks = 1);
const PLUGIN_DIR = 'plugins';
// All IO streams
$_iostreams = [];
// All activated plugins
$_plugins = [];
$_started = false;
$_reload = function()
{
static $require_reload = false;
if (!func_num_args())
{
$ret = $require_reload;
$require_reload = false;
return $ret;
}
else
{
$require_reload = $require_reload || func_get_arg(0);
}
};
// Available plugin hooks:
// onconnect
// oninput
// onoutput
// ondisconnect
// onload
// onforget
require 'utils.php';
$_load_code();
$_started = true;
while (true)
{
$_loop();
echo 'Executing scheduled reload...', PHP_EOL;
$_forget_code();
$_load_code();
}

31
plugins/0001_echoer.php Normal file
View file

@ -0,0 +1,31 @@
<?php
$_plugins['onload'][] = function()
{
echo 'Echoer loaded!', PHP_EOL;
};
$_plugins['onforget'][] = function()
{
echo 'Echoer being forgotten!', PHP_EOL;
};
$_plugins['oninput'][] = function($id, $input)
{
echo '[', $id, '] -> ', $input, PHP_EOL;
};
$_plugins['onoutput'][] = function($id, $output)
{
echo '[', $id, '] <- ', rtrim($output), PHP_EOL;
};
$_plugins['onconnect'][] = function($id, $host, $port)
{
echo 'Connected to ', $host, ':', $port, ' as ', $id, '.', PHP_EOL;
};
$_plugins['ondisconnect'][] = function($id)
{
echo 'Disconnecting from ', $id, '...', PHP_EOL;
};

34
plugins/0020_autojoin.php Normal file
View file

@ -0,0 +1,34 @@
<?php
$_autojoin_servers =
[
['irc.quakenet.org', 6667],
//['irc.cc.tut.fi', 6667]
];
$_user_info =
[
'nick' => 'BaseT',
'altnick' => 'AltBase',
'username' => 'baset',
'realname' => '10/100Base-T Ports'
];
// No need for & since this will only be run at start
$_plugins['onload'][] = function() use ($_autojoin_servers, $_started, $_connect)
{
if (!$_started)
{
foreach ($_autojoin_servers as $server)
{
$_connect($server[0], $server[1]);
}
}
};
$_plugins['onconnect'][] = function($id, $host, $port) use (&$_write, &$_user_info)
{
$_write($id, sprintf("NICK %s\r\n", $_user_info['nick']));
$_write($id, sprintf("USER %s 8 * :%s\r\n", $_user_info['username'],
$_user_info['realname']));
};

View file

@ -0,0 +1,9 @@
<?php
$_plugins['oninput'][] = function($id, $input) use (&$_write)
{
if (substr($input, 0, 4) === 'PING')
{
$_write($id, 'PONG :' . substr($input, 6) . "\r\n");
}
};

166
utils.php Normal file
View file

@ -0,0 +1,166 @@
<?php
$_stream_fwrite = function($fp, $string) {
for ($written = 0; $written < strlen($string); $written += $fwrite) {
$fwrite = fwrite($fp, substr($string, $written));
if ($fwrite === false) {
return $written;
}
}
return $written;
};
$_trigger = function($type, $args) use (&$_plugins)
{
if (!isset($_plugins[$type])) return;
foreach ($_plugins[$type] as $plugin)
{
call_user_func_array($plugin, $args);
}
};
// Events
$_on_connect = function($id, $host, $port) use (&$_trigger)
{
$_trigger('onconnect', [$id, $host, $port]);
};
$_on_disconnect = function($id) use (&$_trigger)
{
$_trigger('ondisconnect', [$id]);
};
$_on_input = function($id, $input) use (&$_trigger)
{
$_trigger('oninput', [$id, $input]);
};
$_on_output = function($id, $output) use (&$_trigger)
{
$_trigger('onoutput', [$id, $output]);
};
$_on_load = function() use (&$_trigger)
{
$_trigger('onload', []);
};
$_on_forget = function() use (&$_trigger)
{
$_trigger('onforget', []);
};
$_load_code = function() use (&$_iostreams, &$_plugins, &$_on_connect,
&$_on_disconnect, &$_on_input, &$_on_load,
&$_on_forget, &$_started, &$_reload)
{
// Reload functions from utils.php
require 'utils.php';
$files = scandir(PLUGIN_DIR, SCANDIR_SORT_ASCENDING);
foreach ($files as $file)
{
if ($file != '.' && $file != '..')
include PLUGIN_DIR . '/' . $file;
}
$_on_load();
};
$_forget_code = function() use (&$_plugins, &$_on_forget)
{
$_on_forget();
$_plugins = [];
};
$_connect = function($host, $port) use (&$_iostreams, &$_on_connect)
{
$sock = fsockopen($host, $port);
stream_set_blocking($sock, 0);
$_iostreams[] = $sock;
$newid = 0;
foreach ($_iostreams as $id => $stream)
{
if ($stream === $sock)
{
$newid = $id;
}
}
$_on_connect($newid, $host, $port);
};
$_disconnect = function($id) use (&$_iostreams, &$_on_disconnect)
{
$_on_disconnect($id);
fclose($_iostreams[$id]);
unset($_iostreams[$id]);
};
$_write = function($id, $output) use (&$_iostreams, &$_stream_fwrite, &$_on_output)
{
$_on_output($id, $output);
$_stream_fwrite($_iostreams[$id], $output);
};
$_loop = function() use (&$_iostreams, &$_plugins, &$_disconnect, &$_on_input, &$_reload)
{
while (true)
{
if ($_reload()) return;
if (count($_iostreams) == 0) exit;
$r = $_iostreams;
$w = [];
$e = [];
@stream_select($r, $w, $e, null);
foreach ($r as $instream)
{
$inid = 0;
foreach ($_iostreams as $id => $stream)
{
if ($stream === $instream)
{
$inid = $id;
}
}
if (feof($instream))
{
$_disconnect($inid);
}
else
{
$read = [];
while (true)
{
$line = rtrim(fgets($instream));
if ($line == '') break;
$read[] = $line;
}
foreach ($read as $line)
{
$_on_input($inid, $line);
}
}
}
}
};
// Reload code when appropriate signal is received
$_sig_handler = function($signo) use (&$_reload)
{
echo 'Got SIGUSR1, scheduling reload...', PHP_EOL;
$_reload(true);
};
pcntl_signal(SIGUSR1, $_sig_handler);