Add test numbers

This commit is contained in:
Andrea Cavalli 2023-05-14 23:05:30 +02:00
parent 2a87d69088
commit 6a7ba6d412
10 changed files with 88 additions and 36 deletions

5
.gitignore vendored
View File

@ -95,7 +95,4 @@ parent/.classpath
tdlight-java/target-snapshot/
tdlight-java-8/target-snapshot/
/example-tdlight-session/data/db.sqlite
/example-tdlight-session/data/db.sqlite-shm
/example-tdlight-session/data/db.sqlite-wal
/example-tdlight-session/data/td.binlog
/example-tdlight-session/

View File

@ -26,7 +26,7 @@
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>tdlight-java-bom</artifactId>
<version>3.0.0.0-SNAPSHOT</version>
<version>3.0.2+td.1.18.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -54,7 +54,7 @@
</dependency>
<dependency>
<groupId>it.tdlight</groupId>
<artifactId>osx_amd64</artifactId>
<artifactId>macos_amd64</artifactId>
</dependency>
-->

View File

@ -44,6 +44,8 @@ public final class Example {
// Configure the client
TDLibSettings settings = TDLibSettings.create(apiToken);
// This is an example, remove this line to use the real telegram datacenters!
settings.setUseTestDatacenter(true);
// Configure the session directory
Path sessionPath = Paths.get("example-tdlight-session");
@ -54,7 +56,7 @@ public final class Example {
SimpleTelegramClientBuilder clientBuilder = clientFactory.builder(settings);
// Configure the authentication info
ConsoleInteractiveAuthenticationData authenticationData = AuthenticationSupplier.consoleLogin();
SimpleAuthenticationSupplier<?> authenticationData = AuthenticationSupplier.testUser(3210); // Replace with AuthenticationSupplier.consoleLogin(), or .user(xxx), or .bot(xxx);
// Add an example update handler that prints when the bot is started
clientBuilder.addUpdateHandler(TdApi.UpdateAuthorizationState.class, Example::onUpdateAuthorizationState);

View File

@ -8,6 +8,7 @@ import it.tdlight.util.CleanSupport.CleanableSupport;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.StampedLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -92,9 +93,9 @@ public class ClientFactory implements AutoCloseable {
TdApi.Object[] clientEvents,
int arrayOffset,
int arrayLength) {
var eventsHandlingLock = state.getEventsHandlingLock();
StampedLock eventsHandlingLock = state.getEventsHandlingLock();
boolean closeWriteLockAcquisitionFailed = false;
var stamp = eventsHandlingLock.readLock();
long stamp = eventsHandlingLock.readLock();
try {
ClientEventsHandler handler = state.getClientEventsHandler(clientId);
@ -119,7 +120,7 @@ public class ClientFactory implements AutoCloseable {
}
if (isClosed) {
var writeLockStamp = eventsHandlingLock.tryConvertToWriteLock(stamp);
long writeLockStamp = eventsHandlingLock.tryConvertToWriteLock(stamp);
if (writeLockStamp != 0L) {
stamp = writeLockStamp;
removeClientEventHandlers(clientId);

View File

@ -152,7 +152,7 @@ final class InternalClient implements ClientEventsHandler, TelegramClient {
private void createAndRegisterClient() {
InternalClientsState clientManagerState = this.clientManagerState;
final StampedLock eventsHandlingLock = clientManagerState.getEventsHandlingLock();
var stamp = eventsHandlingLock.writeLock();
long stamp = eventsHandlingLock.writeLock();
try {
if (clientId != null) {
throw new UnsupportedOperationException("Can't initialize the same client twice!");

View File

@ -15,6 +15,7 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.StampedLock;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscription;
import org.slf4j.Logger;
@ -165,8 +166,8 @@ final class InternalReactiveClient implements ClientEventsHandler, ReactiveTeleg
}
logger.debug(TG_MARKER, "Creating new client");
clientId = NativeClientAccess.create();
var eventsHandlingLock = clientManagerState.getEventsHandlingLock();
var stamp = eventsHandlingLock.writeLock();
StampedLock eventsHandlingLock = clientManagerState.getEventsHandlingLock();
long stamp = eventsHandlingLock.writeLock();
try {
logger.debug(TG_MARKER, "Registering new client {}", clientId);
clientManagerState.registerClient(clientId, this);

View File

@ -10,12 +10,13 @@ final class AuthenticationDataImpl implements SimpleAuthenticationSupplier<Authe
private final String userPhoneNumber;
private final String botToken;
private final boolean test;
/**
* Safe string representation of the bot token
*/
private final String botTokenId;
AuthenticationDataImpl(String userPhoneNumber, String botToken) {
AuthenticationDataImpl(String userPhoneNumber, String botToken, boolean test) {
if ((userPhoneNumber == null) == (botToken == null)) {
throw new IllegalArgumentException("Please use either a bot token or a phone number");
}
@ -26,6 +27,7 @@ final class AuthenticationDataImpl implements SimpleAuthenticationSupplier<Authe
}
this.userPhoneNumber = userPhoneNumber;
this.botToken = botToken;
this.test = test;
if (botToken != null) {
String[] parts = botToken.split(":", 2);
if (parts.length > 0) {
@ -48,6 +50,10 @@ final class AuthenticationDataImpl implements SimpleAuthenticationSupplier<Authe
return botToken != null;
}
public boolean isTest() {
return test;
}
@Override
public String getUserPhoneNumber() {
if (userPhoneNumber == null) {
@ -66,10 +72,16 @@ final class AuthenticationDataImpl implements SimpleAuthenticationSupplier<Authe
@Override
public String toString() {
String value;
if (userPhoneNumber != null) {
return userPhoneNumber;
value = userPhoneNumber;
} else {
return botTokenId;
value = botTokenId;
}
if (test) {
return value + " (test)";
} else {
return value;
}
}
@ -82,12 +94,13 @@ final class AuthenticationDataImpl implements SimpleAuthenticationSupplier<Authe
return false;
}
AuthenticationDataImpl that = (AuthenticationDataImpl) o;
return Objects.equals(userPhoneNumber, that.userPhoneNumber) && Objects.equals(botToken, that.botToken);
return Objects.equals(userPhoneNumber, that.userPhoneNumber) && Objects.equals(botToken, that.botToken)
&& Objects.equals(test, that.test);
}
@Override
public int hashCode() {
return Objects.hash(userPhoneNumber, botToken);
return Objects.hash(userPhoneNumber, botToken, test);
}
@Override

View File

@ -4,6 +4,20 @@ import java.util.concurrent.CompletableFuture;
public interface AuthenticationSupplier<T extends AuthenticationData> {
/**
* User used in Telegram Test Servers
* @param value any number from 0001 to 9999
*/
static SimpleAuthenticationSupplier<?> testUser(int value) {
if (value < 1) {
throw new IllegalArgumentException("value must be greater than 0");
}
if (value > 9999) {
throw new IllegalArgumentException("value must be lower than 10000");
}
return new AuthenticationDataImpl("999664" + value, null, true);
}
CompletableFuture<T> get();
static SimpleAuthenticationSupplier<?> qrCode() {
@ -19,11 +33,11 @@ public interface AuthenticationSupplier<T extends AuthenticationData> {
}
static SimpleAuthenticationSupplier<?> user(String userPhoneNumber) {
return new AuthenticationDataImpl(userPhoneNumber, null);
return new AuthenticationDataImpl(userPhoneNumber, null, false);
}
static SimpleAuthenticationSupplier<?> bot(String botToken) {
return new AuthenticationDataImpl(null, botToken);
return new AuthenticationDataImpl(null, botToken, false);
}
static ConsoleInteractiveAuthenticationData consoleLogin() {

View File

@ -11,13 +11,16 @@ final class AuthorizationStateWaitCodeHandler implements GenericUpdateHandler<Up
private final TelegramClient client;
private final ClientInteraction clientInteraction;
private final String testCode;
private final ExceptionHandler exceptionHandler;
public AuthorizationStateWaitCodeHandler(TelegramClient client,
ClientInteraction clientInteraction,
String testCode,
ExceptionHandler exceptionHandler) {
this.client = client;
this.clientInteraction = clientInteraction;
this.testCode = testCode;
this.exceptionHandler = exceptionHandler;
}
@ -25,23 +28,31 @@ final class AuthorizationStateWaitCodeHandler implements GenericUpdateHandler<Up
public void onUpdate(UpdateAuthorizationState update) {
if (update.authorizationState.getConstructor() == AuthorizationStateWaitCode.CONSTRUCTOR) {
AuthorizationStateWaitCode authorizationState = (AuthorizationStateWaitCode) update.authorizationState;
ParameterInfo parameterInfo = new ParameterInfoCode(authorizationState.codeInfo.phoneNumber,
authorizationState.codeInfo.nextType,
authorizationState.codeInfo.timeout,
authorizationState.codeInfo.type
);
clientInteraction.onParameterRequest(InputParameter.ASK_CODE, parameterInfo).whenComplete((code, ex) -> {
if (ex != null) {
exceptionHandler.onException(ex);
return;
}
CheckAuthenticationCode response = new CheckAuthenticationCode(code);
client.send(response, ok -> {
if (ok.getConstructor() == TdApi.Error.CONSTRUCTOR) {
throw new TelegramError((TdApi.Error) ok);
if (testCode != null) {
sendCode(testCode);
} else {
ParameterInfo parameterInfo = new ParameterInfoCode(authorizationState.codeInfo.phoneNumber,
authorizationState.codeInfo.nextType,
authorizationState.codeInfo.timeout,
authorizationState.codeInfo.type
);
clientInteraction.onParameterRequest(InputParameter.ASK_CODE, parameterInfo).whenComplete((code, ex) -> {
if (ex != null) {
exceptionHandler.onException(ex);
return;
}
}, exceptionHandler);
});
sendCode(code);
});
}
}
}
private void sendCode(String code) {
CheckAuthenticationCode response = new CheckAuthenticationCode(code);
client.send(response, ok -> {
if (ok.getConstructor() == TdApi.Error.CONSTRUCTOR) {
throw new TelegramError((TdApi.Error) ok);
}
}, exceptionHandler);
}
}

View File

@ -105,6 +105,7 @@ public final class SimpleTelegramClient implements Authenticable, MutableTelegra
this.addUpdateHandler(TdApi.UpdateAuthorizationState.class,
new AuthorizationStateWaitCodeHandler(client,
new SimpleTelegramClientInteraction(),
getTestCode(authenticationData),
this::handleDefaultException
)
);
@ -119,6 +120,18 @@ public final class SimpleTelegramClient implements Authenticable, MutableTelegra
client.initialize(this::handleUpdate, this::handleUpdateException, this::handleDefaultException);
}
private String getTestCode(AuthenticationSupplier<?> authenticationData) {
if (authenticationData instanceof AuthenticationDataImpl) {
if (!((AuthenticationDataImpl) authenticationData).isBot()
&& ((AuthenticationDataImpl) authenticationData).isTest()) {
String phoneNumber = ((AuthenticationDataImpl) authenticationData).getUserPhoneNumber();
String substring = phoneNumber.substring(5, 6);
return substring + substring + substring + substring;
}
}
return null;
}
private void handleUpdate(TdApi.Object update) {
boolean handled = false;
for (ResultHandler<TdApi.Update> updateHandler : updateHandlers.keySet()) {