Finish impl

This commit is contained in:
Daniil Gentili 2019-12-17 13:10:30 +01:00
parent ee99686d97
commit 791d6b6b43
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
5 changed files with 47 additions and 24 deletions

View File

@ -19,6 +19,7 @@
namespace danog\MadelineProto\TON; namespace danog\MadelineProto\TON;
use Amp\Deferred;
use Amp\Socket\ConnectContext; use Amp\Socket\ConnectContext;
use danog\MadelineProto\Magic; use danog\MadelineProto\Magic;
use danog\MadelineProto\MTProtoTools\Crypt; use danog\MadelineProto\MTProtoTools\Crypt;
@ -27,10 +28,10 @@ use danog\MadelineProto\Stream\Common\BufferedRawStream;
use danog\MadelineProto\Stream\Common\CtrStream; use danog\MadelineProto\Stream\Common\CtrStream;
use danog\MadelineProto\Stream\Common\HashedBufferedStream; use danog\MadelineProto\Stream\Common\HashedBufferedStream;
use danog\MadelineProto\Stream\ConnectionContext; use danog\MadelineProto\Stream\ConnectionContext;
use danog\MadelineProto\Stream\MTProtoTransport\ObfuscatedStream;
use danog\MadelineProto\Stream\Transport\DefaultStream; use danog\MadelineProto\Stream\Transport\DefaultStream;
use danog\MadelineProto\TL\TL; use danog\MadelineProto\TL\TL;
use danog\MadelineProto\Tools; use danog\MadelineProto\Tools;
use Exception;
use phpseclib3\Crypt\DH; use phpseclib3\Crypt\DH;
use phpseclib3\Crypt\EC; use phpseclib3\Crypt\EC;
use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Curve25519;
@ -52,6 +53,12 @@ class ADNLConnection
* @var StreamInterface * @var StreamInterface
*/ */
private $stream; private $stream;
/**
* Request list.
*
* @var array
*/
private $requests = [];
/** /**
* Construct class. * Construct class.
* *
@ -98,25 +105,25 @@ class ADNLConnection
$private = EC::createKey('Ed25519'); $private = EC::createKey('Ed25519');
$public = $private->getPublicKey(); $public = $private->getPublicKey();
$public = strrev(Tools::getVar($public, 'QA')[1]->toBytes()); $public = \strrev(Tools::getVar($public, 'QA')[1]->toBytes());
$private = strrev(Tools::getVar($private, 'dA')->toBytes()); $private = \strrev(Tools::getVar($private, 'dA')->toBytes());
$private = PrivateKey::loadFormat('MontgomeryPrivate', $private); $private = PrivateKey::loadFormat('MontgomeryPrivate', $private);
// Transpose their public // Transpose their public
$key = $endpoint['id']['key']; $key = $endpoint['id']['key'];
$key[31] = $key[31] & chr(127); $key[31] = $key[31] & \chr(127);
$curve = new Curve25519; $curve = new Curve25519;
$modulo = Tools::getVar($curve, "modulo"); $modulo = Tools::getVar($curve, "modulo");
$y = new BigInteger(strrev($key), 256); $y = new BigInteger(\strrev($key), 256);
$y2 = clone $y; $y2 = clone $y;
$y = $y->add(Magic::$one); $y = $y->add(Magic::$one);
$y2 = $y2->subtract(Magic::$one); $y2 = $y2->subtract(Magic::$one);
$y2 = $modulo->subtract($y2)->powMod(Magic::$one, $modulo); $y2 = $modulo->subtract($y2)->powMod(Magic::$one, $modulo);
$y2 = $y2->modInverse($modulo); $y2 = $y2->modInverse($modulo);
$key = strrev($y->multiply($y2)->powMod(Magic::$one, $modulo)->toBytes()); $key = \strrev($y->multiply($y2)->powMod(Magic::$one, $modulo)->toBytes());
$peerPublic = PublicKey::loadFormat('MontgomeryPublic', $key); $peerPublic = PublicKey::loadFormat('MontgomeryPublic', $key);
// Generate secret // Generate secret
@ -153,35 +160,37 @@ class ADNLConnection
//yield Tools::sleep(1); //yield Tools::sleep(1);
while (true) { while (true) {
$buffer = yield $this->stream->getReadBuffer($length); $buffer = yield $this->stream->getReadBuffer($length);
\var_dump($length, "GOT PACKET WITH LENGTH $length");
if ($length) { if ($length) {
\var_dump($length, yield $buffer->bufferRead($length)); $data = yield $buffer->bufferRead($length);
$data = yield $this->TL->deserialize($data);
if ($data['_'] !== 'adnl.message.answer') {
throw new Exception('Wrong answer type: '.$data['_']);
}
$this->requests[$data['query_id']]->resolve(yield $this->TL->deserialize((string) $data['answer']));
} }
} }
})()); })());
} }
/** /**
* Send TL payload. * Send ADNL query.
* *
* @param array $payload Payload to send * @param string $payload Payload to send
* *
* @return \Generator * @return \Generator
*/ */
public function send(array $payload): \Generator public function query(string $payload): \Generator
{ {
var_dumP("Sending moar");
$data = yield $this->TL->serializeMethod($payload['_'], $payload);
$data = yield $this->TL->serializeObject( $data = yield $this->TL->serializeObject(
['type' => ''], ['type' => ''],
[ [
'_' => 'adnl.message.query', '_' => 'adnl.message.query',
'query_id' => Tools::random(32), 'query_id' => $id = Tools::random(32),
'query' => $data 'query' => $payload
], ],
'' ''
); );
var_dump(unpack('V*', $data));
(yield $this->stream->getWriteBuffer(\strlen($data)))->bufferWrite($data); (yield $this->stream->getWriteBuffer(\strlen($data)))->bufferWrite($data);
return ($this->requests[$id] = new Deferred)->promise();
} }
} }

