Code cleanup

This commit is contained in:
Andrea Cavalli 2021-10-22 12:54:28 +02:00
parent cb024a114f
commit e0f70138c1
52 changed files with 306 additions and 291 deletions

View File

@ -13,7 +13,7 @@ ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = false ij_formatter_tags_enabled = false
ij_smart_tabs = false ij_smart_tabs = false
ij_visual_guides = 100,120 ij_visual_guides = 100, 120
ij_wrap_on_typing = false ij_wrap_on_typing = false
[.editorconfig] [.editorconfig]
@ -56,22 +56,22 @@ ij_shell_use_unix_line_separator = true
[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] [{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}]
ij_visual_guides = none ij_visual_guides = none
ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3 ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3
ij_html_align_attributes = true ij_html_align_attributes = true
ij_html_align_text = false ij_html_align_text = false
ij_html_attribute_wrap = normal ij_html_attribute_wrap = normal
ij_html_block_comment_at_first_column = true ij_html_block_comment_at_first_column = true
ij_html_do_not_align_children_of_min_lines = 0 ij_html_do_not_align_children_of_min_lines = 0
ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p
ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot
ij_html_enforce_quotes = false ij_html_enforce_quotes = false
ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var
ij_html_keep_blank_lines = 2 ij_html_keep_blank_lines = 2
ij_html_keep_indents_on_empty_lines = false ij_html_keep_indents_on_empty_lines = false
ij_html_keep_line_breaks = true ij_html_keep_line_breaks = true
ij_html_keep_line_breaks_in_text = true ij_html_keep_line_breaks_in_text = true
ij_html_keep_whitespaces = false ij_html_keep_whitespaces = false
ij_html_keep_whitespaces_inside = span,pre,textarea ij_html_keep_whitespaces_inside = span, pre, textarea
ij_html_line_comment_at_first_column = true ij_html_line_comment_at_first_column = true
ij_html_new_line_after_last_attribute = never ij_html_new_line_after_last_attribute = never
ij_html_new_line_before_first_attribute = never ij_html_new_line_before_first_attribute = never
@ -182,7 +182,7 @@ ij_java_for_statement_wrap = normal
ij_java_generate_final_locals = false ij_java_generate_final_locals = false
ij_java_generate_final_parameters = false ij_java_generate_final_parameters = false
ij_java_if_brace_force = if_multiline ij_java_if_brace_force = if_multiline
ij_java_imports_layout = $*,|,* ij_java_imports_layout = $*, |, *
ij_java_indent_case_from_switch = true ij_java_indent_case_from_switch = true
ij_java_insert_inner_class_imports = true ij_java_insert_inner_class_imports = true
ij_java_insert_override_annotation = true ij_java_insert_override_annotation = true

View File

