167 lines
3.5 KiB
PHP
167 lines
3.5 KiB
PHP
|
<?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);
|