Start cleaning up repo

This commit is contained in:
Daniil Gentili 2019-10-28 19:48:59 +01:00
parent 579dfe3563
commit e81ecc87c9
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
20 changed files with 156 additions and 547 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "docs"]
path = docs
url = https://github.com/danog/MadelineProtoDocs
[submodule "userbots/magnaluna"]
path = userbots/magnaluna
url = https://github.com/danog/magnaluna

View File

@ -5,7 +5,7 @@ $config->getFinder()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests')
->in(__DIR__ . '/userbots')
->name(__DIR__ . '/*.php');
->in(__DIR__);
$cacheDir = getenv('TRAVIS') ? getenv('HOME') . '/.php-cs-fixer' : __DIR__;

View File

@ -2,35 +2,35 @@
$not_subbing = [];
foreach (explode("\n", shell_exec("find src -type f -name '*.php'")) as $file) {
foreach (\explode("\n", \shell_exec("find src -type f -name '*.php'")) as $file) {
if (!$file) {
continue;
}
if (in_array(basename($file, '.php'), ['APIFactory', 'API', 'Connection', 'Coroutine', 'ReferenceDatabase', 'ProxySocketPool'])) {
if (\in_array(\basename($file, '.php'), ['APIFactory', 'API', 'Connection', 'Coroutine', 'ReferenceDatabase', 'ProxySocketPool'])) {
continue;
}
if (strpos($file, 'Loop/')) {
if (\strpos($file, 'Loop/')) {
continue;
}
if (strpos($file, 'Stream/')) {
if (\strpos($file, 'Stream/')) {
continue;
}
if (strpos($file, 'Server/')) {
if (\strpos($file, 'Server/')) {
continue;
}
if (strpos($file, 'Async/')) {
if (\strpos($file, 'Async/')) {
continue;
}
$to_sub = [];
$last_match = null;
foreach (explode("\n", $filec = file_get_contents($file)) as $number => $line) {
if (preg_match("/public function (\w*)[(]/", $line, $matches)) {
$last_match = stripos($matches[1], 'async') === false ? $matches[1] : null;
foreach (\explode("\n", $filec = \file_get_contents($file)) as $number => $line) {
if (\preg_match("/public function (\w*)[(]/", $line, $matches)) {
$last_match = \stripos($matches[1], 'async') === false ? $matches[1] : null;
}
if (preg_match('/function [(]/', $line) && stripos($line, 'public function') === false) {
if (\preg_match('/function [(]/', $line) && \stripos($line, 'public function') === false) {
$last_match = 0;
}
if (strpos($line, 'yield') !== false) {
if (\strpos($line, 'yield') !== false) {
if ($last_match) {
echo "subbing $last_match for $line at $number in $file".PHP_EOL;
$to_sub[] = $last_match;
@ -47,7 +47,7 @@ foreach (explode("\n", shell_exec("find src -type f -name '*.php'")) as $file) {
$output[] = "public function $func".'_async(';
}
if ($input) {
file_put_contents($file, str_replace($input, $output, $filec));
\file_put_contents($file, \str_replace($input, $output, $filec));
}
}
var_dump(array_values($not_subbing));
\var_dump(\array_values($not_subbing));

View File

@ -13,7 +13,6 @@ You should have received a copy of the GNU General Public License along with Mad
If not, see <http://www.gnu.org/licenses/>.
*/
use danog\MadelineProto\Stream\Proxy\SocksProxy;
\set_include_path(\get_include_path().':'.\realpath(\dirname(__FILE__).'/MadelineProto/'));

View File

@ -15,16 +15,16 @@ $param = 1;
\danog\MadelineProto\Logger::constructor($param);
$logger = \danog\MadelineProto\Logger::$default;
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
\set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
\danog\MadelineProto\Logger::log('Copying readme...', \danog\MadelineProto\Logger::NOTICE);
file_put_contents('docs/docs/index.md', '---
\file_put_contents('docs/docs/index.md', '---
title: MadelineProto documentation
description: PHP client/server for the telegram MTProto protocol (a better tg-cli)
image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png
---
'.str_replace('<img', '<amp-img', file_get_contents('README.md')));
'.\str_replace('<img', '<amp-img', \file_get_contents('README.md')));
$docs = [
/* [
@ -52,8 +52,8 @@ $docs = [
];
$layer_list = '';
foreach (array_slice(glob(__DIR__.'/src/danog/MadelineProto/TL_telegram_*'), 0, -1) as $file) {
$layer = preg_replace(['/.*telegram_/', '/\..+/'], '', $file);
foreach (\array_slice(\glob(__DIR__.'/src/danog/MadelineProto/TL_telegram_*'), 0, -1) as $file) {
$layer = \preg_replace(['/.*telegram_/', '/\..+/'], '', $file);
$docs[] = [
'tl_schema' => ['telegram' => $file],
'title' => 'MadelineProto API documentation (layer '.$layer.')',
@ -65,7 +65,7 @@ foreach (array_slice(glob(__DIR__.'/src/danog/MadelineProto/TL_telegram_*'), 0,
';
}
file_put_contents('docs/old_docs/README.md', '---
\file_put_contents('docs/old_docs/README.md', '---
title: Documentations of old mtproto layers
description: Documentation of old mtproto layers
---
@ -81,7 +81,7 @@ foreach ($docs as $settings) {
$doc->mk_docs();
}
chdir(__DIR__);
\chdir(__DIR__);
$orderedfiles = [];
$order = [
@ -110,49 +110,51 @@ $order = [
'TEMPLATES',
];
$index = '';
$files = glob('docs/docs/docs/*md');
$files = \glob('docs/docs/docs/*md');
foreach ($files as $file) {
$base = basename($file, '.md');
if ($base === 'UPDATES_INTERNAL') continue;
$key = array_search($base, $order);
$base = \basename($file, '.md');
if ($base === 'UPDATES_INTERNAL') {
continue;
}
$key = \array_search($base, $order);
if ($key !== false) {
$orderedfiles[$key] = $file;
}
}
ksort($orderedfiles);
\ksort($orderedfiles);
foreach ($orderedfiles as $key => $filename) {
$lines = explode("\n", file_get_contents($filename));
while (end($lines) === '' || strpos(end($lines), 'Next')) {
unset($lines[count($lines) - 1]);
$lines = \explode("\n", \file_get_contents($filename));
while (\end($lines) === '' || \strpos(\end($lines), 'Next')) {
unset($lines[\count($lines) - 1]);
}
if ($lines[0] === '---') {
array_shift($lines);
\array_shift($lines);
while ($lines[0] !== '---') {
array_shift($lines);
\array_shift($lines);
}
array_shift($lines);
\array_shift($lines);
}
preg_match('|^# (.*)|', $lines[0], $matches);
\preg_match('|^# (.*)|', $lines[0], $matches);
$title = $matches[1];
$description = $lines[2];
array_unshift($lines, '---', 'title: '.$title, 'description: '.$description, 'image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png', '---');
\array_unshift($lines, '---', 'title: '.$title, 'description: '.$description, 'image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png', '---');
if (isset($orderedfiles[$key + 1])) {
$nextfile = 'https://docs.madelineproto.xyz/docs/'.basename($orderedfiles[$key + 1], '.md').'.html';
$prevfile = $key === 0 ? 'https://docs.madelineproto.xyz' : 'https://docs.madelineproto.xyz/docs/'.basename($orderedfiles[$key - 1], '.md').'.html';
$lines[count($lines)] = "\n<a href=\"$nextfile\">Next section</a>";
$nextfile = 'https://docs.madelineproto.xyz/docs/'.\basename($orderedfiles[$key + 1], '.md').'.html';
$prevfile = $key === 0 ? 'https://docs.madelineproto.xyz' : 'https://docs.madelineproto.xyz/docs/'.\basename($orderedfiles[$key - 1], '.md').'.html';
$lines[\count($lines)] = "\n<a href=\"$nextfile\">Next section</a>";
} else {
$lines[count($lines)] = "\n<a href=\"https://docs.madelineproto.xyz/#very-complex-and-complete-examples\">Next section</a>";
$lines[\count($lines)] = "\n<a href=\"https://docs.madelineproto.xyz/#very-complex-and-complete-examples\">Next section</a>";
}
file_put_contents($filename, implode("\n", $lines));
\file_put_contents($filename, \implode("\n", $lines));
$file = file_get_contents($filename);
$file = \file_get_contents($filename);
preg_match_all('|( *)\* \[(.*)\]\((.*)\)|', $file, $matches);
$file = 'https://docs.madelineproto.xyz/docs/'.basename($filename, '.md').'.html';
\preg_match_all('|( *)\* \[(.*)\]\((.*)\)|', $file, $matches);
$file = 'https://docs.madelineproto.xyz/docs/'.\basename($filename, '.md').'.html';
$index .= "* [$title]($file)\n";
if (basename($filename) !== 'FEATURES.md') {
if (\basename($filename) !== 'FEATURES.md') {
foreach ($matches[1] as $key => $match) {
$spaces = " $match";
$name = $matches[2][$key];
@ -160,9 +162,9 @@ foreach ($orderedfiles as $key => $filename) {
$index .= "$spaces* [$name]($url)\n";
if ($name === 'FULL API Documentation with descriptions') {
$spaces .= ' ';
preg_match_all('|\* (.*)|', file_get_contents('docs/docs/API_docs/methods/index.md'), $smatches);
\preg_match_all('|\* (.*)|', \file_get_contents('docs/docs/API_docs/methods/index.md'), $smatches);
foreach ($smatches[1] as $key => $match) {
$match = str_replace('href="', 'href="https://docs.madelineproto.xyz/API_docs/methods/', $match);
$match = \str_replace('href="', 'href="https://docs.madelineproto.xyz/API_docs/methods/', $match);
$index .= "$spaces* ".$match."\n";
}
}
@ -170,16 +172,16 @@ foreach ($orderedfiles as $key => $filename) {
}
}
$readme = explode('## ', file_get_contents('README.md'));
$readme = \explode('## ', \file_get_contents('README.md'));
foreach ($readme as &$section) {
if (explode("\n", $section)[0] === 'Documentation') {
if (\explode("\n", $section)[0] === 'Documentation') {
$section = "Documentation\n\n".$index."\n";
}
}
$readme = implode('## ', $readme);
$readme = \implode('## ', $readme);
file_put_contents('README.md', $readme);
file_put_contents('docs/docs/index.md', '---
\file_put_contents('README.md', $readme);
\file_put_contents('docs/docs/index.md', '---
title: MadelineProto documentation
description: PHP client/server for the telegram MTProto protocol (a better tg-cli)
image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png

View File

@ -10,15 +10,15 @@ See the GNU Affero General Public License for more details.
You should have received a copy of the GNU General Public License along with MadelineProto.
If not, see <http://www.gnu.org/licenses/>.
*/
set_include_path(get_include_path().':'.realpath(dirname(__FILE__).'/MadelineProto/'));
\set_include_path(\get_include_path().':'.\realpath(\dirname(__FILE__).'/MadelineProto/'));
/*
* Various ways to load MadelineProto
*/
if (!file_exists(__DIR__.'/vendor/autoload.php')) {
if (!\file_exists(__DIR__.'/vendor/autoload.php')) {
echo 'You did not run composer update, using madeline.php'.PHP_EOL;
if (!file_exists('madeline.php')) {
copy('https://phar.madelineproto.xyz/madeline.php', 'madeline.php');
if (!\file_exists('madeline.php')) {
\copy('https://phar.madelineproto.xyz/madeline.php', 'madeline.php');
}
include 'madeline.php';
} else {
@ -38,9 +38,9 @@ class EventHandler extends \danog\MadelineProto\CombinedEventHandler
yield $MadelineProto->messages->sendMedia(['peer' => $update, 'message' => $update['message']['message'], 'media' => $update]);
}
$res = json_encode($update, JSON_PRETTY_PRINT);
$res = \json_encode($update, JSON_PRETTY_PRINT);
if ($res == '') {
$res = var_export($update, true);
$res = \var_export($update, true);
}
yield $MadelineProto->sleep(3);

BIN
input.raw

Binary file not shown.

View File

@ -19,7 +19,7 @@ $param = 1;
\danog\MadelineProto\Logger::constructor($param);
$logger = \danog\MadelineProto\Logger::$default;
set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
\set_error_handler(['\danog\MadelineProto\Exception', 'ExceptionErrorHandler']);
if ($argc !== 3) {
die("Usage: {$argv[0]} layernumberold layernumbernew\n");
@ -48,7 +48,7 @@ function getTL($layer)
}
function getUrl($constructor, $type)
{
$changed = str_replace('.', '_', $constructor);
$changed = \str_replace('.', '_', $constructor);
//return "[$constructor](https://github.com/danog/MadelineProtoDocs/blob/geochats/docs/API_docs/$type/$changed.md)";
return "[$constructor](https://docs.madelineproto.xyz/API_docs/$type/$changed.html)";
@ -62,7 +62,7 @@ foreach (['methods', 'constructors'] as $type) {
$key = $type === 'methods' ? 'method' : 'predicate';
// New constructors
$res .= "\n\nNew ".ucfirst($type)."\n";
$res .= "\n\nNew ".\ucfirst($type)."\n";
foreach ($new[$type]->by_id as $constructor) {
$name = $constructor[$key];
if (!$old[$type]->$finder($name)) {
@ -72,7 +72,7 @@ foreach (['methods', 'constructors'] as $type) {
}
// Changed constructors
$res .= "\n\nChanged ".ucfirst($type)."\n";
$res .= "\n\nChanged ".\ucfirst($type)."\n";
foreach ($new[$type]->by_id as $constructor) {
$name = $constructor[$key];
$constructor['id'] = $new[$type]->$finder($name)['id'];
@ -103,7 +103,7 @@ foreach (['methods', 'constructors'] as $type) {
}
// Deleted constructors
$res .= "\n\nDeleted ".ucfirst($type)."\n";
$res .= "\n\nDeleted ".\ucfirst($type)."\n";
foreach ($old[$type]->by_id as $constructor) {
$name = $constructor[$key];
if (!$new[$type]->$finder($name)) {

View File

@ -19,17 +19,17 @@ try {
$Lua = \danog\MadelineProto\Serialization::deserialize('bot.madeline');
} catch (\danog\MadelineProto\Exception $e) {
}
if (!is_object($Lua)) {
if (!\is_object($Lua)) {
$MadelineProto = new \danog\MadelineProto\API($settings);
while (!in_array(($res = readline('Do you want to login as a user or as a bot (u/b)? ')), ['u', 'b'])) {
while (!\in_array(($res = \readline('Do you want to login as a user or as a bot (u/b)? ')), ['u', 'b'])) {
echo 'Please write either u or b'.PHP_EOL;
}
switch ($res) {
case 'u':
$sentCode = $MadelineProto->phone_login(readline('Enter your phone number: '));
$sentCode = $MadelineProto->phone_login(\readline('Enter your phone number: '));
\danog\MadelineProto\Logger::log($sentCode, \danog\MadelineProto\Logger::NOTICE);
echo 'Enter the code you received: ';
$code = fgets(STDIN, (isset($sentCode['type']['length']) ? $sentCode['type']['length'] : 5) + 1);
$code = \fgets(STDIN, (isset($sentCode['type']['length']) ? $sentCode['type']['length'] : 5) + 1);
$authorization = $MadelineProto->complete_phone_login($code);
\danog\MadelineProto\Logger::log($authorization, \danog\MadelineProto\Logger::NOTICE);
if ($authorization['_'] === 'account.noPassword') {
@ -37,17 +37,17 @@ if (!is_object($Lua)) {
}
if ($authorization['_'] === 'account.password') {
\danog\MadelineProto\Logger::log('2FA is enabled', \danog\MadelineProto\Logger::NOTICE);
$authorization = $MadelineProto->complete_2fa_login(readline('Please enter your password (hint '.$authorization['hint'].'): '));
$authorization = $MadelineProto->complete_2fa_login(\readline('Please enter your password (hint '.$authorization['hint'].'): '));
}
if ($authorization['_'] === 'account.needSignup') {
\danog\MadelineProto\Logger::log('Registering new user', \danog\MadelineProto\Logger::NOTICE);
$authorization = $MadelineProto->complete_signup(readline('Please enter your first name: '), readline('Please enter your last name (can be empty): '));
$authorization = $MadelineProto->complete_signup(\readline('Please enter your first name: '), \readline('Please enter your last name (can be empty): '));
}
\danog\MadelineProto\Logger::log($authorization, \danog\MadelineProto\Logger::NOTICE);
$Lua = new \danog\MadelineProto\Lua('madeline.lua', $MadelineProto);
break;
case 'b':
$authorization = $MadelineProto->bot_login(readline('Please enter a bot token: '));
$authorization = $MadelineProto->bot_login(\readline('Please enter a bot token: '));
\danog\MadelineProto\Logger::log($authorization, \danog\MadelineProto\Logger::NOTICE);
$Lua = new \danog\MadelineProto\Lua('madeline.lua', $MadelineProto);
break;

View File

@ -19,17 +19,17 @@ try {
$Lua = \danog\MadelineProto\Serialization::deserialize('td.madeline');
} catch (\danog\MadelineProto\Exception $e) {
}
if (!is_object($Lua)) {
if (!\is_object($Lua)) {
$MadelineProto = new \danog\MadelineProto\API($settings);
while (!in_array(($res = readline('Do you want to login as a user or as a bot (u/b)? ')), ['u', 'b'])) {
while (!\in_array(($res = \readline('Do you want to login as a user or as a bot (u/b)? ')), ['u', 'b'])) {
echo 'Please write either u or b'.PHP_EOL;
}
switch ($res) {
case 'u':
$sentCode = $MadelineProto->phone_login(readline('Enter your phone number: '));
$sentCode = $MadelineProto->phone_login(\readline('Enter your phone number: '));
\danog\MadelineProto\Logger::log($sentCode, \danog\MadelineProto\Logger::NOTICE);
echo 'Enter the code you received: ';
$code = fgets(STDIN, (isset($sentCode['type']['length']) ? $sentCode['type']['length'] : 5) + 1);
$code = \fgets(STDIN, (isset($sentCode['type']['length']) ? $sentCode['type']['length'] : 5) + 1);
$authorization = $MadelineProto->complete_phone_login($code);
\danog\MadelineProto\Logger::log($authorization, \danog\MadelineProto\Logger::NOTICE);
if ($authorization['_'] === 'account.noPassword') {
@ -37,17 +37,17 @@ if (!is_object($Lua)) {
}
if ($authorization['_'] === 'account.password') {
\danog\MadelineProto\Logger::log('2FA is enabled', \danog\MadelineProto\Logger::NOTICE);
$authorization = $MadelineProto->complete_2fa_login(readline('Please enter your password (hint '.$authorization['hint'].'): '));
$authorization = $MadelineProto->complete_2fa_login(\readline('Please enter your password (hint '.$authorization['hint'].'): '));
}
if ($authorization['_'] === 'account.needSignup') {
\danog\MadelineProto\Logger::log('Registering new user', \danog\MadelineProto\Logger::NOTICE);
$authorization = $MadelineProto->complete_signup(readline('Please enter your first name: '), readline('Please enter your last name (can be empty): '));
$authorization = $MadelineProto->complete_signup(\readline('Please enter your first name: '), \readline('Please enter your last name (can be empty): '));
}
\danog\MadelineProto\Logger::log($authorization, \danog\MadelineProto\Logger::NOTICE);
$Lua = new \danog\MadelineProto\Lua('madeline.lua', $MadelineProto);
break;
case 'b':
$authorization = $MadelineProto->bot_login(readline('Please enter a bot token: '));
$authorization = $MadelineProto->bot_login(\readline('Please enter a bot token: '));
\danog\MadelineProto\Logger::log($authorization, \danog\MadelineProto\Logger::NOTICE);
$Lua = new \danog\MadelineProto\Lua('madeline.lua', $MadelineProto);
break;

389
magna.php
View File

@ -1,389 +0,0 @@
#!/usr/bin/env php
<?php
/*
Copyright 2016-2019 Daniil Gentili
(https://daniil.it)
This file is part of MadelineProto.
MadelineProto is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
MadelineProto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Affero General Public License for more details.
You should have received a copy of the GNU General Public License along with MadelineProto.
If not, see <http://www.gnu.org/licenses/>.
*/
set_include_path(get_include_path().':'.realpath(dirname(__FILE__).'/MadelineProto/'));
if (!file_exists(__DIR__.'/vendor/autoload.php')) {
echo 'You did not run composer update, using madeline.php'.PHP_EOL;
if (!file_exists('madeline.php')) {
copy('https://phar.madelineproto.xyz/madeline.php', 'madeline.php');
}
include 'madeline.php';
} else {
require_once 'vendor/autoload.php';
}
if (!file_exists('songs.php')) {
copy('https://github.com/danog/MadelineProto/raw/master/songs.php', 'songs.php');
}
echo 'Deserializing MadelineProto from session.madeline...'.PHP_EOL;
/*if (!isset($MadelineProto->inputEncryptedFilePhoto) && false) {
$MadelineProto->inputEncryptedFilePhoto = $MadelineProto->upload_encrypted('tests/faust.jpg', 'fausticorn.jpg'); // This gets an inputFile object with file name magic
$MadelineProto->inputEncryptedFileGif = $MadelineProto->upload_encrypted('tests/pony.mp4');
$MadelineProto->inputEncryptedFileSticker = $MadelineProto->upload_encrypted('tests/lel.webp');
$MadelineProto->inputEncryptedFileDocument = $MadelineProto->upload_encrypted('tests/60', 'magic'); // This gets an inputFile object with file name magic
$MadelineProto->inputEncryptedFileVideo = $MadelineProto->upload_encrypted('tests/swing.mp4');
$MadelineProto->inputEncryptedFileAudio = $MadelineProto->upload_encrypted('tests/mosconi.mp3');
}*/
use danog\MadelineProto\Loop\Impl\ResumableSignalLoop;
class MessageLoop extends ResumableSignalLoop
{
const INTERVAL = 10;
private $timeout;
private $call;
public function __construct($API, $call, $timeout = self::INTERVAL)
{
$this->API = $API;
$this->call = $call;
$this->timeout = $timeout;
}
public function loop()
{
$MadelineProto = $this->API;
$logger = &$MadelineProto->logger;
while (true) {
while (!isset($this->call->mId)) {
$result = yield $this->waitSignal($this->pause($this->timeout));
if ($result) {
$logger->logger("Got signal in $this, exiting");
return;
}
}
try {
yield $MadelineProto->messages->editMessage(['id' => $this->call->mId, 'peer' => $this->call->getOtherID(), 'message' => 'Total running calls: '.count(yield $MadelineProto->getEventHandler()->calls).PHP_EOL.PHP_EOL.$this->call->getDebugString()]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
$MadelineProto->logger($e);
}
}
}
public function __toString(): string
{
return "VoIP message loop ".$this->call->getOtherId();
}
}
class StatusLoop extends ResumableSignalLoop
{
const INTERVAL = 2;
private $timeout;
private $call;
public function __construct($API, $call, $timeout = self::INTERVAL)
{
$this->API = $API;
$this->call = $call;
$this->timeout = $timeout;
}
public function loop()
{
$MadelineProto = $this->API;
$logger = &$MadelineProto->logger;
$call = $this->call;
while (true) {
$result = yield $this->waitSignal($this->pause($this->timeout));
if ($result) {
$logger->logger("Got signal in $this, exiting");
return;
}
if ($call->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_ENDED) {
try {
/*yield $this->messages->sendMedia([
'reply_to_msg_id' => $this->times[$call->getOtherID()][1],
'peer' => $call->getOtherID(), 'message' => 'Call statistics by @magnaluna',
'media' => [
'_' => 'inputMediaUploadedDocument',
'file' => "/tmp/stats".$call->getCallID()['id'].".txt",
'attributes' => [
['_' => 'documentAttributeFilename', 'file_name' => "stats".$call->getCallID()['id'].".txt"]
]
],
]);*/
yield $MadelineProto->messages->sendMedia([
'reply_to_msg_id' => $this->call->mId,
'peer' => $call->getOtherID(), 'message' => 'Debug info by @magnaluna',
'media' => [
'_' => 'inputMediaUploadedDocument',
'file' => '/tmp/logs'.$call->getCallID()['id'].'.log',
'attributes' => [
['_' => 'documentAttributeFilename', 'file_name' => 'logs'.$call->getCallID()['id'].'.log'],
],
],
]);
} catch (\danog\MadelineProto\Exception $e) {
$MadelineProto->logger($e);
} catch (\danog\MadelineProto\RPCErrorException $e) {
$MadelineProto->logger($e);
} catch (\danog\MadelineProto\Exception $e) {
$MadelineProto->logger($e);
}
@unlink('/tmp/logs'.$call->getCallID()['id'].'.log');
@unlink('/tmp/stats'.$call->getCallID()['id'].'.txt');
$MadelineProto->getEventHandler()->cleanUpCall($call->getOtherID());
return;
}
}
}
public function __toString(): string
{
return "VoIP status loop ".$this->call->getOtherId();
}
}
class EventHandler extends \danog\MadelineProto\EventHandler
{
const ADMINS = [101374607]; // @danogentili, creator of MadelineProto
private $messageLoops = [];
private $statusLoops = [];
private $programmed_call;
private $my_users;
public $calls = [];
public function configureCall($call)
{
include 'songs.php';
$call->configuration['enable_NS'] = false;
$call->configuration['enable_AGC'] = false;
$call->configuration['enable_AEC'] = false;
$call->configuration['log_file_path'] = '/tmp/logs'.$call->getCallID()['id'].'.log'; // Default is /dev/null
//$call->configuration["stats_dump_file_path"] = "/tmp/stats".$call->getCallID()['id'].".txt"; // Default is /dev/null
$call->parseConfig();
$call->playOnHold($songs);
if ($call->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_INCOMING) {
if ($call->accept() === false) {
$this->logger('DID NOT ACCEPT A CALL');
}
}
if ($call->getCallState() !== \danog\MadelineProto\VoIP::CALL_STATE_ENDED) {
$this->calls[$call->getOtherID()] = $call;
try {
$call->mId = yield $this->messages->sendMessage(['peer' => $call->getOtherID(), 'message' => 'Total running calls: '.count($this->calls).PHP_EOL.PHP_EOL.$call->getDebugString()])['id'];
} catch (\Throwable $e) {
$this->logger($e);
}
$this->messageLoops[$call->getOtherID()] = new MessageLoop($this, $call);
$this->statusLoops[$call->getOtherID()] = new StatusLoop($this, $call);
$this->messageLoops[$call->getOtherID()]->start();
$this->statusLoops[$call->getOtherID()]->start();
}
//yield $this->messages->sendMessage(['message' => var_export($call->configuration, true), 'peer' => $call->getOtherID()]);
}
public function cleanUpCall($user)
{
if (isset($this->calls[$user])) {
unset($this->calls[$user]);
}
if (isset($this->messageLoops[$user])) {
$this->messageLoops[$user]->signal(true);
unset($this->messageLoops[$user]);
}
if (isset($this->statusLoops[$user])) {
$this->statusLoops[$user]->signal(true);
unset($this->statusLoops[$user]);
}
}
public function makeCall($user)
{
try {
if (isset($this->calls[$user])) {
if ($this->calls[$user]->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_ENDED) {
yield $this->cleanUpCall($user);
} else {
yield $this->messages->sendMessage(['peer' => $user, 'message' => "I'm already in a call with you!"]);
return;
}
}
yield $this->configureCall(yield $this->requestCall($user));
} catch (\danog\MadelineProto\RPCErrorException $e) {
try {
if ($e->rpc === 'USER_PRIVACY_RESTRICTED') {
$e = 'Please disable call privacy settings to make me call you';
}/* elseif (strpos($e->rpc, 'FLOOD_WAIT_') === 0) {
$t = str_replace('FLOOD_WAIT_', '', $e->rpc);
$this->programmed_call[] = [$user, time() + 1 + $t];
$e = "I'll call you back in $t seconds.\nYou can also call me right now.";
}*/
yield $this->messages->sendMessage(['peer' => $user, 'message' => (string) $e]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
}
} catch (\Throwable $e) {
yield $this->messages->sendMessage(['peer' => $user, 'message' => (string) $e]);
}
}
public function handleMessage($chat_id, $from_id, $message)
{
try {
if (!isset($this->my_users[$from_id]) || $message === '/start') {
$this->my_users[$from_id] = true;
$message = '/call';
yield $this->messages->sendMessage(['no_webpage' => true, 'peer' => $chat_id, 'message' => "Hi, I'm @magnaluna the webradio.
Call _me_ to listen to some **awesome** music, or send /call to make _me_ call _you_ (don't forget to disable call privacy settings!).
You can also program a phone call with /program:
/program 29 August 2018 - call me the 29th of august 2018
/program +1 hour 30 minutes - call me in one hour and thirty minutes
/program next Thursday - call me next Thursday at midnight
Send /start to see this message again.
I also provide advanced stats during calls!
I'm a userbot powered by @MadelineProto, created by @danogentili.
Source code: https://github.com/danog/MadelineProto
Propic art by @magnaluna on [deviantart](https://magnaluna.deviantart.com).", 'parse_mode' => 'Markdown']);
}
if (!isset($this->calls[$from_id]) && $message === '/call') {
yield $this->makeCall($from_id);
}
if (strpos($message, '/program') === 0) {
$time = strtotime(str_replace('/program ', '', $message));
if ($time === false) {
yield $this->messages->sendMessage(['peer' => $chat_id, 'message' => 'Invalid time provided']);
} else if ($time - time() <= 0) {
yield $this->messages->sendMessage(['peer' => $chat_id, 'message' => 'Invalid time provided']);
} else {
yield $this->messages->sendMessage(['peer' => $chat_id, 'message' => 'OK']);
$this->programmed_call[] = [$from_id, $time];
$key = count($this->programmed_call) - 1;
yield $this->sleep($time - time());
yield $this->makeCall($from_id);
unset($this->programmed_call[$key]);
}
}
if ($message === '/broadcast' && in_array(self::ADMINS, $from_id)) {
$time = time() + 100;
$message = explode(' ', $message, 2);
unset($message[0]);
$message = implode(' ', $message);
$params = ['multiple' => true];
foreach (yield $this->get_dialogs() as $peer) {
$params []= ['peer' => $peer, 'message' => $message];
}
yield $this->messages->sendMessage($params);
}
} catch (\danog\MadelineProto\RPCErrorException $e) {
try {
if ($e->rpc === 'USER_PRIVACY_RESTRICTED') {
$e = 'Please disable call privacy settings to make me call you';
} /*elseif (strpos($e->rpc, 'FLOOD_WAIT_') === 0) {
$t = str_replace('FLOOD_WAIT_', '', $e->rpc);
$e = "Too many people used the /call function. I'll be able to call you in $t seconds.\nYou can also call me right now";
}*/
yield $this->messages->sendMessage(['peer' => $chat_id, 'message' => (string) $e]);
} catch (\danog\MadelineProto\RPCErrorException $e) {
}
$this->logger($e);
} catch (\danog\MadelineProto\Exception $e) {
$this->logger($e);
}
}
public function onUpdateNewMessage($update)
{
if ($update['message']['out'] || $update['message']['to_id']['_'] !== 'peerUser' || !isset($update['message']['from_id'])) {
return;
}
$this->logger->logger($update);
$chat_id = $from_id = yield $this->get_info($update)['bot_api_id'];
$message = $update['message']['message'] ?? '';
yield $this->handleMessage($chat_id, $from_id, $message);
}
public function onUpdateNewEncryptedMessage($update)
{
return;
$chat_id = yield $this->get_info($update)['InputEncryptedChat'];
$from_id = yield $this->get_secret_chat($chat_id)['user_id'];
$message = isset($update['message']['decrypted_message']['message']) ? $update['message']['decrypted_message']['message'] : '';
yield $this->handleMessage($chat_id, $from_id, $message);
}
public function onUpdateEncryption($update)
{
return;
try {
if ($update['chat']['_'] !== 'encryptedChat') {
return;
}
$chat_id = yield $this->get_info($update)['InputEncryptedChat'];
$from_id = yield $this->get_secret_chat($chat_id)['user_id'];
$message = '';
} catch (\danog\MadelineProto\Exception $e) {
return;
}
yield $this->handleMessage($chat_id, $from_id, $message);
}
public function onUpdatePhoneCall($update)
{
if (is_object($update['phone_call']) && isset($update['phone_call']->madeline) && $update['phone_call']->getCallState() === \danog\MadelineProto\VoIP::CALL_STATE_INCOMING) {
yield $this->configureCall($update['phone_call']);
}
}
/*public function onAny($update)
{
$this->logger->logger($update);
}*/
public function __construct($API)
{
parent::__construct($API);
$this->programmed_call = [];
foreach ($this->programmed_call as $key => list($user, $time)) {
continue;
$sleepTime = $time <= time() ? 0 : $time - time();
$this->callFork((function () use ($sleepTime, $key, $user) {
yield $this->sleep($sleepTime);
yield $this->makeCall($user);
unset($this->programmed_call[$key]);
})());
}
}
public function __sleep()
{
return ['programmed_call', 'my_users'];
}
}
if (!class_exists('\\danog\\MadelineProto\\VoIPServerConfig')) {
die('Install the libtgvoip extension: https://voip.madelineproto.xyz'.PHP_EOL);
}
\danog\MadelineProto\VoIPServerConfig::update(
[
'audio_init_bitrate' => 100 * 1000,
'audio_max_bitrate' => 100 * 1000,
'audio_min_bitrate' => 10 * 1000,
'audio_congestion_window' => 4 * 1024,
]
);
$MadelineProto = new \danog\MadelineProto\API('session.madeline', ['secret_chats' => ['accept_chats' => false], 'logger' => ['logger' => 3, 'logger_level' => 5, 'logger_param' => getcwd().'/MadelineProto.log'], 'updates' => ['getdifference_interval' => 10], 'serialization' => ['serialization_interval' => 30, 'cleanup_before_serialization' => true], 'flood_timeout' => ['wait_if_lt' => 86400]]);
foreach (['calls', 'programmed_call', 'my_users'] as $key) {
if (isset($MadelineProto->API->storage[$key])) {
unset($MadelineProto->API->storage[$key]);
}
}
$MadelineProto->async(true);
$MadelineProto->loop(function () use ($MadelineProto) {
yield $MadelineProto->start();
yield $MadelineProto->setEventHandler('\EventHandler');
});
$MadelineProto->loop();

View File

@ -16,10 +16,10 @@ if (!isset($argv[3])) {
die(1);
}
@unlink($argv[2]);
@\unlink($argv[2]);
$p = new Phar(__DIR__.'/'.$argv[2], 0, $argv[2]);
$p->buildFromDirectory(realpath($argv[1]), '/^((?!tests).)*(\.php|\.py|\.tl|\.json|\.dat)$/i');
$p->buildFromDirectory(\realpath($argv[1]), '/^((?!tests).)*(\.php|\.py|\.tl|\.json|\.dat)$/i');
$p->addFromString('vendor/danog/madelineproto/.git/refs/heads/master', $argv[3]);
$p->addFromString('.git/refs/heads/master', $argv[3]);

View File

@ -2,7 +2,7 @@
function ___install_madeline()
{
if (count(debug_backtrace(0)) === 1) {
if (\count(\debug_backtrace(0)) === 1) {
die('You must include this file in another PHP script'.PHP_EOL);
}
$old = false;
@ -17,7 +17,7 @@ function ___install_madeline()
}
if ($old) {
$newline = PHP_EOL;
if (php_sapi_name() !== 'cli') {
if (PHP_SAPI !== 'cli') {
$newline = '<br>'.$newline;
}
echo "**********************************************************************************$newline";
@ -33,12 +33,12 @@ function ___install_madeline()
}
// MTProxy update
$file = debug_backtrace(0, 1)[0]['file'];
if (file_exists($file)) {
$contents = file_get_contents($file);
$file = \debug_backtrace(0, 1)[0]['file'];
if (\file_exists($file)) {
$contents = \file_get_contents($file);
if (strpos($contents, 'new \danog\MadelineProto\Server') && in_array($contents, [file_get_contents('https://github.com/danog/MadelineProtoPhar/raw/2270bd9a94d168a5e6731ffd7e61821ea244beff/mtproxyd'), file_get_contents('https://github.com/danog/MadelineProtoPhar/raw/7cabb718ec3ccb79e3c8e3d34f5bccbe3f63b0fd/mtproxyd')]) && ($mtproxyd = file_get_contents('https://phar.madelineproto.xyz/mtproxyd?v=new'))) {
file_put_contents($file, $mtproxyd);
if (\strpos($contents, 'new \danog\MadelineProto\Server') && \in_array($contents, [\file_get_contents('https://github.com/danog/MadelineProtoPhar/raw/2270bd9a94d168a5e6731ffd7e61821ea244beff/mtproxyd'), \file_get_contents('https://github.com/danog/MadelineProtoPhar/raw/7cabb718ec3ccb79e3c8e3d34f5bccbe3f63b0fd/mtproxyd')]) && ($mtproxyd = \file_get_contents('https://phar.madelineproto.xyz/mtproxyd?v=new'))) {
\file_put_contents($file, $mtproxyd);
return;
}
@ -49,10 +49,10 @@ function ___install_madeline()
$phar_template = 'https://phar.madelineproto.xyz/madeline%s.phar?v=new';
// Version definition
$custom_branch = defined('MADELINE_BRANCH') ? MADELINE_BRANCH : null;
$custom_branch = \defined('MADELINE_BRANCH') ? MADELINE_BRANCH : null;
if ($custom_branch === '') { // If the constant is an empty string, default to the latest alpha build
$custom_branch = 'master';
} else if ($custom_branch === null) { // If the constant is not defined, default to the latest stable build
} elseif ($custom_branch === null) { // If the constant is not defined, default to the latest stable build
$custom_branch = '';
}
@ -75,19 +75,19 @@ function ___install_madeline()
}
// Checking if defined branch/default branch builds can be downloaded
if (!($release = @file_get_contents(sprintf($release_template, $release_branch)))) {
if (!($release = @file_get_contents(sprintf($release_template, $release_fallback_branch)))) {
if (!($release = @\file_get_contents(\sprintf($release_template, $release_branch)))) {
if (!($release = @\file_get_contents(\sprintf($release_template, $release_fallback_branch)))) {
return;
}
$release_branch = $release_fallback_branch;
}
if (!file_exists('madeline.phar') || !file_exists('madeline.phar.version') || file_get_contents('madeline.phar.version') !== $release) {
$phar = file_get_contents(sprintf($phar_template, $release_branch));
if (!\file_exists('madeline.phar') || !\file_exists('madeline.phar.version') || \file_get_contents('madeline.phar.version') !== $release) {
$phar = \file_get_contents(\sprintf($phar_template, $release_branch));
if ($phar) {
file_put_contents('madeline.phar', $phar);
file_put_contents('madeline.phar.version', $release);
\file_put_contents('madeline.phar', $phar);
\file_put_contents('madeline.phar.version', $release);
}
}
}

View File

@ -10,15 +10,15 @@ See the GNU Affero General Public License for more details.
You should have received a copy of the GNU General Public License along with MadelineProto.
If not, see <http://www.gnu.org/licenses/>.
*/
set_include_path(get_include_path().':'.realpath(dirname(__FILE__).'/MadelineProto/'));
\set_include_path(\get_include_path().':'.\realpath(\dirname(__FILE__).'/MadelineProto/'));
/*
* Various ways to load MadelineProto
*/
if (!file_exists(__DIR__.'/vendor/autoload.php')) {
if (!\file_exists(__DIR__.'/vendor/autoload.php')) {
echo 'You did not run composer update, using madeline.php'.PHP_EOL;
if (!file_exists('madeline.php')) {
copy('https://phar.madelineproto.xyz/madeline.php', 'madeline.php');
if (!\file_exists('madeline.php')) {
\copy('https://phar.madelineproto.xyz/madeline.php', 'madeline.php');
}
include 'madeline.php';
} else {
@ -41,27 +41,27 @@ class EventHandler extends \danog\MadelineProto\EventHandler
$secret_media = [];
// Photo uploaded as document, secret chat
$secret_media['document_photo'] = ['peer' => $update, 'file' => 'tests/faust.jpg', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => mime_content_type('tests/faust.jpg'), 'caption' => 'This file was uploaded using MadelineProto', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'faust.jpg', 'size' => filesize('tests/faust.jpg'), 'attributes' => [['_' => 'documentAttributeImageSize', 'w' => 1280, 'h' => 914]]]]];
$secret_media['document_photo'] = ['peer' => $update, 'file' => 'tests/faust.jpg', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => \file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => \mime_content_type('tests/faust.jpg'), 'caption' => 'This file was uploaded using MadelineProto', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'faust.jpg', 'size' => \filesize('tests/faust.jpg'), 'attributes' => [['_' => 'documentAttributeImageSize', 'w' => 1280, 'h' => 914]]]]];
// Photo, secret chat
$secret_media['photo'] = ['peer' => $update, 'file' => 'tests/faust.jpg', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaPhoto', 'thumb' => file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'caption' => 'This file was uploaded using MadelineProto', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'size' => filesize('tests/faust.jpg'), 'w' => 1280, 'h' => 914]]];
$secret_media['photo'] = ['peer' => $update, 'file' => 'tests/faust.jpg', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaPhoto', 'thumb' => \file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'caption' => 'This file was uploaded using MadelineProto', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'size' => \filesize('tests/faust.jpg'), 'w' => 1280, 'h' => 914]]];
// GIF, secret chat
$secret_media['gif'] = ['peer' => $update, 'file' => 'tests/pony.mp4', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => file_get_contents('tests/pony.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => mime_content_type('tests/pony.mp4'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'pony.mp4', 'size' => filesize('tests/faust.jpg'), 'attributes' => [['_' => 'documentAttributeAnimated']]]]];
$secret_media['gif'] = ['peer' => $update, 'file' => 'tests/pony.mp4', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => \file_get_contents('tests/pony.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => \mime_content_type('tests/pony.mp4'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'pony.mp4', 'size' => \filesize('tests/faust.jpg'), 'attributes' => [['_' => 'documentAttributeAnimated']]]]];
// Sticker, secret chat
$secret_media['sticker'] = ['peer' => $update, 'file' => 'tests/lel.webp', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => file_get_contents('tests/lel.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => mime_content_type('tests/lel.webp'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'lel.webp', 'size' => filesize('tests/lel.webp'), 'attributes' => [['_' => 'documentAttributeSticker', 'alt' => 'LEL', 'stickerset' => ['_' => 'inputStickerSetEmpty']]]]]];
$secret_media['sticker'] = ['peer' => $update, 'file' => 'tests/lel.webp', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => \file_get_contents('tests/lel.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => \mime_content_type('tests/lel.webp'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'lel.webp', 'size' => \filesize('tests/lel.webp'), 'attributes' => [['_' => 'documentAttributeSticker', 'alt' => 'LEL', 'stickerset' => ['_' => 'inputStickerSetEmpty']]]]]];
// Document, secrey chat
$secret_media['document'] = ['peer' => $update, 'file' => 'tests/60', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => 'magic/magic', 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'magic.magic', 'size' => filesize('tests/60'), 'attributes' => [['_' => 'documentAttributeFilename', 'file_name' => 'fairy']]]]];
$secret_media['document'] = ['peer' => $update, 'file' => 'tests/60', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => \file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => 'magic/magic', 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'magic.magic', 'size' => \filesize('tests/60'), 'attributes' => [['_' => 'documentAttributeFilename', 'file_name' => 'fairy']]]]];
// Video, secret chat
$secret_media['video'] = ['peer' => $update, 'file' => 'tests/swing.mp4', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => file_get_contents('tests/swing.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => mime_content_type('tests/swing.mp4'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'swing.mp4', 'size' => filesize('tests/swing.mp4'), 'attributes' => [['_' => 'documentAttributeVideo', 'duration' => 5, 'w' => 1280, 'h' => 720]]]]];
$secret_media['video'] = ['peer' => $update, 'file' => 'tests/swing.mp4', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => \file_get_contents('tests/swing.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => \mime_content_type('tests/swing.mp4'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'swing.mp4', 'size' => \filesize('tests/swing.mp4'), 'attributes' => [['_' => 'documentAttributeVideo', 'duration' => 5, 'w' => 1280, 'h' => 720]]]]];
// audio, secret chat
$secret_media['audio'] = ['peer' => $update, 'file' => 'tests/mosconi.mp3', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => mime_content_type('tests/mosconi.mp3'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'mosconi.mp3', 'size' => filesize('tests/mosconi.mp3'), 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => false, 'duration' => 1, 'title' => 'AH NON LO SO IO', 'performer' => 'IL DIO GERMANO MOSCONI']]]]];
$secret_media['audio'] = ['peer' => $update, 'file' => 'tests/mosconi.mp3', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => \file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => \mime_content_type('tests/mosconi.mp3'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'mosconi.mp3', 'size' => \filesize('tests/mosconi.mp3'), 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => false, 'duration' => 1, 'title' => 'AH NON LO SO IO', 'performer' => 'IL DIO GERMANO MOSCONI']]]]];
$secret_media['voice'] = ['peer' => $update, 'file' => 'tests/mosconi.mp3', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => mime_content_type('tests/mosconi.mp3'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'mosconi.mp3', 'size' => filesize('tests/mosconi.mp3'), 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => true, 'duration' => 1, 'title' => 'AH NON LO SO IO', 'performer' => 'IL DIO GERMANO MOSCONI']]]]];
$secret_media['voice'] = ['peer' => $update, 'file' => 'tests/mosconi.mp3', 'message' => ['_' => 'decryptedMessage', 'ttl' => 0, 'message' => '', 'media' => ['_' => 'decryptedMessageMediaDocument', 'thumb' => \file_get_contents('tests/faust.preview.jpg'), 'thumb_w' => 90, 'thumb_h' => 90, 'mime_type' => \mime_content_type('tests/mosconi.mp3'), 'caption' => 'test', 'key' => $inputEncryptedFile['key'], 'iv' => $inputEncryptedFile['iv'], 'file_name' => 'mosconi.mp3', 'size' => \filesize('tests/mosconi.mp3'), 'attributes' => [['_' => 'documentAttributeAudio', 'voice' => true, 'duration' => 1, 'title' => 'AH NON LO SO IO', 'performer' => 'IL DIO GERMANO MOSCONI']]]]];
foreach ($secret_media as $type => $smessage) {
$type = yield $this->messages->sendEncryptedFile($smessage);
@ -83,14 +83,14 @@ class EventHandler extends \danog\MadelineProto\EventHandler
}
}
if (file_exists('.env')) {
if (\file_exists('.env')) {
echo 'Loading .env...'.PHP_EOL;
$dotenv = Dotenv\Dotenv::create(getcwd());
$dotenv = Dotenv\Dotenv::create(\getcwd());
$dotenv->load();
}
echo 'Loading settings...'.PHP_EOL;
$settings = json_decode(getenv('MTPROTO_SETTINGS'), true) ?: [];
$settings = \json_decode(\getenv('MTPROTO_SETTINGS'), true) ?: [];
$MadelineProto = new \danog\MadelineProto\API('s.madeline', $settings);

View File

@ -1,11 +0,0 @@
<?php
$songs = glob('*raw');
if (!$songs) {
die('No songs defined! Convert some songs as described in https://docs.madelineproto.xyz/docs/CALLS.html#playing-mp3-files');
}
$songs_length = count($songs);
for ($x = 0; $x < $songs_length; $x++) {
shuffle($songs);
}

View File

@ -524,7 +524,7 @@ class Connection extends Session
* Disconnect from DC.
*
* @param bool $temporary Whether the disconnection is temporary, triggered by the reconnect method
*
*
* @return void
*/
public function disconnect(bool $temporary = false)

View File

@ -530,6 +530,9 @@ class DataCenterConnection implements JsonSerializable
*/
public function even()
{
if (!$this->availableConnections) {
return;
}
$min = \min($this->availableConnections);
if ($min < 50) {
foreach ($this->availableConnections as &$count) {

View File

@ -33,14 +33,14 @@ use danog\MadelineProto\Stream\RawProxyStreamInterface;
class SocksProxy implements RawProxyStreamInterface, BufferedProxyStreamInterface
{
const REPS = [
0 => 'succeeded',
1 => 'general SOCKS server failure',
2 => 'connection not allowed by ruleset',
3 => 'Network unreachable',
4 => 'Host unreachable',
5 => 'Connection refused',
6 => 'TTL expired',
7 => 'Command not supported',
0 => 'succeeded',
1 => 'general SOCKS server failure',
2 => 'connection not allowed by ruleset',
3 => 'Network unreachable',
4 => 'Host unreachable',
5 => 'Connection refused',
6 => 'TTL expired',
7 => 'Command not supported',
8 => 'Address type not supported'
];
use RawStream;

View File

@ -30,16 +30,16 @@ class Lang
}';
function from_camel_case($input)
{
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
\preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
$ret = $matches[0];
foreach ($ret as &$match) {
$match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
$match = $match == \strtoupper($match) ? \strtolower($match) : \lcfirst($match);
}
return implode(' ', $ret);
return \implode(' ', $ret);
}
$lang_code = readline('Enter the language you whish to localize: ');
$lang_code = \readline('Enter the language you whish to localize: ');
if (!isset(\danog\MadelineProto\Lang::$lang[$lang_code])) {
\danog\MadelineProto\Lang::$lang[$lang_code] = \danog\MadelineProto\Lang::$current_lang;
@ -47,26 +47,27 @@ if (!isset(\danog\MadelineProto\Lang::$lang[$lang_code])) {
} else {
echo 'Completing localization of existing language'.PHP_EOL.PHP_EOL;
}
$count = count(\danog\MadelineProto\Lang::$lang[$lang_code]);
$count = \count(\danog\MadelineProto\Lang::$lang[$lang_code]);
$curcount = 0;
ksort(\danog\MadelineProto\Lang::$current_lang);
\ksort(\danog\MadelineProto\Lang::$current_lang);
foreach (\danog\MadelineProto\Lang::$current_lang as $key => $value) {
if (!isset(\danog\MadelineProto\Lang::$lang[$lang_code][$key])) {
\danog\MadelineProto\Lang::$lang[$lang_code][$key] = $value;
}
if (\danog\MadelineProto\Lang::$lang[$lang_code][$key] === $value && ($lang_code !== 'en' || $value == '' ||
strpos($value, 'You cannot use this method directly') === 0 ||
strpos($value, 'Update ') === 0 ||
ctype_lower($value[0])
if (\danog\MadelineProto\Lang::$lang[$lang_code][$key] === $value && (
$lang_code !== 'en' || $value == '' ||
\strpos($value, 'You cannot use this method directly') === 0 ||
\strpos($value, 'Update ') === 0 ||
\ctype_lower($value[0])
)) {
$value = \danog\MadelineProto\Lang::$lang[$lang_code][$key];
if (in_array($key, ['v_error', 'v_tgerror'])) {
$value = hex2bin($value);
if (\in_array($key, ['v_error', 'v_tgerror'])) {
$value = \hex2bin($value);
}
if ($value == '') {
$value = $key;
}
preg_match('/^[^_]+_(.*?)(?:_param_(.*)_type_(.*))?$/', $key, $matches);
\preg_match('/^[^_]+_(.*?)(?:_param_(.*)_type_(.*))?$/', $key, $matches);
$method_name = isset($matches[1]) ? $matches[1] : '';
$param_name = isset($matches[2]) ? $matches[2] : '';
$param_type = isset($matches[3]) ? $matches[3] : '';
@ -79,29 +80,29 @@ foreach (\danog\MadelineProto\Lang::$current_lang as $key => $value) {
\danog\MadelineProto\Lang::$lang[$lang_code][$key] = 'Random number for cryptographic security';
} elseif (isset(\danog\MadelineProto\MTProto::DISALLOWED_METHODS[$method_name])) {
\danog\MadelineProto\Lang::$lang[$lang_code][$key] = \danog\MadelineProto\MTProto::DISALLOWED_METHODS[$method_name];
} elseif (strpos($value, 'Update ') === 0) {
if (!$param_name && strpos($key, 'object_') === 0) {
$value = str_replace('Update ', '', $value).' update';
} elseif (\strpos($value, 'Update ') === 0) {
if (!$param_name && \strpos($key, 'object_') === 0) {
$value = \str_replace('Update ', '', $value).' update';
}
//} elseif (ctype_lower($value[0])) {
} else {
\danog\MadelineProto\Lang::$lang[$lang_code][$key] = readline($value.' => ');
\danog\MadelineProto\Lang::$lang[$lang_code][$key] = \readline($value.' => ');
if (\danog\MadelineProto\Lang::$lang[$lang_code][$key] === '') {
if ($param_name) {
$l = str_replace('_', ' ', $param_name);
$l = \str_replace('_', ' ', $param_name);
} else {
$l = explode('.', $method_name);
$l = from_camel_case(end($l));
$l = \explode('.', $method_name);
$l = from_camel_case(\end($l));
}
$l = ucfirst(strtolower($l));
if (preg_match('/ empty$/', $l)) {
$l = 'Empty '.strtolower(preg_replace('/ empty$/', '', $l));
$l = \ucfirst(\strtolower($l));
if (\preg_match('/ empty$/', $l)) {
$l = 'Empty '.\strtolower(\preg_replace('/ empty$/', '', $l));
}
foreach (['id', 'url', 'dc'] as $upper) {
$l = str_replace([ucfirst($upper), ' '.$upper], [strtoupper($upper), ' '.strtoupper($upper)], $l);
$l = \str_replace([\ucfirst($upper), ' '.$upper], [\strtoupper($upper), ' '.\strtoupper($upper)], $l);
}
if (in_array($param_type, ['Bool', 'true', 'false'])) {
if (\in_array($param_type, ['Bool', 'true', 'false'])) {
$l .= '?';
}
@ -109,14 +110,14 @@ foreach (\danog\MadelineProto\Lang::$current_lang as $key => $value) {
echo 'Using default value '.\danog\MadelineProto\Lang::$lang[$lang_code][$key].PHP_EOL;
}
}
\danog\MadelineProto\Lang::$lang[$lang_code][$key] = ucfirst(\danog\MadelineProto\Lang::$lang[$lang_code][$key]);
if (in_array($key, ['v_error', 'v_tgerror'])) {
\danog\MadelineProto\Lang::$lang[$lang_code][$key] = bin2hex(\danog\MadelineProto\Lang::$lang[$lang_code][$key]);
\danog\MadelineProto\Lang::$lang[$lang_code][$key] = \ucfirst(\danog\MadelineProto\Lang::$lang[$lang_code][$key]);
if (\in_array($key, ['v_error', 'v_tgerror'])) {
\danog\MadelineProto\Lang::$lang[$lang_code][$key] = \bin2hex(\danog\MadelineProto\Lang::$lang[$lang_code][$key]);
}
file_put_contents('src/danog/MadelineProto/Lang.php', sprintf($template, var_export(\danog\MadelineProto\Lang::$lang, true), var_export(\danog\MadelineProto\Lang::$lang['en'], true)));
\file_put_contents('src/danog/MadelineProto/Lang.php', \sprintf($template, \var_export(\danog\MadelineProto\Lang::$lang, true), \var_export(\danog\MadelineProto\Lang::$lang['en'], true)));
echo 'OK, '.($curcount * 100 / $count).'% done. edit src/danog/MadelineProto/Lang.php to fix mistakes.'.PHP_EOL;
}
$curcount++;
}
file_put_contents('src/danog/MadelineProto/Lang.php', sprintf($template, var_export(\danog\MadelineProto\Lang::$lang, true), var_export(\danog\MadelineProto\Lang::$lang['en'], true)));
\file_put_contents('src/danog/MadelineProto/Lang.php', \sprintf($template, \var_export(\danog\MadelineProto\Lang::$lang, true), \var_export(\danog\MadelineProto\Lang::$lang['en'], true)));
echo 'OK. edit src/danog/MadelineProto/Lang.php to fix mistakes.'.PHP_EOL;

1
userbots/magnaluna Submodule

@ -0,0 +1 @@
Subproject commit 6121026ffc906305083796df8b831c93b79ad819