@ -20,6 +20,7 @@
**Operating systems**: Linux, Windows, MacOS **Operating systems**: Linux, Windows, MacOS
**CPU architectures**: **CPU architectures**:
- i386/x86 (Linux, Windows) - i386/x86 (Linux, Windows)
- amd64/x86_64 (Linux, Windows, OSX) - amd64/x86_64 (Linux, Windows, OSX)
- armhf/armv7 (Linux) - armhf/armv7 (Linux)
@ -30,7 +31,9 @@
**Required libraries for Linux: OpenSSL and zlib** **Required libraries for Linux: OpenSSL and zlib**
### Install OpenSSL on macOS ### Install OpenSSL on macOS
You must install `openssl@1.1` using the <a href="https://brew.sh">brew package manager </a>, then link openssl to `/usr/local/opt/openssl`
You must install `openssl@1.1` using the <a href="https://brew.sh">brew package manager </a>, then link openssl
to `/usr/local/opt/openssl`
If you don't know how to do this, type the following commands in your terminal: If you don't know how to do this, type the following commands in your terminal:
@ -40,9 +43,13 @@ ln -sf /usr/local/Cellar/openssl@1.1/1.1.1l /usr/local/opt/openssl
``` ```
## 📚 How to use the library ## 📚 How to use the library
### Setting up the library using Maven ### Setting up the library using Maven
If you are using Maven, edit your `pom.xml` file as below: If you are using Maven, edit your `pom.xml` file as below:
```xml ```xml
<project> <project>
<repositories> <repositories>
@ -73,13 +80,17 @@ If you are using Maven, edit your `pom.xml` file as below:
</dependencies> </dependencies>
</project> </project>
``` ```
Replace `VERSION` with the latest release version, you can find it [here](https://github.com/tdlight-team/tdlight-java/releases).
Replace `NATIVES_VERSION` with the latest native version. Replace `VERSION` with the latest release version, you can find
Make sure that you are using the correct natives version for the release that you are using. it [here](https://github.com/tdlight-team/tdlight-java/releases).
Replace `NATIVES_VERSION` with the latest native version. Make sure that you are using the correct natives version for
the release that you are using.
## Setting up the library using Gradle ## Setting up the library using Gradle
If you are using Gradle, add the following lines into your `build.gradle` file If you are using Gradle, add the following lines into your `build.gradle` file
```groovy ```groovy
repositories { repositories {
maven { url "https://mvn.mchv.eu/repository/mchv/" } maven { url "https://mvn.mchv.eu/repository/mchv/" }
@ -90,13 +101,17 @@ dependencies {
// Include other native versions that you want, for example for windows, osx, ... // Include other native versions that you want, for example for windows, osx, ...
} }
``` ```
Replace `VERSION` with the latest release version, you can find it [here](https://github.com/tdlight-team/tdlight-java/releases).
Replace `NATIVES_VERSION` with the latest native version. Replace `VERSION` with the latest release version, you can find
Make sure that you are using the correct natives version for the release that you are using. it [here](https://github.com/tdlight-team/tdlight-java/releases).
Replace `NATIVES_VERSION` with the latest native version. Make sure that you are using the correct natives version for
the release that you are using.
## ⚒ Native dependencies ## ⚒ Native dependencies
To use TDLight Java you need to include one or more native dependencies: To use TDLight Java you need to include one or more native dependencies:
- `tdlight-natives-linux-amd64` - `tdlight-natives-linux-amd64`
- `tdlight-natives-linux-aarch64` - `tdlight-natives-linux-aarch64`
- `tdlight-natives-linux-x86` - `tdlight-natives-linux-x86`
@ -107,26 +122,37 @@ To use TDLight Java you need to include one or more native dependencies:
- `tdlight-natives-osx-amd64` - `tdlight-natives-osx-amd64`
## Usage ## Usage
An example on how to use TDLight Java can be found here: [Example.java](https://github.com/tdlight-team/tdlight-java/blob/master/example/src/main/java/it.tdlight.example/Example.java)
An example on how to use TDLight Java can be found
here: [Example.java](https://github.com/tdlight-team/tdlight-java/blob/master/example/src/main/java/it.tdlight.example/Example.java)
### Advanced usage ### Advanced usage
If you want to disable the automatic runtime shutdown hook, you should set the property `it.tdlight.enableShutdownHooks` to `false`
If you want to disable the automatic runtime shutdown hook, you should set the property `it.tdlight.enableShutdownHooks`
to `false`
### TDLight methods documentation ### TDLight methods documentation
[TdApi JavaDoc](https://tdlight-team.github.io/tdlight-docs) [TdApi JavaDoc](https://tdlight-team.github.io/tdlight-docs)
### TDLight extended features ### TDLight extended features
TDLight has some extended features compared to TDLib, that you can see on the [TDLight official repository](https://github.com/tdlight-team/tdlight#tdlight-extra-features).
TDLight has some extended features compared to TDLib, that you can see on
the [TDLight official repository](https://github.com/tdlight-team/tdlight#tdlight-extra-features).
## About ## About
### **License** ### **License**
TDLight is licensed by Andrea Cavalli <andrea@cavallium.it> under the terms of the GNU Lesser General Public License 3 TDLight is licensed by Andrea Cavalli <andrea@cavallium.it> under the terms of the GNU Lesser General Public License 3
### **Libraries licenses** ### **Libraries licenses**
JTDLib is licensed by Ernesto Castellotti <erny.castell@gmail.com> under the terms of the GNU Lesser General Public License 3 JTDLib is licensed by Ernesto Castellotti <erny.castell@gmail.com> under the terms of the GNU Lesser General Public
License 3
TDLib is licensed by Aliaksei Levin <levlam@telegram.org> and Arseny Smirnov <arseny30@gmail.com> under the terms of the Boost Software License TDLib is licensed by Aliaksei Levin <levlam@telegram.org> and Arseny Smirnov <arseny30@gmail.com> under the terms of the
Boost Software License
OpenSSL is licensed under the terms of Apache License v2 OpenSSL is licensed under the terms of Apache License v2

View File

@ -1,16 +1,16 @@
package it.tdlight.example; package it.tdlight.example;
import it.tdlight.common.TelegramClient;
import it.tdlight.tdlight.ClientManager;
import it.tdlight.common.Init; import it.tdlight.common.Init;
import it.tdlight.common.TelegramClient;
import it.tdlight.common.utils.CantLoadLibrary; import it.tdlight.common.utils.CantLoadLibrary;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.tdlight.ClientManager;
/** /**
* This is an advanced example that uses directly the native client without using the SimpleClient implementation * This is an advanced example that uses directly the native client without using the SimpleClient implementation
*/ */
public class AdvancedExample { public class AdvancedExample {
public static void main(String[] args) throws CantLoadLibrary { public static void main(String[] args) throws CantLoadLibrary {
// Initialize TDLight native libraries // Initialize TDLight native libraries
Init.start(); Init.start();

View File

@ -1,16 +1,11 @@
package it.tdlight.example; package it.tdlight.example;
import it.tdlight.client.APIToken; import it.tdlight.client.APIToken;
import it.tdlight.client.Authenticable;
import it.tdlight.client.AuthenticationData; import it.tdlight.client.AuthenticationData;
import it.tdlight.client.CommandHandler; import it.tdlight.client.CommandHandler;
import it.tdlight.client.Result;
import it.tdlight.client.SimpleTelegramClient; import it.tdlight.client.SimpleTelegramClient;
import it.tdlight.client.TDLibSettings; import it.tdlight.client.TDLibSettings;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.Init; import it.tdlight.common.Init;
import it.tdlight.common.ResultHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.common.utils.CantLoadLibrary; import it.tdlight.common.utils.CantLoadLibrary;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationState; import it.tdlight.jni.TdApi.AuthorizationState;
@ -21,24 +16,11 @@ import it.tdlight.jni.TdApi.MessageSenderUser;
import it.tdlight.jni.TdApi.MessageText; import it.tdlight.jni.TdApi.MessageText;
import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import it.tdlight.jni.TdApi.UpdateNewMessage; import it.tdlight.jni.TdApi.UpdateNewMessage;
import it.tdlight.tdlight.ClientManager;
import java.io.BufferedReader;
import java.io.IOError;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.NavigableSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/** /**
* Example class for TDLight Java * Example class for TDLight Java
* * <p>
* The documentation of the TDLight functions can be found here: * The documentation of the TDLight functions can be found here: https://tdlight-team.github.io/tdlight-docs
* https://tdlight-team.github.io/tdlight-docs
*/ */
public final class Example { public final class Example {

View File

@ -1,5 +1,7 @@
package it.tdlight.common.utils; package it.tdlight.common.utils;
public final class LibraryVersion { public final class LibraryVersion {
public static final String VERSION = "${project.version}"; public static final String VERSION = "${project.version}";
public static final String NATIVES_VERSION = "4.0.${nativesRevisionNumber}${nativesRevisionSuffix}"; public static final String NATIVES_VERSION = "4.0.${nativesRevisionNumber}${nativesRevisionSuffix}";
public static final String IMPLEMENTATION_NAME = "tdlib"; public static final String IMPLEMENTATION_NAME = "tdlib";

View File

@ -1,5 +1,7 @@
package it.tdlight.common.utils; package it.tdlight.common.utils;
public final class LibraryVersion { public final class LibraryVersion {
public static final String VERSION = "${project.version}"; public static final String VERSION = "${project.version}";
public static final String NATIVES_VERSION = "4.0.${nativesRevisionNumber}${nativesRevisionSuffix}"; public static final String NATIVES_VERSION = "4.0.${nativesRevisionNumber}${nativesRevisionSuffix}";
public static final String IMPLEMENTATION_NAME = "tdlight"; public static final String IMPLEMENTATION_NAME = "tdlight";

View File

@ -4,6 +4,7 @@ import java.util.Objects;
@SuppressWarnings("unused") @SuppressWarnings("unused")
final class AuthenticationDataImpl implements AuthenticationData { final class AuthenticationDataImpl implements AuthenticationData {
private final Long userPhoneNumber; private final Long userPhoneNumber;
private final String botToken; private final String botToken;

View File

@ -1,9 +1,7 @@
package it.tdlight.client; package it.tdlight.client;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationStateReady; import it.tdlight.jni.TdApi.AuthorizationStateReady;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.GetMe; import it.tdlight.jni.TdApi.GetMe;
import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import it.tdlight.jni.TdApi.User; import it.tdlight.jni.TdApi.User;

View File

@ -1,18 +1,12 @@
package it.tdlight.client; package it.tdlight.client;
import it.tdlight.common.ExceptionHandler; import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.common.utils.ScannerUtils; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi.AuthorizationStateWaitPhoneNumber;
import it.tdlight.jni.TdApi.AuthorizationStateWaitEncryptionKey; import it.tdlight.jni.TdApi.PhoneNumberAuthenticationSettings;
import it.tdlight.jni.TdApi.AuthorizationStateWaitPhoneNumber; import it.tdlight.jni.TdApi.SetAuthenticationPhoneNumber;
import it.tdlight.jni.TdApi.CheckDatabaseEncryptionKey; import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.PhoneNumberAuthenticationSettings;
import it.tdlight.jni.TdApi.SetAuthenticationPhoneNumber;
import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitAuthenticationDataHandler implements GenericUpdateHandler<UpdateAuthorizationState> { final class AuthorizationStateWaitAuthenticationDataHandler implements GenericUpdateHandler<UpdateAuthorizationState> {

View File

@ -2,15 +2,9 @@ package it.tdlight.client;
import it.tdlight.common.ExceptionHandler; import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationStateWaitCode; import it.tdlight.jni.TdApi.AuthorizationStateWaitCode;
import it.tdlight.jni.TdApi.AuthorizationStateWaitOtherDeviceConfirmation;
import it.tdlight.jni.TdApi.CheckAuthenticationCode; import it.tdlight.jni.TdApi.CheckAuthenticationCode;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Function;
import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitCodeHandler implements GenericUpdateHandler<UpdateAuthorizationState> { final class AuthorizationStateWaitCodeHandler implements GenericUpdateHandler<UpdateAuthorizationState> {
@ -29,8 +23,7 @@ final class AuthorizationStateWaitCodeHandler implements GenericUpdateHandler<Up
@Override @Override
public void onUpdate(UpdateAuthorizationState update) { public void onUpdate(UpdateAuthorizationState update) {
if (update.authorizationState.getConstructor() == AuthorizationStateWaitCode.CONSTRUCTOR) { if (update.authorizationState.getConstructor() == AuthorizationStateWaitCode.CONSTRUCTOR) {
AuthorizationStateWaitCode authorizationState = AuthorizationStateWaitCode authorizationState = (AuthorizationStateWaitCode) update.authorizationState;
(AuthorizationStateWaitCode) update.authorizationState;
ParameterInfo parameterInfo = new ParameterInfoCode(authorizationState.codeInfo.phoneNumber, ParameterInfo parameterInfo = new ParameterInfoCode(authorizationState.codeInfo.phoneNumber,
authorizationState.codeInfo.nextType, authorizationState.codeInfo.nextType,
authorizationState.codeInfo.timeout, authorizationState.codeInfo.timeout,

View File

@ -3,14 +3,8 @@ package it.tdlight.client;
import it.tdlight.common.ExceptionHandler; import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi.AuthorizationStateWaitEncryptionKey; import it.tdlight.jni.TdApi.AuthorizationStateWaitEncryptionKey;
import it.tdlight.jni.TdApi.AuthorizationStateWaitTdlibParameters;
import it.tdlight.jni.TdApi.CheckDatabaseEncryptionKey; import it.tdlight.jni.TdApi.CheckDatabaseEncryptionKey;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.SetTdlibParameters;
import it.tdlight.jni.TdApi.TdlibParameters;
import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitEncryptionKeyHandler implements GenericUpdateHandler<UpdateAuthorizationState> { final class AuthorizationStateWaitEncryptionKeyHandler implements GenericUpdateHandler<UpdateAuthorizationState> {

View File

@ -1,6 +1,5 @@
package it.tdlight.client; package it.tdlight.client;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationStateClosed; import it.tdlight.jni.TdApi.AuthorizationStateClosed;
import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateAuthorizationState;

View File

@ -1,12 +1,10 @@
package it.tdlight.client; package it.tdlight.client;
import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi.AuthorizationStateWaitOtherDeviceConfirmation; import it.tdlight.jni.TdApi.AuthorizationStateWaitOtherDeviceConfirmation;
import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateAuthorizationState;
final class AuthorizationStateWaitOtherDeviceConfirmationHandler final class AuthorizationStateWaitOtherDeviceConfirmationHandler implements
implements GenericUpdateHandler<UpdateAuthorizationState> { GenericUpdateHandler<UpdateAuthorizationState> {
private final ClientInteraction clientInteraction; private final ClientInteraction clientInteraction;
@ -17,8 +15,7 @@ final class AuthorizationStateWaitOtherDeviceConfirmationHandler
@Override @Override
public void onUpdate(UpdateAuthorizationState update) { public void onUpdate(UpdateAuthorizationState update) {
if (update.authorizationState.getConstructor() == AuthorizationStateWaitOtherDeviceConfirmation.CONSTRUCTOR) { if (update.authorizationState.getConstructor() == AuthorizationStateWaitOtherDeviceConfirmation.CONSTRUCTOR) {
AuthorizationStateWaitOtherDeviceConfirmation authorizationState = AuthorizationStateWaitOtherDeviceConfirmation authorizationState = (AuthorizationStateWaitOtherDeviceConfirmation) update.authorizationState;
(AuthorizationStateWaitOtherDeviceConfirmation) update.authorizationState;
ParameterInfo parameterInfo = new ParameterInfoNotifyLink(authorizationState.link); ParameterInfo parameterInfo = new ParameterInfoNotifyLink(authorizationState.link);
clientInteraction.onParameterRequest(InputParameter.NOTIFY_LINK, parameterInfo); clientInteraction.onParameterRequest(InputParameter.NOTIFY_LINK, parameterInfo);
} }

View File

@ -2,15 +2,9 @@ package it.tdlight.client;
import it.tdlight.common.ExceptionHandler; import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi.AuthorizationStateWaitCode;
import it.tdlight.jni.TdApi.AuthorizationStateWaitPassword; import it.tdlight.jni.TdApi.AuthorizationStateWaitPassword;
import it.tdlight.jni.TdApi.CheckAuthenticationCode;
import it.tdlight.jni.TdApi.CheckAuthenticationPassword; import it.tdlight.jni.TdApi.CheckAuthenticationPassword;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Function;
import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitPasswordHandler implements GenericUpdateHandler<UpdateAuthorizationState> { final class AuthorizationStateWaitPasswordHandler implements GenericUpdateHandler<UpdateAuthorizationState> {
@ -29,8 +23,7 @@ final class AuthorizationStateWaitPasswordHandler implements GenericUpdateHandle
@Override @Override
public void onUpdate(UpdateAuthorizationState update) { public void onUpdate(UpdateAuthorizationState update) {
if (update.authorizationState.getConstructor() == AuthorizationStateWaitPassword.CONSTRUCTOR) { if (update.authorizationState.getConstructor() == AuthorizationStateWaitPassword.CONSTRUCTOR) {
AuthorizationStateWaitPassword authorizationState = AuthorizationStateWaitPassword authorizationState = (AuthorizationStateWaitPassword) update.authorizationState;
(AuthorizationStateWaitPassword) update.authorizationState;
ParameterInfo parameterInfo = new ParameterInfoPasswordHint(authorizationState.passwordHint, ParameterInfo parameterInfo = new ParameterInfoPasswordHint(authorizationState.passwordHint,
authorizationState.hasRecoveryEmailAddress, authorizationState.hasRecoveryEmailAddress,
authorizationState.recoveryEmailAddressPattern authorizationState.recoveryEmailAddressPattern

View File

@ -4,11 +4,8 @@ import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.AuthorizationStateWaitRegistration; import it.tdlight.jni.TdApi.AuthorizationStateWaitRegistration;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.RegisterUser; import it.tdlight.jni.TdApi.RegisterUser;
import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitRegistrationHandler implements GenericUpdateHandler<UpdateAuthorizationState> { final class AuthorizationStateWaitRegistrationHandler implements GenericUpdateHandler<UpdateAuthorizationState> {
@ -27,9 +24,10 @@ final class AuthorizationStateWaitRegistrationHandler implements GenericUpdateHa
@Override @Override
public void onUpdate(UpdateAuthorizationState update) { public void onUpdate(UpdateAuthorizationState update) {
if (update.authorizationState.getConstructor() == AuthorizationStateWaitRegistration.CONSTRUCTOR) { if (update.authorizationState.getConstructor() == AuthorizationStateWaitRegistration.CONSTRUCTOR) {
TdApi.AuthorizationStateWaitRegistration authorizationState = TdApi.AuthorizationStateWaitRegistration authorizationState = (TdApi.AuthorizationStateWaitRegistration) update.authorizationState;
(TdApi.AuthorizationStateWaitRegistration) update.authorizationState; clientInteraction.onParameterRequest(InputParameter.TERMS_OF_SERVICE,
clientInteraction.onParameterRequest(InputParameter.TERMS_OF_SERVICE, new ParameterInfoTermsOfService(authorizationState.termsOfService)); new ParameterInfoTermsOfService(authorizationState.termsOfService)
);
String firstName = clientInteraction.onParameterRequest(InputParameter.ASK_FIRST_NAME, new EmptyParameterInfo()); String firstName = clientInteraction.onParameterRequest(InputParameter.ASK_FIRST_NAME, new EmptyParameterInfo());
String lastName = clientInteraction.onParameterRequest(InputParameter.ASK_LAST_NAME, new EmptyParameterInfo()); String lastName = clientInteraction.onParameterRequest(InputParameter.ASK_LAST_NAME, new EmptyParameterInfo());
if (firstName == null || firstName.isEmpty()) { if (firstName == null || firstName.isEmpty()) {

View File

@ -3,12 +3,9 @@ package it.tdlight.client;
import it.tdlight.common.ExceptionHandler; import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi.AuthorizationStateWaitTdlibParameters; import it.tdlight.jni.TdApi.AuthorizationStateWaitTdlibParameters;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.SetTdlibParameters; import it.tdlight.jni.TdApi.SetTdlibParameters;
import it.tdlight.jni.TdApi.TdlibParameters; import it.tdlight.jni.TdApi.TdlibParameters;
import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateAuthorizationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
final class AuthorizationStateWaitTdlibParametersHandler implements GenericUpdateHandler<UpdateAuthorizationState> { final class AuthorizationStateWaitTdlibParametersHandler implements GenericUpdateHandler<UpdateAuthorizationState> {

View File

@ -2,7 +2,6 @@ package it.tdlight.client;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Chat; import it.tdlight.jni.TdApi.Chat;
import it.tdlight.jni.TdApi.User;
public interface CommandHandler { public interface CommandHandler {

View File

@ -3,7 +3,6 @@ package it.tdlight.client;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Chat; import it.tdlight.jni.TdApi.Chat;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Message; import it.tdlight.jni.TdApi.Message;
import it.tdlight.jni.TdApi.MessageText; import it.tdlight.jni.TdApi.MessageText;
import it.tdlight.jni.TdApi.UpdateNewMessage; import it.tdlight.jni.TdApi.UpdateNewMessage;
@ -36,15 +35,14 @@ final class CommandsHandler implements GenericUpdateHandler<UpdateNewMessage> {
public void onUpdate(UpdateNewMessage update) { public void onUpdate(UpdateNewMessage update) {
if (update.getConstructor() == UpdateNewMessage.CONSTRUCTOR) { if (update.getConstructor() == UpdateNewMessage.CONSTRUCTOR) {
Message message = update.message; Message message = update.message;
if (message.forwardInfo == null && !message.isChannelPost if (message.forwardInfo == null && !message.isChannelPost && (message.authorSignature == null
&& (message.authorSignature == null || message.authorSignature.isEmpty()) || message.authorSignature.isEmpty()) && message.content.getConstructor() == MessageText.CONSTRUCTOR) {
&& message.content.getConstructor() == MessageText.CONSTRUCTOR) {
MessageText messageText = (MessageText) message.content; MessageText messageText = (MessageText) message.content;
String text = messageText.text.text; String text = messageText.text.text;
if (text.startsWith("/")) { if (text.startsWith("/")) {
String[] parts = text.split(" ", 2); String[] parts = text.split(" ", 2);
if (parts.length == 1) { if (parts.length == 1) {
parts = new String[] {parts[0], ""}; parts = new String[]{parts[0], ""};
} }
if (parts.length == 2) { if (parts.length == 2) {
String currentUnsplittedCommandName = parts[0].substring(1); String currentUnsplittedCommandName = parts[0].substring(1);
@ -71,15 +69,12 @@ final class CommandsHandler implements GenericUpdateHandler<UpdateNewMessage> {
Set<CommandHandler> handlers = commandHandlers.getOrDefault(currentCommandName, Collections.emptySet()); Set<CommandHandler> handlers = commandHandlers.getOrDefault(currentCommandName, Collections.emptySet());
for (CommandHandler handler : handlers) { for (CommandHandler handler : handlers) {
client.send(new TdApi.GetChat(message.chatId), client.send(new TdApi.GetChat(message.chatId), response -> {
response -> {
if (response.getConstructor() == Error.CONSTRUCTOR) { if (response.getConstructor() == Error.CONSTRUCTOR) {
throw new TelegramError((Error) response); throw new TelegramError((Error) response);
} }
handler.onCommand((Chat) response, message.sender, arguments); handler.onCommand((Chat) response, message.sender, arguments);
}, }, error -> logger.warn("Error when handling the command {}", commandName, error));
error -> logger.warn("Error when handling the command {}", commandName, error)
);
} }
} }
} }

View File

@ -2,7 +2,6 @@ package it.tdlight.client;
import it.tdlight.common.utils.ScannerUtils; import it.tdlight.common.utils.ScannerUtils;
import java.util.Locale; import java.util.Locale;
import java.util.stream.Collector;
final class ConsoleInteractiveAuthenticationData implements AuthenticationData { final class ConsoleInteractiveAuthenticationData implements AuthenticationData {
@ -57,10 +56,14 @@ final class ConsoleInteractiveAuthenticationData implements AuthenticationData {
} }
private void initializeIfNeeded() { private void initializeIfNeeded() {
if (initialized) return; if (initialized) {
return;
}
synchronized (LOCK) { synchronized (LOCK) {
if (initialized) return; if (initialized) {
return;
}
String choice; String choice;
@ -68,7 +71,9 @@ final class ConsoleInteractiveAuthenticationData implements AuthenticationData {
String mode; String mode;
do { do {
choice = ScannerUtils choice = ScannerUtils
.askParameter("login", "Do you want to login using a bot [token], a [phone] number, or a [qr] code? [token/phone/qr]") .askParameter("login",
"Do you want to login using a bot [token], a [phone] number, or a [qr] code? [token/phone/qr]"
)
.trim() .trim()
.toLowerCase(Locale.ROOT); .toLowerCase(Locale.ROOT);
switch (choice) { switch (choice) {

View File

@ -1,8 +1,6 @@
package it.tdlight.client; package it.tdlight.client;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Interface for incoming responses from TDLib. * Interface for incoming responses from TDLib.

View File

@ -1,6 +1,5 @@
package it.tdlight.client; package it.tdlight.client;
import it.tdlight.jni.TdApi.Object;
import it.tdlight.jni.TdApi.Update; import it.tdlight.jni.TdApi.Update;
/** /**

View File

@ -1,10 +1,5 @@
package it.tdlight.client; package it.tdlight.client;
public enum InputParameter { public enum InputParameter {
ASK_FIRST_NAME, ASK_FIRST_NAME, ASK_LAST_NAME, ASK_CODE, ASK_PASSWORD, NOTIFY_LINK, TERMS_OF_SERVICE
ASK_LAST_NAME,
ASK_CODE,
ASK_PASSWORD,
NOTIFY_LINK,
TERMS_OF_SERVICE
} }

View File

@ -5,6 +5,7 @@ import java.util.Objects;
import java.util.StringJoiner; import java.util.StringJoiner;
public final class ParameterInfoCode implements ParameterInfo { public final class ParameterInfoCode implements ParameterInfo {
private final String phoneNumber; private final String phoneNumber;
private final AuthenticationCodeType nextType; private final AuthenticationCodeType nextType;
private final int timeout; private final int timeout;

View File

@ -5,6 +5,7 @@ import java.util.Objects;
import java.util.StringJoiner; import java.util.StringJoiner;
public final class ParameterInfoTermsOfService implements ParameterInfo { public final class ParameterInfoTermsOfService implements ParameterInfo {
private final TermsOfService termsOfService; private final TermsOfService termsOfService;
public ParameterInfoTermsOfService(TermsOfService termsOfService) { public ParameterInfoTermsOfService(TermsOfService termsOfService) {

View File

@ -33,16 +33,27 @@ final class ScannerClientInteraction implements ClientInteraction {
String question; String question;
boolean trim = false; boolean trim = false;
switch (parameter) { switch (parameter) {
case ASK_FIRST_NAME: question = "Enter first name"; trim = true; break; case ASK_FIRST_NAME:
case ASK_LAST_NAME: question = "Enter last name"; trim = true; break; question = "Enter first name";
trim = true;
break;
case ASK_LAST_NAME:
question = "Enter last name";
trim = true;
break;
case ASK_CODE: case ASK_CODE:
question = "Enter authentication code"; question = "Enter authentication code";
ParameterInfoCode codeInfo = ((ParameterInfoCode) parameterInfo); ParameterInfoCode codeInfo = ((ParameterInfoCode) parameterInfo);
question += "\n\tPhone number: " + codeInfo.getPhoneNumber(); question += "\n\tPhone number: " + codeInfo.getPhoneNumber();
question += "\n\tTimeout: " + codeInfo.getTimeout() + " seconds"; question += "\n\tTimeout: " + codeInfo.getTimeout() + " seconds";
question += "\n\tCode type: " + codeInfo.getType().getClass().getSimpleName().replace("AuthenticationCodeType", ""); question +=
"\n\tCode type: " + codeInfo.getType().getClass().getSimpleName().replace("AuthenticationCodeType", "");
if (codeInfo.getNextType() != null) { if (codeInfo.getNextType() != null) {
question += "\n\tNext code type: " + codeInfo.getNextType().getClass().getSimpleName().replace("AuthenticationCodeType", ""); question += "\n\tNext code type: " + codeInfo
.getNextType()
.getClass()
.getSimpleName()
.replace("AuthenticationCodeType", "");
} }
trim = true; trim = true;
break; break;
@ -82,7 +93,9 @@ final class ScannerClientInteraction implements ClientInteraction {
return ""; return "";
} }
break; break;
default: question = parameter.toString(); break; default:
question = parameter.toString();
break;
} }
String result = ScannerUtils.askParameter(who, question); String result = ScannerUtils.askParameter(who, question);
if (trim) { if (trim) {

View File

@ -10,7 +10,6 @@ import it.tdlight.common.internal.CommonClientManager;
import it.tdlight.common.utils.CantLoadLibrary; import it.tdlight.common.utils.CantLoadLibrary;
import it.tdlight.common.utils.LibraryVersion; import it.tdlight.common.utils.LibraryVersion;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Function; import it.tdlight.jni.TdApi.Function;
import it.tdlight.jni.TdApi.User; import it.tdlight.jni.TdApi.User;
import java.io.IOException; import java.io.IOException;
@ -49,13 +48,12 @@ public final class SimpleTelegramClient implements Authenticable {
private AuthenticationData authenticationData; private AuthenticationData authenticationData;
private final Map<String, Set<CommandHandler>> commandHandlers = new ConcurrentHashMap<>(); private final Map<String, Set<CommandHandler>> commandHandlers = new ConcurrentHashMap<>();
private final Set<ResultHandler<TdApi.Update>> updateHandlers private final Set<ResultHandler<TdApi.Update>> updateHandlers = new ConcurrentHashMap<ResultHandler<TdApi.Update>, Object>().keySet(
= new ConcurrentHashMap<ResultHandler<TdApi.Update>, Object>() new Object());
.keySet(new Object()); private final Set<ExceptionHandler> updateExceptionHandlers = new ConcurrentHashMap<ExceptionHandler, Object>().keySet(
private final Set<ExceptionHandler> updateExceptionHandlers = new ConcurrentHashMap<ExceptionHandler, Object>() new Object());
.keySet(new Object()); private final Set<ExceptionHandler> defaultExceptionHandlers = new ConcurrentHashMap<ExceptionHandler, Object>().keySet(
private final Set<ExceptionHandler> defaultExceptionHandlers = new ConcurrentHashMap<ExceptionHandler, Object>() new Object());
.keySet(new Object());
private final CountDownLatch closed = new CountDownLatch(1); private final CountDownLatch closed = new CountDownLatch(1);
@ -63,23 +61,35 @@ public final class SimpleTelegramClient implements Authenticable {
this.client = CommonClientManager.create(LibraryVersion.IMPLEMENTATION_NAME); this.client = CommonClientManager.create(LibraryVersion.IMPLEMENTATION_NAME);
this.settings = settings; this.settings = settings;
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitTdlibParametersHandler(client, settings, this::handleDefaultException)); new AuthorizationStateWaitTdlibParametersHandler(client, settings, this::handleDefaultException)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitEncryptionKeyHandler(client, this::handleDefaultException)); new AuthorizationStateWaitEncryptionKeyHandler(client, this::handleDefaultException)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitAuthenticationDataHandler(client, this, new AuthorizationStateWaitAuthenticationDataHandler(client, this, this::handleDefaultException)
this::handleDefaultException)); );
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitRegistrationHandler(client, new SimpleTelegramClientInteraction(), new AuthorizationStateWaitRegistrationHandler(client,
this::handleDefaultException)); new SimpleTelegramClientInteraction(),
this::handleDefaultException
)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitPasswordHandler(client, new SimpleTelegramClientInteraction(), new AuthorizationStateWaitPasswordHandler(client,
this::handleDefaultException)); new SimpleTelegramClientInteraction(),
this::handleDefaultException
)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitOtherDeviceConfirmationHandler(new SimpleTelegramClientInteraction())); new AuthorizationStateWaitOtherDeviceConfirmationHandler(new SimpleTelegramClientInteraction())
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitCodeHandler(client, new SimpleTelegramClientInteraction(), new AuthorizationStateWaitCodeHandler(client,
this::handleDefaultException)); new SimpleTelegramClientInteraction(),
this::handleDefaultException
)
);
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitForExit(this.closed)); this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateWaitForExit(this.closed));
AtomicReference<User> me = new AtomicReference<>(); AtomicReference<User> me = new AtomicReference<>();
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateReadyGetMe(client, me)); this.addUpdateHandler(TdApi.UpdateAuthorizationState.class, new AuthorizationStateReadyGetMe(client, me));
@ -133,8 +143,9 @@ public final class SimpleTelegramClient implements Authenticable {
} }
public <T extends TdApi.Update> void addCommandHandler(String commandName, CommandHandler handler) { public <T extends TdApi.Update> void addCommandHandler(String commandName, CommandHandler handler) {
Set<CommandHandler> handlers = this.commandHandlers Set<CommandHandler> handlers = this.commandHandlers.computeIfAbsent(commandName,
.computeIfAbsent(commandName, k -> new ConcurrentHashMap<CommandHandler, Object>().keySet(new Object())); k -> new ConcurrentHashMap<CommandHandler, Object>().keySet(new Object())
);
handlers.add(handler); handlers.add(handler);
} }

View File

@ -209,7 +209,8 @@ public final class TDLibSettings {
downloadedFilesDirectoryPath, downloadedFilesDirectoryPath,
fileDatabaseEnabled, fileDatabaseEnabled,
chatInfoDatabaseEnabled, chatInfoDatabaseEnabled,
messageDatabaseEnabled, apiToken, messageDatabaseEnabled,
apiToken,
systemLanguageCode, systemLanguageCode,
deviceModel, deviceModel,
systemVersion, systemVersion,

View File

@ -3,7 +3,6 @@ package it.tdlight.client;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Error; import it.tdlight.jni.TdApi.Error;
import java.util.Objects; import java.util.Objects;
import java.util.StringJoiner;
public final class TelegramError extends RuntimeException { public final class TelegramError extends RuntimeException {

View File

@ -1,7 +1,5 @@
package it.tdlight.common; package it.tdlight.common;
import it.tdlight.jni.TdApi.Object;
public interface ClientEventsHandler { public interface ClientEventsHandler {
int getClientId(); int getClientId();

View File

@ -1,7 +1,5 @@
package it.tdlight.common; package it.tdlight.common;
import it.tdlight.jni.TdApi.Object;
public interface EventsHandler { public interface EventsHandler {
void handleClientEvents(int clientId, void handleClientEvents(int clientId,

View File

@ -19,7 +19,6 @@ package it.tdlight.common;
import it.tdlight.common.utils.CantLoadLibrary; import it.tdlight.common.utils.CantLoadLibrary;
import it.tdlight.common.utils.LoadLibrary; import it.tdlight.common.utils.LoadLibrary;
import it.tdlight.common.utils.Os;
/** /**
* Init class to successfully initialize Tdlib * Init class to successfully initialize Tdlib

View File

@ -1,7 +1,7 @@
package it.tdlight.common; package it.tdlight.common;
import it.tdlight.tdnative.NativeLog;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.tdnative.NativeLog;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**

View File

@ -26,11 +26,14 @@ import java.util.StringJoiner;
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class Response { public final class Response {
private final long id; private final long id;
private final TdApi.Object object; private final TdApi.Object object;
/** /**
* Creates a response with eventId and object, do not create answers explicitly! you must receive the reply through a client. * Creates a response with eventId and object, do not create answers explicitly! you must receive the reply through a
* client.
*
* @param id TDLib request identifier, which corresponds to the response or 0 for incoming updates from TDLib. * @param id TDLib request identifier, which corresponds to the response or 0 for incoming updates from TDLib.
* @param object TDLib API object representing a response to a TDLib request or an incoming update. * @param object TDLib API object representing a response to a TDLib request or an incoming update.
*/ */
@ -41,6 +44,7 @@ public final class Response {
/** /**
* Get TDLib request identifier. * Get TDLib request identifier.
*
* @return TDLib request identifier, which corresponds to the response or 0 for incoming updates from TDLib. * @return TDLib request identifier, which corresponds to the response or 0 for incoming updates from TDLib.
*/ */
public long getId() { public long getId() {
@ -49,6 +53,7 @@ public final class Response {
/** /**
* Get TDLib API object. * Get TDLib API object.
*
* @return TDLib API object representing a response to a TDLib request or an incoming update. * @return TDLib API object representing a response to a TDLib request or an incoming update.
*/ */
public TdApi.Object getObject() { public TdApi.Object getObject() {

View File

@ -1,7 +1,5 @@
package it.tdlight.common; package it.tdlight.common;
public enum SignalType { public enum SignalType {
UPDATE, UPDATE, EXCEPTION, CLOSE
EXCEPTION,
CLOSE
} }

View File

@ -41,7 +41,8 @@ public interface TelegramClient {
* resultHandler. If it is null, then defaultExceptionHandler will be called. * resultHandler. If it is null, then defaultExceptionHandler will be called.
* @throws NullPointerException if query is null. * @throws NullPointerException if query is null.
*/ */
<R extends TdApi.Object> void send(TdApi.Function<R> query, ResultHandler<R> resultHandler, <R extends TdApi.Object> void send(TdApi.Function<R> query,
ResultHandler<R> resultHandler,
ExceptionHandler exceptionHandler); ExceptionHandler exceptionHandler);
/** /**

View File

@ -1,6 +1,5 @@
package it.tdlight.common; package it.tdlight.common;
import it.tdlight.jni.TdApi.Object;
import java.util.List; import java.util.List;
/** /**

View File

@ -5,6 +5,7 @@ import it.tdlight.common.ResultHandler;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
public final class Handler<R extends TdApi.Object> { public final class Handler<R extends TdApi.Object> {
private final ResultHandler<R> resultHandler; private final ResultHandler<R> resultHandler;
private final ExceptionHandler exceptionHandler; private final ExceptionHandler exceptionHandler;

View File

@ -6,7 +6,6 @@ import it.tdlight.common.ResultHandler;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.common.UpdatesHandler; import it.tdlight.common.UpdatesHandler;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Error;
import it.tdlight.jni.TdApi.Function; import it.tdlight.jni.TdApi.Function;
import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@ -46,8 +45,7 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
} }
@Override @Override
public void handleEvents(boolean isClosed, long[] eventIds, TdApi.Object[] events, public void handleEvents(boolean isClosed, long[] eventIds, TdApi.Object[] events, int arrayOffset, int arrayLength) {
int arrayOffset, int arrayLength) {
if (updatesHandler != null) { if (updatesHandler != null) {
LongArrayList idsToFilter = new LongArrayList(eventIds); LongArrayList idsToFilter = new LongArrayList(eventIds);
ObjectArrayList<TdApi.Object> eventsToFilter = new ObjectArrayList<>(events); ObjectArrayList<TdApi.Object> eventsToFilter = new ObjectArrayList<>(events);
@ -115,7 +113,9 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
*/ */
private void handleEvent(long eventId, TdApi.Object event) { private void handleEvent(long eventId, TdApi.Object event) {
logger.trace(TG_MARKER, "Received response {}: {}", eventId, event); logger.trace(TG_MARKER, "Received response {}: {}", eventId, event);
if (updatesHandler != null || updateHandler == null) throw new IllegalStateException(); if (updatesHandler != null || updateHandler == null) {
throw new IllegalStateException();
}
Handler<?> handler = eventId == 0 ? updateHandler : handlers.remove(eventId); Handler<?> handler = eventId == 0 ? updateHandler : handlers.remove(eventId);
handleResponse(eventId, event, handler); handleResponse(eventId, event, handler);
} }
@ -127,7 +127,8 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
if (exceptionHandler != null) { if (exceptionHandler != null) {
try { try {
exceptionHandler.onException(cause); exceptionHandler.onException(cause);
} catch (Throwable ignored) {} } catch (Throwable ignored) {
}
} }
} }
@ -152,7 +153,9 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
} }
private void createAndRegisterClient() { private void createAndRegisterClient() {
if (clientId != null) throw new UnsupportedOperationException("Can't initialize the same client twice!"); if (clientId != null) {
throw new UnsupportedOperationException("Can't initialize the same client twice!");
}
clientId = NativeClientAccess.create(); clientId = NativeClientAccess.create();
clientManager.registerClient(clientId, this); clientManager.registerClient(clientId, this);
logger.info(TG_MARKER, "Registered new client {}", clientId); logger.info(TG_MARKER, "Registered new client {}", clientId);
@ -162,7 +165,8 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
} }
@Override @Override
public <R extends TdApi.Object> void send(Function<R> query, ResultHandler<R> resultHandler, public <R extends TdApi.Object> void send(Function<R> query,
ResultHandler<R> resultHandler,
ExceptionHandler exceptionHandler) { ExceptionHandler exceptionHandler) {
logger.trace(TG_MARKER, "Trying to send {}", query); logger.trace(TG_MARKER, "Trying to send {}", query);
if (isClosedAndMaybeThrow(query)) { if (isClosedAndMaybeThrow(query)) {
@ -202,7 +206,6 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
} }
/** /**
*
* @param function function used to check if the check will be enforced or not. Can be null * @param function function used to check if the check will be enforced or not. Can be null
* @return true if closed * @return true if closed
*/ */

View File

@ -39,7 +39,6 @@ public final class InternalClientManager implements AutoCloseable {
} }
/** /**
*
* @return true if started as a result of this call * @return true if started as a result of this call
*/ */
public boolean startIfNeeded() { public boolean startIfNeeded() {
@ -73,22 +72,30 @@ public final class InternalClientManager implements AutoCloseable {
return clientManager; return clientManager;
} }
private void handleClientEvents(int clientId, boolean isClosed, long[] clientEventIds, TdApi.Object[] clientEvents, private void handleClientEvents(int clientId,
int arrayOffset, int arrayLength) { boolean isClosed,
long[] clientEventIds,
TdApi.Object[] clientEvents,
int arrayOffset,
int arrayLength) {
ClientEventsHandler handler = registeredClientEventHandlers.get(clientId); ClientEventsHandler handler = registeredClientEventHandlers.get(clientId);
if (handler != null) { if (handler != null) {
handler.handleEvents(isClosed, clientEventIds, clientEvents, arrayOffset, arrayLength); handler.handleEvents(isClosed, clientEventIds, clientEvents, arrayOffset, arrayLength);
} else { } else {
java.util.List<DroppedEvent> droppedEvents java.util.List<DroppedEvent> droppedEvents = getEffectivelyDroppedEvents(clientEventIds,
= getEffectivelyDroppedEvents(clientEventIds, clientEvents, arrayOffset, arrayLength); clientEvents,
arrayOffset,
arrayLength
);
if (!droppedEvents.isEmpty()) { if (!droppedEvents.isEmpty()) {
logger.error("Unknown client id \"{}\"! {} events have been dropped!", clientId, droppedEvents.size()); logger.error("Unknown client id \"{}\"! {} events have been dropped!", clientId, droppedEvents.size());
for (DroppedEvent droppedEvent : droppedEvents) { for (DroppedEvent droppedEvent : droppedEvents) {
logger.error("The following event, with id \"{}\", has been dropped: {}", logger.error("The following event, with id \"{}\", has been dropped: {}",
droppedEvent.id, droppedEvent.id,
droppedEvent.event); droppedEvent.event
);
} }
} }
} }
@ -103,8 +110,10 @@ public final class InternalClientManager implements AutoCloseable {
/** /**
* Get only events that have been dropped, ignoring synthetic errors related to the closure of a client * Get only events that have been dropped, ignoring synthetic errors related to the closure of a client
*/ */
private List<DroppedEvent> getEffectivelyDroppedEvents(long[] clientEventIds, TdApi.Object[] clientEvents, private List<DroppedEvent> getEffectivelyDroppedEvents(long[] clientEventIds,
int arrayOffset, int arrayLength) { TdApi.Object[] clientEvents,
int arrayOffset,
int arrayLength) {
java.util.List<DroppedEvent> droppedEvents = new ArrayList<>(arrayLength); java.util.List<DroppedEvent> droppedEvents = new ArrayList<>(arrayLength);
for (int i = arrayOffset; i < arrayOffset + arrayLength; i++) { for (int i = arrayOffset; i < arrayOffset + arrayLength; i++) {
long id = clientEventIds[i]; long id = clientEventIds[i];
@ -155,6 +164,7 @@ public final class InternalClientManager implements AutoCloseable {
} }
private static final class DroppedEvent { private static final class DroppedEvent {
private final long id; private final long id;
private final TdApi.Object event; private final TdApi.Object event;

View File

@ -2,8 +2,8 @@ package it.tdlight.common.internal;
import it.tdlight.common.ClientEventsHandler; import it.tdlight.common.ClientEventsHandler;
import it.tdlight.common.ExceptionHandler; import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.Signal;
import it.tdlight.common.ReactiveTelegramClient; import it.tdlight.common.ReactiveTelegramClient;
import it.tdlight.common.Signal;
import it.tdlight.common.SignalListener; import it.tdlight.common.SignalListener;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Error; import it.tdlight.jni.TdApi.Error;
@ -20,7 +20,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription; import org.reactivestreams.Subscription;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -60,8 +59,7 @@ public final class InternalReactiveClient implements ClientEventsHandler, Reacti
} }
@Override @Override
public void handleEvents(boolean isClosed, long[] eventIds, TdApi.Object[] events, public void handleEvents(boolean isClosed, long[] eventIds, TdApi.Object[] events, int arrayOffset, int arrayLength) {
int arrayOffset, int arrayLength) {
for (int i = arrayOffset; i < arrayOffset + arrayLength; i++) { for (int i = arrayOffset; i < arrayOffset + arrayLength; i++) {
handleEvent(eventIds[i], events[i]); handleEvent(eventIds[i], events[i]);
} }
@ -127,8 +125,11 @@ public final class InternalReactiveClient implements ClientEventsHandler, Reacti
} }
} }
if (timedOutHandlers.remove(eventId)) { if (timedOutHandlers.remove(eventId)) {
logger.trace(TG_MARKER, "Received event id \"{}\", but the event has been dropped because it" logger.trace(TG_MARKER,
+ "timed out some time ago! {}", eventId, event); "Received event id \"{}\", but the event has been dropped because it" + "timed out some time ago! {}",
eventId,
event
);
} else { } else {
logger.error(TG_MARKER, "Unknown event id \"{}\", the event has been dropped! {}", eventId, event); logger.error(TG_MARKER, "Unknown event id \"{}\", the event has been dropped! {}", eventId, event);
} }

View File

@ -4,6 +4,7 @@ import it.tdlight.common.ExceptionHandler;
import it.tdlight.common.UpdatesHandler; import it.tdlight.common.UpdatesHandler;
public final class MultiHandler { public final class MultiHandler {
private final UpdatesHandler updatesHandler; private final UpdatesHandler updatesHandler;
private final ExceptionHandler exceptionHandler; private final ExceptionHandler exceptionHandler;

View File

@ -1,8 +1,8 @@
package it.tdlight.common.internal; package it.tdlight.common.internal;
import it.tdlight.tdnative.NativeClient;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import it.tdlight.jni.TdApi.Function; import it.tdlight.jni.TdApi.Function;
import it.tdlight.tdnative.NativeClient;
final class NativeClientAccess extends NativeClient { final class NativeClientAccess extends NativeClient {

View File

@ -23,6 +23,7 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
)); ));
private static final int MAX_EVENTS = 100; private static final int MAX_EVENTS = 100;
private static final int[] originalSortingSource = new int[MAX_EVENTS]; private static final int[] originalSortingSource = new int[MAX_EVENTS];
static { static {
for (int i = 0; i < originalSortingSource.length; i++) { for (int i = 0; i < originalSortingSource.length; i++) {
originalSortingSource[i] = i; originalSortingSource[i] = i;
@ -44,8 +45,7 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
private int clientEventsLastUsedLength = 0; private int clientEventsLastUsedLength = 0;
private final CountDownLatch closeWait = new CountDownLatch(1); private final CountDownLatch closeWait = new CountDownLatch(1);
private final Set<Integer> registeredClients private final Set<Integer> registeredClients = new ConcurrentHashMap<Integer, java.lang.Object>().keySet(new java.lang.Object());
= new ConcurrentHashMap<Integer, java.lang.Object>().keySet(new java.lang.Object());
public ResponseReceiver(EventsHandler eventsHandler) { public ResponseReceiver(EventsHandler eventsHandler) {
@ -72,8 +72,8 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
int[] sortIndex; int[] sortIndex;
try { try {
boolean interrupted; boolean interrupted;
while (!(interrupted = Thread.interrupted()) while (!(interrupted = Thread.interrupted()) && ((!closeCalled.get() && !jvmShutdown.get())
&& ((!closeCalled.get() && !jvmShutdown.get()) || !registeredClients.isEmpty())) { || !registeredClients.isEmpty())) {
int resultsCount = NativeClientAccess.receive(clientIds, eventIds, events, 2.0 /*seconds*/); int resultsCount = NativeClientAccess.receive(clientIds, eventIds, events, 2.0 /*seconds*/);
if (resultsCount <= 0) { if (resultsCount <= 0) {
@ -101,8 +101,7 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
if (clientEventIds[j] == 0 if (clientEventIds[j] == 0
&& clientEvents[j].getConstructor() == TdApi.UpdateAuthorizationState.CONSTRUCTOR) { && clientEvents[j].getConstructor() == TdApi.UpdateAuthorizationState.CONSTRUCTOR) {
TdApi.AuthorizationState authorizationState TdApi.AuthorizationState authorizationState = ((TdApi.UpdateAuthorizationState) clientEvents[j]).authorizationState;
= ((TdApi.UpdateAuthorizationState) clientEvents[j]).authorizationState;
if (authorizationState.getConstructor() == TdApi.AuthorizationStateClosed.CONSTRUCTOR) { if (authorizationState.getConstructor() == TdApi.AuthorizationStateClosed.CONSTRUCTOR) {
lastClientClosed = true; lastClientClosed = true;
closedClients.add(clientId); closedClients.add(clientId);
@ -111,8 +110,13 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
} }
cleanClientEventsArray(lastClientIdEventsCount); cleanClientEventsArray(lastClientIdEventsCount);
eventsHandler.handleClientEvents(clientId, lastClientClosed, clientEventIds, clientEvents, eventsHandler.handleClientEvents(clientId,
0, lastClientIdEventsCount); lastClientClosed,
clientEventIds,
clientEvents,
0,
lastClientIdEventsCount
);
} }
if (i < resultsCount) { if (i < resultsCount) {
@ -146,7 +150,8 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
} }
Set<Integer> clientIds = eventsList.stream().map(e -> e.clientId).collect(Collectors.toSet()); Set<Integer> clientIds = eventsList.stream().map(e -> e.clientId).collect(Collectors.toSet());
for (int clientId : clientIds) { for (int clientId : clientIds) {
List<Event> clientEventsList = eventsList.stream() List<Event> clientEventsList = eventsList
.stream()
.filter(e -> e.clientId == clientId) .filter(e -> e.clientId == clientId)
.collect(Collectors.toList()); .collect(Collectors.toList());
boolean closed = false; boolean closed = false;
@ -156,8 +161,7 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
clientEvents[i] = e.event; clientEvents[i] = e.event;
if (e.eventId == 0 && e.event.getConstructor() == TdApi.UpdateAuthorizationState.CONSTRUCTOR) { if (e.eventId == 0 && e.event.getConstructor() == TdApi.UpdateAuthorizationState.CONSTRUCTOR) {
TdApi.AuthorizationState authorizationState TdApi.AuthorizationState authorizationState = ((TdApi.UpdateAuthorizationState) e.event).authorizationState;
= ((TdApi.UpdateAuthorizationState) e.event).authorizationState;
if (authorizationState.getConstructor() == TdApi.AuthorizationStateClosed.CONSTRUCTOR) { if (authorizationState.getConstructor() == TdApi.AuthorizationStateClosed.CONSTRUCTOR) {
closed = true; closed = true;
closedClients.add(clientId); closedClients.add(clientId);
@ -165,8 +169,13 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
} }
} }
cleanClientEventsArray(clientEventsList.size()); cleanClientEventsArray(clientEventsList.size());
eventsHandler.handleClientEvents(clientId, closed, clientEventIds, clientEvents, eventsHandler.handleClientEvents(clientId,
0, clientEventsList.size()); closed,
clientEventIds,
clientEvents,
0,
clientEventsList.size()
);
} }
} }
@ -206,7 +215,8 @@ public final class ResponseReceiver extends Thread implements AutoCloseable {
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
private int[] generateSortIndex(int from, int to, int[] data) { private int[] generateSortIndex(int from, int to, int[] data) {
int[] sortedIndices = Arrays.copyOfRange(originalSortingSource, from, to); int[] sortedIndices = Arrays.copyOfRange(originalSortingSource, from, to);
it.unimi.dsi.fastutil.Arrays.mergeSort(from, to, it.unimi.dsi.fastutil.Arrays.mergeSort(from,
to,
(o1, o2) -> Integer.compare(data[sortedIndices[o1]], data[sortedIndices[o2]]), (o1, o2) -> Integer.compare(data[sortedIndices[o1]], data[sortedIndices[o2]]),
new IntSwapper(sortedIndices) new IntSwapper(sortedIndices)
); );

View File

@ -17,12 +17,11 @@
package it.tdlight.common.utils; package it.tdlight.common.utils;
import java.io.IOException;
/** /**
* An exception that is thrown when the LoadLibrary class fails to load the library. * An exception that is thrown when the LoadLibrary class fails to load the library.
*/ */
public final class CantLoadLibrary extends Exception { public final class CantLoadLibrary extends Exception {
/** /**
* Creates a new CantLoadLibrary exception. * Creates a new CantLoadLibrary exception.
*/ */

View File

@ -19,13 +19,13 @@ package it.tdlight.common.utils;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.lang.reflect.InvocationTargetException;
/** /**
* The class to load the libraries needed to run Tdlib * The class to load the libraries needed to run Tdlib

View File

@ -1,8 +1,5 @@
package it.tdlight.common.utils; package it.tdlight.common.utils;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.LockSupport;
public class SpinWaitSupport { public class SpinWaitSupport {

View File

@ -1,8 +1,8 @@
package it.tdlight.tdlib; package it.tdlight.tdlib;
import it.tdlight.common.internal.CommonClientManager;
import it.tdlight.common.ReactiveTelegramClient; import it.tdlight.common.ReactiveTelegramClient;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.common.internal.CommonClientManager;
/** /**
* Interface for interaction with TDLib. * Interface for interaction with TDLib.

View File

@ -1,8 +1,8 @@
package it.tdlight.tdlight; package it.tdlight.tdlight;
import it.tdlight.common.internal.CommonClientManager;
import it.tdlight.common.ReactiveTelegramClient; import it.tdlight.common.ReactiveTelegramClient;
import it.tdlight.common.TelegramClient; import it.tdlight.common.TelegramClient;
import it.tdlight.common.internal.CommonClientManager;
/** /**
* Interface for interaction with TDLight. * Interface for interaction with TDLight.

View File

@ -6,10 +6,13 @@ public class NativeClient {
protected static native int createNativeClient(); protected static native int createNativeClient();
protected static native <R extends TdApi.Object> void nativeClientSend(int nativeClientId, long eventId, protected static native <R extends TdApi.Object> void nativeClientSend(int nativeClientId,
long eventId,
TdApi.Function<R> function); TdApi.Function<R> function);
protected static native int nativeClientReceive(int[] clientIds, long[] eventIds, TdApi.Object[] events, protected static native int nativeClientReceive(int[] clientIds,
long[] eventIds,
TdApi.Object[] events,
double timeout); double timeout);
protected static native <R extends TdApi.Object> TdApi.Object nativeClientExecute(TdApi.Function<R> function); protected static native <R extends TdApi.Object> TdApi.Object nativeClientExecute(TdApi.Function<R> function);

View File

@ -1,7 +1,6 @@
package it.tdlight.tdnative; package it.tdlight.tdnative;
import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**