diff --git a/src/danog/MadelineProto/DataCenter.php b/src/danog/MadelineProto/DataCenter.php index c215eb45..3c87ad74 100644 --- a/src/danog/MadelineProto/DataCenter.php +++ b/src/danog/MadelineProto/DataCenter.php @@ -119,6 +119,9 @@ class DataCenter case 'tcp_intermediate': $default = [[DefaultStream::getName(), []], [BufferedRawStream::getName(), []], [IntermediateStream::getName(), []]]; break; + case 'obfuscated2': + $this->settings[$dc_config_number]['protocol'] = 'tcp_intermediate_padded'; + $this->settings[$dc_config_number]['obfuscated'] = true; case 'tcp_intermediate_padded': $default = [[DefaultStream::getName(), []], [BufferedRawStream::getName(), []], [IntermediatePaddedStream::getName(), []]]; break; diff --git a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php index b464b81b..44a0ca4e 100644 --- a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php @@ -83,8 +83,10 @@ trait PeerHandler public function add_user($user) { if (!isset($user['access_hash'])) { + $this->logger->logger("No access hash with user {$user['id']}, trying to fetch by ID..."); $this->cache_pwr_chat($user['id'], false, true); if (isset($user['username']) && !isset($this->chats[$user['id']])) { + $this->logger->logger("No access hash with user {$user['id']}, trying to fetch by username..."); $this->cache_pwr_chat($user['username'], false, true); } @@ -93,6 +95,7 @@ trait PeerHandler switch ($user['_']) { case 'user': if (!isset($this->chats[$user['id']]) || $this->chats[$user['id']] !== $user) { + $this->logger->logger("Updated user {$user['id']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE); $this->chats[$user['id']] = $user; $this->cache_pwr_chat($user['id'], false, true); } @@ -118,6 +121,7 @@ trait PeerHandler case 'chatEmpty': case 'chatForbidden': if (!isset($this->chats[-$chat['id']]) || $this->chats[-$chat['id']] !== $chat) { + $this->logger->logger("Updated chat -{$chat['id']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE); $this->chats[-$chat['id']] = $chat; $this->cache_pwr_chat(-$chat['id'], $this->settings['peer']['full_fetch'], true); } @@ -128,14 +132,18 @@ trait PeerHandler case 'channelForbidden': $bot_api_id = $this->to_supergroup($chat['id']); if (!isset($chat['access_hash'])) { + $this->logger->logger("Chat $bot_api_id does not have access hash, fetching by ID..."); $this->cache_pwr_chat($bot_api_id, $this->settings['peer']['full_fetch'], true); if (isset($chat['username']) && !isset($this->chats[$bot_api_id])) { + $this->logger->logger("Chat $bot_api_id does not have access hash, fetching by username..."); $this->cache_pwr_chat($chat['username'], $this->settings['peer']['full_fetch'], true); } return; } if (!isset($this->chats[$bot_api_id]) || $this->chats[$bot_api_id] !== $chat) { + $this->logger->logger("Updated chat $bot_api_id", \danog\MadelineProto\Logger::ULTRA_VERBOSE); + $this->chats[$bot_api_id] = $chat; if ($this->settings['peer']['full_fetch'] && (!isset($this->full_chats[$bot_api_id]) || $this->full_chats[$bot_api_id]['full']['participants_count'] !== $this->get_full_info($bot_api_id)['full']['participants_count'])) { @@ -217,7 +225,7 @@ trait PeerHandler return true; } - public function get_info($id, $recursive = true) + public function get_id($id) { if (is_array($id)) { switch ($id['_']) { @@ -232,54 +240,38 @@ trait PeerHandler case 'notifyPeer': case 'dialog': case 'help.proxyDataPromo': - return $this->get_info($id['peer']); + return $this->get_id($id['peer']); case 'inputUserSelf': case 'inputPeerSelf': - $id = $this->authorization['user']['id']; - break; + return $this->authorization['user']['id']; case 'user': - $id = $id['id']; - break; + return $id['id']; case 'userFull': - $id = $id['user']['id']; - break; + return $id['user']['id']; case 'inputPeerUser': case 'inputUser': case 'peerUser': - $id = $id['user_id']; - break; + return $id['user_id']; case 'chat': case 'chatFull': - $id = -$id['id']; - break; + return -$id['id']; case 'inputPeerChat': case 'peerChat': - $id = -$id['chat_id']; - break; + return -$id['chat_id']; case 'channel': case 'channelFull': - $id = $this->to_supergroup($id['id']); - break; + return $this->to_supergroup($id['id']); case 'inputPeerChannel': case 'inputChannel': case 'peerChannel': - $id = $this->to_supergroup($id['channel_id']); - break; + return $this->to_supergroup($id['channel_id']); case 'message': case 'messageService': if (!isset($id['from_id']) || $id['to_id']['_'] !== 'peerUser' || $id['to_id']['user_id'] !== $this->authorization['user']['id']) { - return $this->get_info($id['to_id']); - } - $id = $id['from_id']; - break; - case 'encryptedMessage': - case 'encryptedMessageService': - $id = $id['chat_id']; - if (!isset($this->secret_chats[$id])) { - throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['sec_peer_not_in_db']); + return $this->get_id($id['to_id']); } + return $id['from_id']; - return $this->secret_chats[$id]; case 'updateChannelReadMessagesContents': case 'updateChannelAvailableMessages': case 'updateChannel': @@ -290,7 +282,7 @@ trait PeerHandler case 'updateReadChannelOutbox': case 'updateDeleteChannelMessages': case 'updateChannelPinnedMessage': - return $this->get_info($this->to_supergroup($id['channel_id'])); + return $this->to_supergroup($id['channel_id']); case 'updateChatParticipants': $id = $id['participants']; case 'updateChatUserTyping': @@ -298,7 +290,7 @@ trait PeerHandler case 'updateChatParticipantDelete': case 'updateChatParticipantAdmin': case 'updateChatAdmins': - return $this->get_info(-$id['chat_id']); + return -$id['chat_id']; case 'updateUserTyping': case 'updateUserStatus': case 'updateUserName': @@ -313,47 +305,69 @@ trait PeerHandler case 'updateBotCallbackQuery': case 'updateBotPrecheckoutQuery': case 'updateBotShippingQuery': - return $this->get_info($id['user_id']); + return $id['user_id']; case 'updatePhoneCall': - return $this->get_info($id->getOtherID()); + return $id->getOtherID(); case 'updateReadHistoryInbox': case 'updateReadHistoryOutbox': - return $this->get_info($id['peer']); + return $this->get_id($id['peer']); case 'updateNewMessage': case 'updateNewChannelMessage': case 'updateEditMessage': case 'updateEditChannelMessage': case 'updateNewEncryptedMessage': - return $this->get_info($id['message']); - case 'updateEncryption': - return $this->get_secret_chat($id['chat']['id']); - case 'updateEncryptedChatTyping': - case 'updateEncryptedMessagesRead': - return $this->get_secret_chat($id['chat_id']); + return $this->get_id($id['message']); case 'chatForbidden': case 'channelForbidden': throw new \danog\MadelineProto\RPCErrorException('CHAT_FORBIDDEN'); default: throw new \danog\MadelineProto\Exception('Invalid constructor given '.var_export($id, true)); - break; } } - if (is_string($id) && strpos($id, '#') !== false) { - if (preg_match('/^channel#(\d*)/', $id, $matches)) { - $id = $this->to_supergroup($matches[1]); - } - if (preg_match('/^chat#(\d*)/', $id, $matches)) { - $id = '-'.$matches[1]; - } - if (preg_match('/^user#(\d*)/', $id, $matches)) { - $id = $matches[1]; + if (is_string($id)) { + if (strpos($id, '#') !== false) { + if (preg_match('/^channel#(\d*)/', $id, $matches)) { + return $this->to_supergroup($matches[1]); + } + if (preg_match('/^chat#(\d*)/', $id, $matches)) { + $id = '-'.$matches[1]; + } + if (preg_match('/^user#(\d*)/', $id, $matches)) { + return $matches[1]; + } } } if (is_numeric($id)) { if (is_string($id)) { $id = \danog\MadelineProto\Magic::$bigint ? (float) $id : (int) $id; } + return $id; + } + return false; + } + public function get_info($id, $recursive = true) + { + if (is_array($id)) { + switch ($id['_']) { + case 'updateEncryption': + return $this->get_secret_chat($id['chat']['id']); + case 'updateEncryptedChatTyping': + case 'updateEncryptedMessagesRead': + return $this->get_secret_chat($id['chat_id']); + case 'encryptedMessage': + case 'encryptedMessageService': + $id = $id['chat_id']; + if (!isset($this->secret_chats[$id])) { + throw new \danog\MadelineProto\Exception(\danog\MadelineProto\Lang::$current_lang['sec_peer_not_in_db']); + } + return $this->secret_chats[$id]; + } + } + $try_id = $this->get_id($id); + if ($try_id !== false) $id = $try_id; + + if (is_numeric($id)) { if (!isset($this->chats[$id])) { try { if ($id < 0) { diff --git a/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php b/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php index 34fcfc85..cbe49205 100644 --- a/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php +++ b/src/danog/MadelineProto/MTProtoTools/ReferenceDatabase.php @@ -86,8 +86,6 @@ class ReferenceDatabase implements TLCallback 'user' => self::USER_PHOTO_ORIGIN, 'userFull' => self::USER_PHOTO_ORIGIN, - 'message' => self::MESSAGE_ORIGIN, - 'messageService' => self::MESSAGE_ORIGIN, 'wallPaper' => self::WALLPAPER_ORIGIN, @@ -266,7 +264,7 @@ class ReferenceDatabase implements TLCallback switch ($data['_']) { case 'message': case 'messageService': - $origin['peer'] = $data; + $origin['peer'] = $this->API->get_id($data); $origin['msg_id'] = $data['id']; break; case 'messages.savedGifs': @@ -481,7 +479,7 @@ class ReferenceDatabase implements TLCallback // Peer + msg ID case self::MESSAGE_ORIGIN: if (is_array($origin['peer'])) { - $origin['peer'] = $this->API->get_info($origin['peer'])['bot_api_id']; + $origin['peer'] = $this->API->get_id($origin['peer']); } if ($origin['peer'] < 0) { yield $this->API->method_call_async_read('channels.getMessages', ['channel' => $origin['peer'], 'id' => [$origin['msg_id']]], ['datacenter' => $this->API->settings['connection_settings']['default_dc']]); diff --git a/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php b/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php index efc2aa98..95f7a054 100644 --- a/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/ResponseHandler.php @@ -528,6 +528,7 @@ trait ResponseHandler unset($request); $this->got_response_for_outgoing_message_id($request_id, $datacenter); Loop::defer(function () use ($request_id, $response, $datacenter) { + $this->logger->logger("Deferred: sent {$response['_']} to deferred"); $this->datacenter->sockets[$datacenter]->outgoing_messages[$request_id]['promise']->resolve($response); unset($this->datacenter->sockets[$datacenter]->outgoing_messages[$request_id]['promise']); }); diff --git a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php index 64b5ed69..cadbaf86 100644 --- a/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/UpdateHandler.php @@ -121,7 +121,7 @@ trait UpdateHandler public function check_msg_id($message) { try { - $peer_id = $this->get_info($message['to_id'])['bot_api_id']; + $peer_id = $this->get_id($message['to_id']); } catch (\danog\MadelineProto\Exception $e) { return true; } catch (\danog\MadelineProto\RPCErrorException $e) { @@ -408,13 +408,18 @@ trait UpdateHandler case 'updateEditMessage': case 'updateNewChannelMessage': case 'updateEditChannelMessage': - if ((isset($update['message']['from_id']) && !$this->peer_isset($update['message']['from_id'])) || - !$this->peer_isset($update['message']['to_id']) || - isset($update['message']['via_bot_id']) && !$this->peer_isset($update['message']['via_bot_id']) || - isset($update['message']['entities']) && !$this->entities_peer_isset($update['message']['entities']) // || + if (($from = isset($update['message']['from_id']) && !$this->peer_isset($update['message']['from_id'])) || + ($to = !$this->peer_isset($update['message']['to_id'])) || + ($via_bot = isset($update['message']['via_bot_id']) && !$this->peer_isset($update['message']['via_bot_id'])) || + ($entities = isset($update['message']['entities']) && !$this->entities_peer_isset($update['message']['entities'])) // || //isset($update['message']['fwd_from']) && !$this->fwd_peer_isset($update['message']['fwd_from']) ) { - $this->logger->logger('Not enough data for message update, getting difference...', \danog\MadelineProto\Logger::VERBOSE); + $log = ''; + if ($from) $log .= "from_id {$update['message']['from_id']}, "; + if ($to) $log .= "to_id ".json_encode($update['message']['to_id']).", "; + if ($via_bot) $log .= "via_bot {$update['message']['via_bot_id']}, "; + if ($entities) $log .= "entities ".json_encode($update['message']['entities']).", "; + $this->logger->logger("Not enough data: for message update $log, getting difference...", \danog\MadelineProto\Logger::VERBOSE); if ($channel_id !== false && $this->peer_isset($this->to_supergroup($channel_id))) { $this->get_channel_difference($channel_id); } else { @@ -513,7 +518,7 @@ trait UpdateHandler $this->get_config(); } if (in_array($update['_'], ['updateUserName', 'updateUserPhone', 'updateUserBlocked', 'updateUserPhoto', 'updateContactRegistered', 'updateContactLink'])) { - $id = $this->get_info($update)['bot_api_id']; + $id = $this->get_id($update); $this->full_chats[$id]['last_update'] = 0; $this->get_full_info($id); } diff --git a/src/danog/MadelineProto/Wrappers/Loop.php b/src/danog/MadelineProto/Wrappers/Loop.php index a05a8beb..d5e0f2fd 100644 --- a/src/danog/MadelineProto/Wrappers/Loop.php +++ b/src/danog/MadelineProto/Wrappers/Loop.php @@ -87,6 +87,7 @@ trait Loop if ($needs_restart) { $a = fsockopen((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? 'tls' : 'tcp') . '://' . $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT']); fwrite($a, $_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI'] . ' ' . $_SERVER['SERVER_PROTOCOL'] . "\r\n" . 'Host: ' . $_SERVER['SERVER_NAME'] . "\r\n\r\n"); + $this->logger->logger("Self-restarted"); } }); @@ -130,6 +131,7 @@ trait Loop if (php_sapi_name() === 'cli' || isset($GLOBALS['exited']) || headers_sent()) { return; } + $this->logger->logger($message); @ob_end_clean(); header('Connection: close'); ignore_user_abort(true);