From e600aa0c4338fd5fea7093d674d163098359f357 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Tue, 17 Apr 2018 10:39:55 +0200 Subject: [PATCH] Bugfixes to server, logging and serialization --- server.php | 2 +- src/danog/MadelineProto/FileCallback.php | 3 +- src/danog/MadelineProto/MTProto.php | 1 + .../MadelineProto/MTProtoTools/Files.php | 5 +- src/danog/MadelineProto/Serialization.php | 10 ++++ src/danog/MadelineProto/Server/Handler.php | 54 ++++++++++--------- src/danog/MadelineProto/TL/TL.php | 5 ++ src/danog/MadelineProto/Wrappers/Noop.php | 24 +++++++++ 8 files changed, 77 insertions(+), 27 deletions(-) create mode 100644 src/danog/MadelineProto/Wrappers/Noop.php diff --git a/server.php b/server.php index da1c1c48..d2c5da4c 100644 --- a/server.php +++ b/server.php @@ -2,5 +2,5 @@ require 'vendor/autoload.php'; -$handler = new \danog\MadelineProto\Server(['type' => AF_INET, 'protocol' => 0, 'address' => 'localhost', 'port' => 8011]); +$handler = new \danog\MadelineProto\Server(['type' => AF_INET, 'protocol' => 0, 'address' => 'localhost', 'port' => 8002]); $handler->start(); diff --git a/src/danog/MadelineProto/FileCallback.php b/src/danog/MadelineProto/FileCallback.php index 9d8f6fbe..f5611bf7 100644 --- a/src/danog/MadelineProto/FileCallback.php +++ b/src/danog/MadelineProto/FileCallback.php @@ -31,6 +31,7 @@ class FileCallback implements FileCallbackInterface public function __invoke($percent) { - $this->callback($percent); + $callback = $this->callback; + $callback($percent); } } diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index b4d8abb6..60fccdde 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -48,6 +48,7 @@ class MTProto use \danog\MadelineProto\Wrappers\Callback; use \danog\MadelineProto\Wrappers\Login; use \danog\MadelineProto\Wrappers\Loop; + use \danog\MadelineProto\Wrappers\Noop; use \danog\MadelineProto\Wrappers\Start; use \danog\MadelineProto\Wrappers\Templates; diff --git a/src/danog/MadelineProto/MTProtoTools/Files.php b/src/danog/MadelineProto/MTProtoTools/Files.php index f86c8d94..2eaedfef 100644 --- a/src/danog/MadelineProto/MTProtoTools/Files.php +++ b/src/danog/MadelineProto/MTProtoTools/Files.php @@ -20,7 +20,10 @@ trait Files { public function upload($file, $file_name = '', $cb = null, $encrypted = false, $datacenter = null) { - if (is_object($file) && class_implements($file)['\danog\MadelineProto\FileCallbackInterface']) { + if (is_object($file)) { + if (!isset(class_implements($file)['danog\MadelineProto\FileCallbackInterface'])) { + throw new \danog\MadelineProto\Exception('Provided object does not implement FileCallbackInterface'); + } $cb = $file; $file = $file->getFile(); } diff --git a/src/danog/MadelineProto/Serialization.php b/src/danog/MadelineProto/Serialization.php index ac782d41..cf863424 100644 --- a/src/danog/MadelineProto/Serialization.php +++ b/src/danog/MadelineProto/Serialization.php @@ -71,9 +71,19 @@ class Serialization \danog\MadelineProto\Logger::log('Lock acquired, serializing'); try { + $update_closure = $instance->API->settings['updates']['callback']; + if ($instance->API->settings['updates']['callback'] instanceof \Closure) { + $instance->API->settings['updates']['callback'] = [$instance->API, 'noop']; + } + $logger_closure = $instance->API->settings['logger']['logger_param']; + if ($instance->API->settings['logger']['logger_param'] instanceof \Closure) { + $instance->API->settings['logger']['logger_param'] = [$instance->API, 'noop']; + } $wrote = file_put_contents($realpaths['tempfile'], serialize($instance)); rename($realpaths['tempfile'], $realpaths['file']); } finally { + $instance->API->settings['updates']['callback'] = $update_closure; + $instance->API->settings['logger']['logger_param'] = $logger_closure; flock($realpaths['lockfile'], LOCK_UN); fclose($realpaths['lockfile']); } diff --git a/src/danog/MadelineProto/Server/Handler.php b/src/danog/MadelineProto/Server/Handler.php index 8459f7ae..547f7de4 100644 --- a/src/danog/MadelineProto/Server/Handler.php +++ b/src/danog/MadelineProto/Server/Handler.php @@ -48,7 +48,7 @@ class Handler extends \danog\MadelineProto\Connection public function destruct_madeline() { - if ($this->madeline !== null) { + if (isset($this->madeline) && $this->madeline !== null) { $this->madeline->API->settings['logger'] = ['logger' => 0, 'logger_param' => '']; $this->madeline->API->settings['updates']['callback'] = []; unset($this->madeline); @@ -154,28 +154,8 @@ class Handler extends \danog\MadelineProto\Connection if ($this->madeline === null) { throw new \danog\MadelineProto\Exception('__construct was not called'); } - array_walk_recursive($args, function (&$arg, $zis) { - if (is_array($arg) && isset($arg['_'])) { - if ($arg['_'] === 'fileCallback' && isset($arg['callback']) && isset($arg['file']) && !method_exists($zis, $arg['callback']['callback'])) { - if (isset($arg['file']['_']) && $arg['file']['_'] === 'stream') { - $arg['file'] = fopen('madelineSocket://', 'r+b', false, Stream::getContext($zis, $arg['file']['stream_id'])); - } - $arg = new \danog\MadelineProto\FileCallback($arg['file'], [$zis, $arg['callback']['callback']]); - return; - } - if ($arg['_'] === 'callback' && isset($arg['callback']) && !method_exists($zis, $arg['callback'])) { - $arg = [$zis, $arg['callback']]; - - return; - } - if ($arg['_'] === 'stream' && isset($arg['stream_id'])) { - $arg = fopen('madelineSocket://', 'r+b', false, Stream::getContext($zis, $arg['stream_id'])); - - return; - } - } - }, $this); + array_walk($args, [$this, 'walker']); if (count($method) === 1) { return $this->madeline->{$method[0]}(...$args); @@ -185,8 +165,34 @@ class Handler extends \danog\MadelineProto\Connection } } + private function walker(&$arg) { + if (is_array($arg)) { + if (isset($arg['_'])) { + if ($arg['_'] === 'fileCallback' && isset($arg['callback']) && isset($arg['file']) && !method_exists($this, $arg['callback']['callback'])) { + if (isset($arg['file']['_']) && $arg['file']['_'] === 'stream') { + $arg['file'] = fopen('madelineSocket://', 'r+b', false, Stream::getContext($this, $arg['file']['stream_id'])); + } + $arg = new \danog\MadelineProto\FileCallback($arg['file'], [$this, $arg['callback']['callback']]); + return; + } else if ($arg['_'] === 'callback' && isset($arg['callback']) && !method_exists($this, $arg['callback'])) { + $arg = [$this, $arg['callback']]; + + return; + } else if ($arg['_'] === 'stream' && isset($arg['stream_id'])) { + $arg = fopen('madelineSocket://', 'r+b', false, Stream::getContext($this, $arg['stream_id'])); + return; + } else { + array_walk($arg, [$this, 'walker']); + } + } else { + array_walk($arg, [$this, 'walker']); + } + } + } + public function send_exception($request_id, $e) { + echo $e.PHP_EOL; if ($e instanceof \danog\MadelineProto\RPCErrorException) { $exception = ['_' => 'socketRPCErrorException']; if ($e->getMessage() === $e->rpc) { @@ -209,7 +215,7 @@ class Handler extends \danog\MadelineProto\Connection $tl_frame = ['_' => 'socketTLFrame']; if (isset($frame['function']) && in_array($frame['function'], ['serialize_params', 'serialize_object'])) { if ($frame['args'][2] !== '') { - $tl_frame['tl_param'] = $frame['args'][2]; + $tl_frame['tl_param'] = (string) $frame['args'][2]; $tl = true; } } else { @@ -284,6 +290,6 @@ class Handler extends \danog\MadelineProto\Connection public function __call($method, $args) { - $this->send_message_safe($this->serialize_object(['type' => ''], ['_' => 'socketMessageRequest', 'request_id' => 0, 'method' => $method, 'args' => $args], 'method')); + $this->send_message_safe($this->serialize_object(['type' => ''], ['_' => 'socketMessageRequest', 'request_id' => 0, 'method' => [$method], 'args' => $args], 'method')); } } diff --git a/src/danog/MadelineProto/TL/TL.php b/src/danog/MadelineProto/TL/TL.php index 1d54168b..5e1630ab 100644 --- a/src/danog/MadelineProto/TL/TL.php +++ b/src/danog/MadelineProto/TL/TL.php @@ -503,6 +503,11 @@ trait TL if (in_array($current_argument['type'], ['DataJSON', '%DataJSON'])) { $arguments[$current_argument['name']] = ['_' => 'dataJSON', 'data' => json_encode($arguments[$current_argument['name']])]; } + + if (isset($current_argument['subtype']) && in_array($current_argument['subtype'], ['DataJSON', '%DataJSON'])) { + array_walk($arguments[$current_argument['name']], function (&$arg) { $arg = ['_' => 'dataJSON', 'data' => json_encode($arg)]; }); + } + if (!is_array($arguments[$current_argument['name']]) && $current_argument['type'] === 'InputFile' && $this->settings['upload']['allow_automatic_upload']) { $arguments[$current_argument['name']] = $this->upload($arguments[$current_argument['name']]); } diff --git a/src/danog/MadelineProto/Wrappers/Noop.php b/src/danog/MadelineProto/Wrappers/Noop.php new file mode 100644 index 00000000..408abda9 --- /dev/null +++ b/src/danog/MadelineProto/Wrappers/Noop.php @@ -0,0 +1,24 @@ +. +*/ + +namespace danog\MadelineProto\Wrappers; + +trait Noop +{ + public function setNoop() + { + $this->settings['updates']['callback'] = [$this, 'noop']; + $this->settings['updates']['handle_updates'] = true; + } + public function noop() {} +}