View File

@ -39,5 +39,8 @@ class API extends InternalDoc
foreach (\get_class_methods($this->API) as $method) { foreach (\get_class_methods($this->API) as $method) {
$this->methods[$method] = [$this->API, \strtolower($method)]; $this->methods[$method] = [$this->API, \strtolower($method)];
} }
foreach ($this->API->getMethodNamespaces() as $namespace) {
$this->{$namespace} = new APIFactory($namespace, $this->API, $this->async);
}
} }
} }

View File

@ -95,7 +95,7 @@ class APIFactory extends AbstractAPIFactory
$aargs['apifactory'] = true; $aargs['apifactory'] = true;
$args = isset($arguments[0]) && \is_array($arguments[0]) ? $arguments[0] : []; $args = isset($arguments[0]) && \is_array($arguments[0]) ? $arguments[0] : [];
return $this->API->methodCallAsyncRead($name, $args, $aargs); return $this->API->methodCall($name, $args, $aargs);
} }
return $this->methods[$lower_name](...$arguments); return $this->methods[$lower_name](...$arguments);
} }

View File

@ -102,13 +102,13 @@ class Lite
foreach ($this->config['liteservers'] as $lite) { foreach ($this->config['liteservers'] as $lite) {
$this->connections[] = $connection = new ADNLConnection($this->TL); $this->connections[] = $connection = new ADNLConnection($this->TL);
yield $connection->connect($lite); yield $connection->connect($lite);
yield $connection->send(
[
'_' => 'liteServer.getTime'
]
);
} }
yield Tools::sleep(10); }
public function methodCall(string $methodName, array $args = [], array $aargs = []) {
$data = yield $this->TL->serializeMethod($methodName, $args);
$data = yield $this->TL->serializeMethod('liteServer.query', ['data' => $data]);
return yield $this->connections[rand(0, count($this->connections) - 1)]->query($data);
} }
/** /**
@ -134,4 +134,14 @@ class Lite
{ {
return $parameters; return $parameters;
} }
/**
* Get TL method namespaces
*
* @return void
*/
public function getMethodNamespaces()
{
return $this->TL->getMethodNamespaces();
}
} }

View File

@ -17,5 +17,6 @@ $API->async(true);
$API->loop( $API->loop(
function () use ($API) { function () use ($API) {
yield $API->connect(__DIR__.'/ton-lite-client-test1.config.json'); yield $API->connect(__DIR__.'/ton-lite-client-test1.config.json');
var_dump(yield $API->liteServer->getTime());
} }
); );