Files
overwatch/Ov3rw4tch.class.php

251 lines
6.9 KiB
PHP

<?php
/**
* ../overwatch/Ov3rw4tch.class.php
* Overwatchd
* @package default
*/
define("OVERWATCH_ROOT", dirname(__FILE__));
define("OVERWATCH_LIBRARIES", OVERWATCH_ROOT."/lib");
define("OVERWATCH_MODULES", OVERWATCH_LIBRARIES."/modules/");
// Load in module support and required classes.
require_once "vendor/autoload.php";
require_once OVERWATCH_LIBRARIES."/libModOverwatch.class.php";
require_once OVERWATCH_LIBRARIES."/libOverwatchAPI.class.php";
require_once OVERWATCH_LIBRARIES."/libAPIQL.class.php";
use Noodlehaus\Config;
echo PHP_EOL;
#error_reporting(0);
$quit = 0;
$arrOverwatch_Config = array();
$arrOverwatch_SystemConfig = array();
$application_channel = "release";
// Load version information from built-in version file. (used for releases)
$version = file_get_contents(OVERWATCH_ROOT."/build/version");
// Define engine version so that plugins can check against it.
// We will want to define the local version information (built into the phar if compiled)
// rather than the git version, unless there's a decent way to compare versions provided by git describe.
define("OVERWATCH_VERSION", $version);
// Load (or override local) version information using git repository.
if (file_exists(".git")) {
$version = `git describe`;
$application_channel = "dev";
}
// Load the core version from the phar if we're running compiled.
$coreversion = file_get_contents(OVERWATCH_ROOT."/build/core-version");
// Now we'll define the core version of the software as well.
$version = str_replace(PHP_EOL, "", $version);
LogEcho("Overwatchd startup, version: $version (built from: $coreversion), channel: $application_channel", "OVERWATCH");
/**
* Allows a "pretty-print" style output.
* @param mixed $str Log message.
* @param mixed $level Log level or specific part of application.
*/
function LogEcho($str, $level) {
$str = str_replace(PHP_EOL, "", $str);
$level = str_replace(PHP_EOL, "", $level);
echo "[$level] $str".PHP_EOL;
}
LogEcho("Loading built-in API Modules...", "OVERWATCH");
LoadAPIModules(OVERWATCH_MODULES);
// We look for a system-wide configuration file for the daemon in /etc. If one is not available,
// we then skip it.
if(file_exists(__FILE__."/overwatchd.conf.dist"))
{
$configFiles = array(__FILE__."/overwatchd.conf.dist");
}
if(file_exists("/etc/overwatchd.conf"))
{
array_push($configFiles,"/etc/overwatchd.conf");
}
if(file_exists(__FILE__."/overwatchd.conf"))
{
array_push($configFiles,__FILE__."/overwatchd.conf");
}
if(isset($configFiles))
{
$arrOverwatch_Config = new Config($configFiles);
}
// We're now looking for a local configuration file for the daemon.
// Allow turning on debug mode from a configuration option.
if(array_key_exists("DEBUG",$arrOverwatch_Config) OR $application_channel == "dev")
{
if($arrOverwatch_Config['DEBUG'] == "true")
{
define("DEBUG",true);
LogEcho("Enabling debug mode due to configuration flag..", "DEBUG");
} elseif ($application_channel == "dev")
{
define("DEBUG", true);
LogEcho("We're running under the dev channel. Debug Ahoy!", "DEBUG");
}
}
LoadModulesFromConfiguration();
$state = array();
// We're going to register a shutdown command so that we can easily shutdown the system remotely,
// only when we're in debug mode though. We'll also turn on PHP's error messages.
if(defined("DEBUG"))
{
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
apiql::register("!SHUTDOWN", "Shutdown");
$quit == 2;
} else {
error_reporting(0);
}
// Let's set up the event loop
$loop = React\EventLoop\Factory::create();
// Now that the rest is set up, let's start the actual server.
$socket = new React\Socket\Server($loop);
$clients = new SplObjectStorage();
$i = 0;
$socket->on('connection', function($connection) use ($clients, &$i) {
$connection->id = ++$i;
// Socket Listener
$connection->on('data', function($message) use ($clients, $connection) {
$connection->lastAPI = str_replace(array("\n", "\r\n", "\r"), '', $message);
if ( base64_encode(base64_decode($connection->lastAPI, true)) === $connection->lastAPI){
if(DEBUG)
{
LogEcho("Raw data from conection: $connection->id, $connection->lastAPI","S2S-COMMS-DEBUG");
}
$connection->lastAPI = base64_decode($connection->lastAPI);
}
if(strtoupper($connection->lastAPI) != strtoupper("shutdown"))
{
$connection->lastAPI = str_replace("'", "\"", $connection->lastAPI);
# Let's pull apart the current request to check for a connection-id item. If it doesn't exist, we'll inject it in.
$command = explode ("{", $connection->lastAPI, 2);
$commandJSON = json_decode("{".$command[1], true);
if(!isset($commandJSON['connection-id']))
{
$commandJSON['connection-id'] = $connection->id;
$commandJSON = json_encode($commandJSON);
$connection->lastAPI = rtrim($command[0]," ")." ".$commandJSON;
}
} else {
}
$connection->lastResult = apicall($connection->lastAPI);
LogEcho("Received query: ".$connection->lastAPI." from ".$connection->id, "SOCKET-API");
foreach ($clients as $client) {
if ($client->id == $connection->id) {
if($connection->lastResult != NULL)
{
$client->write($connection->lastResult."\r\n");
}
} else {
continue;
}
}
});
$clients->attach($connection);
});
if (empty($arrOverwatch_Config['API_PORT'])) {
$API_PORT="1337";
} else {
$API_PORT= $arrOverwatch_Config['API_PORT'];
}
// Start listening on the configured port.
$socket->listen($API_PORT, "0.0.0.0");
LogEcho("Server listening on port: $API_PORT", "OVERWATCH");
// Now we begin the actual event loop.
$loop->run();
/**
*
* @return unknown
*/
function Shutdown() {
global $quit;
global $loop;
$loop->stop();
$quit = 1;
return "Shutting Down.";
exit(0);
}
/**
*
* @param unknown $call
* @param unknown $apiKey (optional)
* @return unknown
*/
function APIcall($call, $apiKey = null) {
#LogEcho("APIcall($call)","S2S-DEBUG");
$APIResponse = apiql::query($call);
if ($APIResponse == NULL) {
$ResponseArray = array('response_type'=>"error",
'response_data'=>array('type'=>'APIcall',
'data'=>$call,
'response'=>$APIResponse),
'response_code'=>'OVW_404');
return "ERROR ".json_encode($ResponseArray);
} else {
if(empty($APIResponse) or $APIResponse == "1")
{
return NULL;
}
return $APIResponse;
}
}
function LoadModulesFromConfiguration()
{
global $arrOverwatch_Config;
if(array_key_exists("MODULES_DIR", $arrOverwatch_Config))
{
LogEcho("External module directory defined, loading external modules...","OVERWATCH");
LoadAPIModules($arrOverwatch_Config['MODULES_DIR']);
}
if(array_key_exists("SYSTEM_MODULES_DIR", $arrOverwatch_Config))
{
LogEcho("Loading modules from system store: ".$arrOverwatch_Config['SYSTEM_MODULES_DIR']);
LoadAPIModules($arrOverwatch_Config['SYSTEM_MODULES_DIR']);
}
}
function is_json($json)
{
json_decode($json);
return (json_last_error() == JSON_ERROR_NONE);
}
?>