diff options
author | George Hazan <ghazan@miranda.im> | 2022-12-08 12:33:42 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2022-12-08 12:33:42 +0300 |
commit | e4a555d8e146994b7fc99c8f0c0f6b4ca8af1495 (patch) | |
tree | 310ece548498c4f7862f4ca2bb6fb060f6c5071e /protocols/Telegram/tdlib/td/example/java/org | |
parent | baa88cd35d210debe6af6e784466c813e2ebcf58 (diff) |
we don't need this code
Diffstat (limited to 'protocols/Telegram/tdlib/td/example/java/org')
-rw-r--r-- | protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/Client.java | 242 | ||||
-rw-r--r-- | protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java | 685 |
2 files changed, 0 insertions, 927 deletions
diff --git a/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/Client.java b/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/Client.java deleted file mode 100644 index 0a58bb45a7..0000000000 --- a/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/Client.java +++ /dev/null @@ -1,242 +0,0 @@ -// -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -package org.drinkless.tdlib; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - -/** - * Main class for interaction with the TDLib. - */ -public final class Client { - static { - try { - System.loadLibrary("tdjni"); - } catch (UnsatisfiedLinkError e) { - e.printStackTrace(); - } - } - - /** - * Interface for handler for results of queries to TDLib and incoming updates from TDLib. - */ - public interface ResultHandler { - /** - * Callback called on result of query to TDLib or incoming update from TDLib. - * - * @param object Result of query or update of type TdApi.Update about new events. - */ - void onResult(TdApi.Object object); - } - - /** - * Interface for handler of exceptions thrown while invoking ResultHandler. - * By default, all such exceptions are ignored. - * All exceptions thrown from ExceptionHandler are ignored. - */ - public interface ExceptionHandler { - /** - * Callback called on exceptions thrown while invoking ResultHandler. - * - * @param e Exception thrown by ResultHandler. - */ - void onException(Throwable e); - } - - /** - * Interface for handler of messages that are added to the internal TDLib log. - */ - public interface LogMessageHandler { - /** - * Callback called on messages that are added to the internal TDLib log. - * - * @param verbosityLevel Log verbosity level with which the message was added from -1 up to 1024. - * If 0, then TDLib will crash as soon as the callback returns. - * None of the TDLib methods can be called from the callback. - * @param message The message added to the internal TDLib log. - */ - void onLogMessage(int verbosityLevel, String message); - } - - /** - * Sends a request to the TDLib. - * - * @param query Object representing a query to the TDLib. - * @param resultHandler Result handler with onResult method which will be called with result - * of the query or with TdApi.Error as parameter. If it is null, nothing - * will be called. - * @param exceptionHandler Exception handler with onException method which will be called on - * exception thrown from resultHandler. If it is null, then - * defaultExceptionHandler will be called. - * @throws NullPointerException if query is null. - */ - public void send(TdApi.Function query, ResultHandler resultHandler, ExceptionHandler exceptionHandler) { - long queryId = currentQueryId.incrementAndGet(); - if (resultHandler != null) { - handlers.put(queryId, new Handler(resultHandler, exceptionHandler)); - } - nativeClientSend(nativeClientId, queryId, query); - } - - /** - * Sends a request to the TDLib with an empty ExceptionHandler. - * - * @param query Object representing a query to the TDLib. - * @param resultHandler Result handler with onResult method which will be called with result - * of the query or with TdApi.Error as parameter. If it is null, then - * defaultExceptionHandler will be called. - * @throws NullPointerException if query is null. - */ - public void send(TdApi.Function query, ResultHandler resultHandler) { - send(query, resultHandler, null); - } - - /** - * Synchronously executes a TDLib request. Only a few marked accordingly requests can be executed synchronously. - * - * @param query Object representing a query to the TDLib. - * @return request result. - * @throws NullPointerException if query is null. - */ - public static TdApi.Object execute(TdApi.Function query) { - return nativeClientExecute(query); - } - - /** - * Creates new Client. - * - * @param updateHandler Handler for incoming updates. - * @param updateExceptionHandler Handler for exceptions thrown from updateHandler. If it is null, exceptions will be iggnored. - * @param defaultExceptionHandler Default handler for exceptions thrown from all ResultHandler. If it is null, exceptions will be iggnored. - * @return created Client - */ - public static Client create(ResultHandler updateHandler, ExceptionHandler updateExceptionHandler, ExceptionHandler defaultExceptionHandler) { - Client client = new Client(updateHandler, updateExceptionHandler, defaultExceptionHandler); - synchronized (responseReceiver) { - if (!responseReceiver.isRun) { - responseReceiver.isRun = true; - - Thread receiverThread = new Thread(responseReceiver, "TDLib thread"); - receiverThread.setDaemon(true); - receiverThread.start(); - } - } - return client; - } - - /** - * Sets the handler for messages that are added to the internal TDLib log. - * None of the TDLib methods can be called from the callback. - * - * @param maxVerbosityLevel The maximum verbosity level of messages for which the callback will be called. - * @param logMessageHandler Handler for messages that are added to the internal TDLib log. Pass null to remove the handler. - */ - public static void setLogMessageHandler(int maxVerbosityLevel, Client.LogMessageHandler logMessageHandler) { - nativeClientSetLogMessageHandler(maxVerbosityLevel, logMessageHandler); - } - - private static class ResponseReceiver implements Runnable { - public boolean isRun = false; - - @Override - public void run() { - while (true) { - int resultN = nativeClientReceive(clientIds, eventIds, events, 100000.0 /*seconds*/); - for (int i = 0; i < resultN; i++) { - processResult(clientIds[i], eventIds[i], events[i]); - events[i] = null; - } - } - } - - private void processResult(int clientId, long id, TdApi.Object object) { - boolean isClosed = false; - if (id == 0 && object instanceof TdApi.UpdateAuthorizationState) { - TdApi.AuthorizationState authorizationState = ((TdApi.UpdateAuthorizationState) object).authorizationState; - if (authorizationState instanceof TdApi.AuthorizationStateClosed) { - isClosed = true; - } - } - - Handler handler = id == 0 ? updateHandlers.get(clientId) : handlers.remove(id); - if (handler != null) { - try { - handler.resultHandler.onResult(object); - } catch (Throwable cause) { - ExceptionHandler exceptionHandler = handler.exceptionHandler; - if (exceptionHandler == null) { - exceptionHandler = defaultExceptionHandlers.get(clientId); - } - if (exceptionHandler != null) { - try { - exceptionHandler.onException(cause); - } catch (Throwable ignored) { - } - } - } - } - - if (isClosed) { - updateHandlers.remove(clientId); // there will be no more updates - defaultExceptionHandlers.remove(clientId); // ignore further exceptions - clientCount.decrementAndGet(); - } - } - - private static final int MAX_EVENTS = 1000; - private final int[] clientIds = new int[MAX_EVENTS]; - private final long[] eventIds = new long[MAX_EVENTS]; - private final TdApi.Object[] events = new TdApi.Object[MAX_EVENTS]; - } - - private final int nativeClientId; - - private static final ConcurrentHashMap<Integer, ExceptionHandler> defaultExceptionHandlers = new ConcurrentHashMap<Integer, ExceptionHandler>(); - private static final ConcurrentHashMap<Integer, Handler> updateHandlers = new ConcurrentHashMap<Integer, Handler>(); - private static final ConcurrentHashMap<Long, Handler> handlers = new ConcurrentHashMap<Long, Handler>(); - private static final AtomicLong currentQueryId = new AtomicLong(); - private static final AtomicLong clientCount = new AtomicLong(); - - private static final ResponseReceiver responseReceiver = new ResponseReceiver(); - - private static class Handler { - final ResultHandler resultHandler; - final ExceptionHandler exceptionHandler; - - Handler(ResultHandler resultHandler, ExceptionHandler exceptionHandler) { - this.resultHandler = resultHandler; - this.exceptionHandler = exceptionHandler; - } - } - - private Client(ResultHandler updateHandler, ExceptionHandler updateExceptionHandler, ExceptionHandler defaultExceptionHandler) { - clientCount.incrementAndGet(); - nativeClientId = createNativeClient(); - if (updateHandler != null) { - updateHandlers.put(nativeClientId, new Handler(updateHandler, updateExceptionHandler)); - } - if (defaultExceptionHandler != null) { - defaultExceptionHandlers.put(nativeClientId, defaultExceptionHandler); - } - send(new TdApi.GetOption("version"), null, null); - } - - @Override - protected void finalize() throws Throwable { - send(new TdApi.Close(), null, null); - } - - private static native int createNativeClient(); - - private static native void nativeClientSend(int nativeClientId, long eventId, TdApi.Function function); - - private static native int nativeClientReceive(int[] clientIds, long[] eventIds, TdApi.Object[] events, double timeout); - - private static native TdApi.Object nativeClientExecute(TdApi.Function function); - - private static native void nativeClientSetLogMessageHandler(int maxVerbosityLevel, LogMessageHandler logMessageHandler); -} diff --git a/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java b/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java deleted file mode 100644 index 7e76b42276..0000000000 --- a/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java +++ /dev/null @@ -1,685 +0,0 @@ -// -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -package org.drinkless.tdlib.example; - -import org.drinkless.tdlib.Client; -import org.drinkless.tdlib.TdApi; - -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.atomic.AtomicLong; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -/** - * Example class for TDLib usage from Java. - */ -public final class Example { - private static Client client = null; - - private static TdApi.AuthorizationState authorizationState = null; - private static volatile boolean haveAuthorization = false; - private static volatile boolean needQuit = false; - private static volatile boolean canQuit = false; - - private static final Client.ResultHandler defaultHandler = new DefaultHandler(); - - private static final Lock authorizationLock = new ReentrantLock(); - private static final Condition gotAuthorization = authorizationLock.newCondition(); - - private static final ConcurrentMap<Long, TdApi.User> users = new ConcurrentHashMap<Long, TdApi.User>(); - private static final ConcurrentMap<Long, TdApi.BasicGroup> basicGroups = new ConcurrentHashMap<Long, TdApi.BasicGroup>(); - private static final ConcurrentMap<Long, TdApi.Supergroup> supergroups = new ConcurrentHashMap<Long, TdApi.Supergroup>(); - private static final ConcurrentMap<Integer, TdApi.SecretChat> secretChats = new ConcurrentHashMap<Integer, TdApi.SecretChat>(); - - private static final ConcurrentMap<Long, TdApi.Chat> chats = new ConcurrentHashMap<Long, TdApi.Chat>(); - private static final NavigableSet<OrderedChat> mainChatList = new TreeSet<OrderedChat>(); - private static boolean haveFullMainChatList = false; - - private static final ConcurrentMap<Long, TdApi.UserFullInfo> usersFullInfo = new ConcurrentHashMap<Long, TdApi.UserFullInfo>(); - private static final ConcurrentMap<Long, TdApi.BasicGroupFullInfo> basicGroupsFullInfo = new ConcurrentHashMap<Long, TdApi.BasicGroupFullInfo>(); - private static final ConcurrentMap<Long, TdApi.SupergroupFullInfo> supergroupsFullInfo = new ConcurrentHashMap<Long, TdApi.SupergroupFullInfo>(); - - private static final String newLine = System.getProperty("line.separator"); - private static final String commandsLine = "Enter command (gcs - GetChats, gc <chatId> - GetChat, me - GetMe, sm <chatId> <message> - SendMessage, lo - LogOut, q - Quit): "; - private static volatile String currentPrompt = null; - - private static void print(String str) { - if (currentPrompt != null) { - System.out.println(""); - } - System.out.println(str); - if (currentPrompt != null) { - System.out.print(currentPrompt); - } - } - - private static void setChatPositions(TdApi.Chat chat, TdApi.ChatPosition[] positions) { - synchronized (mainChatList) { - synchronized (chat) { - for (TdApi.ChatPosition position : chat.positions) { - if (position.list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) { - boolean isRemoved = mainChatList.remove(new OrderedChat(chat.id, position)); - assert isRemoved; - } - } - - chat.positions = positions; - - for (TdApi.ChatPosition position : chat.positions) { - if (position.list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) { - boolean isAdded = mainChatList.add(new OrderedChat(chat.id, position)); - assert isAdded; - } - } - } - } - } - - private static void onAuthorizationStateUpdated(TdApi.AuthorizationState authorizationState) { - if (authorizationState != null) { - Example.authorizationState = authorizationState; - } - switch (Example.authorizationState.getConstructor()) { - case TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR: - TdApi.SetTdlibParameters request = new TdApi.SetTdlibParameters(); - request.databaseDirectory = "tdlib"; - request.useMessageDatabase = true; - request.useSecretChats = true; - request.apiId = 94575; - request.apiHash = "a3406de8d171bb422bb6ddf3bbd800e2"; - request.systemLanguageCode = "en"; - request.deviceModel = "Desktop"; - request.applicationVersion = "1.0"; - request.enableStorageOptimizer = true; - - client.send(request, new AuthorizationRequestHandler()); - break; - case TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR: { - String phoneNumber = promptString("Please enter phone number: "); - client.send(new TdApi.SetAuthenticationPhoneNumber(phoneNumber, null), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitOtherDeviceConfirmation.CONSTRUCTOR: { - String link = ((TdApi.AuthorizationStateWaitOtherDeviceConfirmation) Example.authorizationState).link; - System.out.println("Please confirm this login link on another device: " + link); - break; - } - case TdApi.AuthorizationStateWaitEmailAddress.CONSTRUCTOR: { - String emailAddress = promptString("Please enter email address: "); - client.send(new TdApi.SetAuthenticationEmailAddress(emailAddress), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitEmailCode.CONSTRUCTOR: { - String code = promptString("Please enter email authentication code: "); - client.send(new TdApi.CheckAuthenticationEmailCode(new TdApi.EmailAddressAuthenticationCode(code)), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitCode.CONSTRUCTOR: { - String code = promptString("Please enter authentication code: "); - client.send(new TdApi.CheckAuthenticationCode(code), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitRegistration.CONSTRUCTOR: { - String firstName = promptString("Please enter your first name: "); - String lastName = promptString("Please enter your last name: "); - client.send(new TdApi.RegisterUser(firstName, lastName), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR: { - String password = promptString("Please enter password: "); - client.send(new TdApi.CheckAuthenticationPassword(password), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateReady.CONSTRUCTOR: - haveAuthorization = true; - authorizationLock.lock(); - try { - gotAuthorization.signal(); - } finally { - authorizationLock.unlock(); - } - break; - case TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR: - haveAuthorization = false; - print("Logging out"); - break; - case TdApi.AuthorizationStateClosing.CONSTRUCTOR: - haveAuthorization = false; - print("Closing"); - break; - case TdApi.AuthorizationStateClosed.CONSTRUCTOR: - print("Closed"); - if (!needQuit) { - client = Client.create(new UpdateHandler(), null, null); // recreate client after previous has closed - } else { - canQuit = true; - } - break; - default: - System.err.println("Unsupported authorization state:" + newLine + Example.authorizationState); - } - } - - private static int toInt(String arg) { - int result = 0; - try { - result = Integer.parseInt(arg); - } catch (NumberFormatException ignored) { - } - return result; - } - - private static long getChatId(String arg) { - long chatId = 0; - try { - chatId = Long.parseLong(arg); - } catch (NumberFormatException ignored) { - } - return chatId; - } - - private static String promptString(String prompt) { - System.out.print(prompt); - currentPrompt = prompt; - BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - String str = ""; - try { - str = reader.readLine(); - } catch (IOException e) { - e.printStackTrace(); - } - currentPrompt = null; - return str; - } - - private static void getCommand() { - String command = promptString(commandsLine); - String[] commands = command.split(" ", 2); - try { - switch (commands[0]) { - case "gcs": { - int limit = 20; - if (commands.length > 1) { - limit = toInt(commands[1]); - } - getMainChatList(limit); - break; - } - case "gc": - client.send(new TdApi.GetChat(getChatId(commands[1])), defaultHandler); - break; - case "me": - client.send(new TdApi.GetMe(), defaultHandler); - break; - case "sm": { - String[] args = commands[1].split(" ", 2); - sendMessage(getChatId(args[0]), args[1]); - break; - } - case "lo": - haveAuthorization = false; - client.send(new TdApi.LogOut(), defaultHandler); - break; - case "q": - needQuit = true; - haveAuthorization = false; - client.send(new TdApi.Close(), defaultHandler); - break; - default: - System.err.println("Unsupported command: " + command); - } - } catch (ArrayIndexOutOfBoundsException e) { - print("Not enough arguments"); - } - } - - private static void getMainChatList(final int limit) { - synchronized (mainChatList) { - if (!haveFullMainChatList && limit > mainChatList.size()) { - // send LoadChats request if there are some unknown chats and have not enough known chats - client.send(new TdApi.LoadChats(new TdApi.ChatListMain(), limit - mainChatList.size()), new Client.ResultHandler() { - @Override - public void onResult(TdApi.Object object) { - switch (object.getConstructor()) { - case TdApi.Error.CONSTRUCTOR: - if (((TdApi.Error) object).code == 404) { - synchronized (mainChatList) { - haveFullMainChatList = true; - } - } else { - System.err.println("Receive an error for LoadChats:" + newLine + object); - } - break; - case TdApi.Ok.CONSTRUCTOR: - // chats had already been received through updates, let's retry request - getMainChatList(limit); - break; - default: - System.err.println("Receive wrong response from TDLib:" + newLine + object); - } - } - }); - return; - } - - java.util.Iterator<OrderedChat> iter = mainChatList.iterator(); - System.out.println(); - System.out.println("First " + limit + " chat(s) out of " + mainChatList.size() + " known chat(s):"); - for (int i = 0; i < limit && i < mainChatList.size(); i++) { - long chatId = iter.next().chatId; - TdApi.Chat chat = chats.get(chatId); - synchronized (chat) { - System.out.println(chatId + ": " + chat.title); - } - } - print(""); - } - } - - private static void sendMessage(long chatId, String message) { - // initialize reply markup just for testing - TdApi.InlineKeyboardButton[] row = {new TdApi.InlineKeyboardButton("https://telegram.org?1", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?2", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?3", new TdApi.InlineKeyboardButtonTypeUrl())}; - TdApi.ReplyMarkup replyMarkup = new TdApi.ReplyMarkupInlineKeyboard(new TdApi.InlineKeyboardButton[][]{row, row, row}); - - TdApi.InputMessageContent content = new TdApi.InputMessageText(new TdApi.FormattedText(message, null), false, true); - client.send(new TdApi.SendMessage(chatId, 0, 0, null, replyMarkup, content), defaultHandler); - } - - public static void main(String[] args) throws InterruptedException { - // set log message handler to handle only fatal errors (0) and plain log messages (-1) - Client.setLogMessageHandler(0, new LogMessageHandler()); - - // disable TDLib log and redirect fatal errors and plain log messages to a file - Client.execute(new TdApi.SetLogVerbosityLevel(0)); - if (Client.execute(new TdApi.SetLogStream(new TdApi.LogStreamFile("tdlib.log", 1 << 27, false))) instanceof TdApi.Error) { - throw new IOError(new IOException("Write access to the current directory is required")); - } - - // create client - client = Client.create(new UpdateHandler(), null, null); - - // test Client.execute - defaultHandler.onResult(Client.execute(new TdApi.GetTextEntities("@telegram /test_command https://telegram.org telegram.me @gif @test"))); - - // main loop - while (!needQuit) { - // await authorization - authorizationLock.lock(); - try { - while (!haveAuthorization) { - gotAuthorization.await(); - } - } finally { - authorizationLock.unlock(); - } - - while (haveAuthorization) { - getCommand(); - } - } - while (!canQuit) { - Thread.sleep(1); - } - } - - private static class OrderedChat implements Comparable<OrderedChat> { - final long chatId; - final TdApi.ChatPosition position; - - OrderedChat(long chatId, TdApi.ChatPosition position) { - this.chatId = chatId; - this.position = position; - } - - @Override - public int compareTo(OrderedChat o) { - if (this.position.order != o.position.order) { - return o.position.order < this.position.order ? -1 : 1; - } - if (this.chatId != o.chatId) { - return o.chatId < this.chatId ? -1 : 1; - } - return 0; - } - - @Override - public boolean equals(Object obj) { - OrderedChat o = (OrderedChat) obj; - return this.chatId == o.chatId && this.position.order == o.position.order; - } - } - - private static class DefaultHandler implements Client.ResultHandler { - @Override - public void onResult(TdApi.Object object) { - print(object.toString()); - } - } - - private static class UpdateHandler implements Client.ResultHandler { - @Override - public void onResult(TdApi.Object object) { - switch (object.getConstructor()) { - case TdApi.UpdateAuthorizationState.CONSTRUCTOR: - onAuthorizationStateUpdated(((TdApi.UpdateAuthorizationState) object).authorizationState); - break; - - case TdApi.UpdateUser.CONSTRUCTOR: - TdApi.UpdateUser updateUser = (TdApi.UpdateUser) object; - users.put(updateUser.user.id, updateUser.user); - break; - case TdApi.UpdateUserStatus.CONSTRUCTOR: { - TdApi.UpdateUserStatus updateUserStatus = (TdApi.UpdateUserStatus) object; - TdApi.User user = users.get(updateUserStatus.userId); - synchronized (user) { - user.status = updateUserStatus.status; - } - break; - } - case TdApi.UpdateBasicGroup.CONSTRUCTOR: - TdApi.UpdateBasicGroup updateBasicGroup = (TdApi.UpdateBasicGroup) object; - basicGroups.put(updateBasicGroup.basicGroup.id, updateBasicGroup.basicGroup); - break; - case TdApi.UpdateSupergroup.CONSTRUCTOR: - TdApi.UpdateSupergroup updateSupergroup = (TdApi.UpdateSupergroup) object; - supergroups.put(updateSupergroup.supergroup.id, updateSupergroup.supergroup); - break; - case TdApi.UpdateSecretChat.CONSTRUCTOR: - TdApi.UpdateSecretChat updateSecretChat = (TdApi.UpdateSecretChat) object; - secretChats.put(updateSecretChat.secretChat.id, updateSecretChat.secretChat); - break; - - case TdApi.UpdateNewChat.CONSTRUCTOR: { - TdApi.UpdateNewChat updateNewChat = (TdApi.UpdateNewChat) object; - TdApi.Chat chat = updateNewChat.chat; - synchronized (chat) { - chats.put(chat.id, chat); - - TdApi.ChatPosition[] positions = chat.positions; - chat.positions = new TdApi.ChatPosition[0]; - setChatPositions(chat, positions); - } - break; - } - case TdApi.UpdateChatTitle.CONSTRUCTOR: { - TdApi.UpdateChatTitle updateChat = (TdApi.UpdateChatTitle) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.title = updateChat.title; - } - break; - } - case TdApi.UpdateChatPhoto.CONSTRUCTOR: { - TdApi.UpdateChatPhoto updateChat = (TdApi.UpdateChatPhoto) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.photo = updateChat.photo; - } - break; - } - case TdApi.UpdateChatLastMessage.CONSTRUCTOR: { - TdApi.UpdateChatLastMessage updateChat = (TdApi.UpdateChatLastMessage) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.lastMessage = updateChat.lastMessage; - setChatPositions(chat, updateChat.positions); - } - break; - } - case TdApi.UpdateChatPosition.CONSTRUCTOR: { - TdApi.UpdateChatPosition updateChat = (TdApi.UpdateChatPosition) object; - if (updateChat.position.list.getConstructor() != TdApi.ChatListMain.CONSTRUCTOR) { - break; - } - - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - int i; - for (i = 0; i < chat.positions.length; i++) { - if (chat.positions[i].list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) { - break; - } - } - TdApi.ChatPosition[] new_positions = new TdApi.ChatPosition[chat.positions.length + (updateChat.position.order == 0 ? 0 : 1) - (i < chat.positions.length ? 1 : 0)]; - int pos = 0; - if (updateChat.position.order != 0) { - new_positions[pos++] = updateChat.position; - } - for (int j = 0; j < chat.positions.length; j++) { - if (j != i) { - new_positions[pos++] = chat.positions[j]; - } - } - assert pos == new_positions.length; - - setChatPositions(chat, new_positions); - } - break; - } - case TdApi.UpdateChatReadInbox.CONSTRUCTOR: { - TdApi.UpdateChatReadInbox updateChat = (TdApi.UpdateChatReadInbox) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.lastReadInboxMessageId = updateChat.lastReadInboxMessageId; - chat.unreadCount = updateChat.unreadCount; - } - break; - } - case TdApi.UpdateChatReadOutbox.CONSTRUCTOR: { - TdApi.UpdateChatReadOutbox updateChat = (TdApi.UpdateChatReadOutbox) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.lastReadOutboxMessageId = updateChat.lastReadOutboxMessageId; - } - break; - } - case TdApi.UpdateChatUnreadMentionCount.CONSTRUCTOR: { - TdApi.UpdateChatUnreadMentionCount updateChat = (TdApi.UpdateChatUnreadMentionCount) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.unreadMentionCount = updateChat.unreadMentionCount; - } - break; - } - case TdApi.UpdateMessageMentionRead.CONSTRUCTOR: { - TdApi.UpdateMessageMentionRead updateChat = (TdApi.UpdateMessageMentionRead) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.unreadMentionCount = updateChat.unreadMentionCount; - } - break; - } - case TdApi.UpdateChatReplyMarkup.CONSTRUCTOR: { - TdApi.UpdateChatReplyMarkup updateChat = (TdApi.UpdateChatReplyMarkup) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.replyMarkupMessageId = updateChat.replyMarkupMessageId; - } - break; - } - case TdApi.UpdateChatDraftMessage.CONSTRUCTOR: { - TdApi.UpdateChatDraftMessage updateChat = (TdApi.UpdateChatDraftMessage) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.draftMessage = updateChat.draftMessage; - setChatPositions(chat, updateChat.positions); - } - break; - } - case TdApi.UpdateChatPermissions.CONSTRUCTOR: { - TdApi.UpdateChatPermissions update = (TdApi.UpdateChatPermissions) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.permissions = update.permissions; - } - break; - } - case TdApi.UpdateChatNotificationSettings.CONSTRUCTOR: { - TdApi.UpdateChatNotificationSettings update = (TdApi.UpdateChatNotificationSettings) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.notificationSettings = update.notificationSettings; - } - break; - } - case TdApi.UpdateChatDefaultDisableNotification.CONSTRUCTOR: { - TdApi.UpdateChatDefaultDisableNotification update = (TdApi.UpdateChatDefaultDisableNotification) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.defaultDisableNotification = update.defaultDisableNotification; - } - break; - } - case TdApi.UpdateChatIsMarkedAsUnread.CONSTRUCTOR: { - TdApi.UpdateChatIsMarkedAsUnread update = (TdApi.UpdateChatIsMarkedAsUnread) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.isMarkedAsUnread = update.isMarkedAsUnread; - } - break; - } - case TdApi.UpdateChatIsBlocked.CONSTRUCTOR: { - TdApi.UpdateChatIsBlocked update = (TdApi.UpdateChatIsBlocked) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.isBlocked = update.isBlocked; - } - break; - } - case TdApi.UpdateChatHasScheduledMessages.CONSTRUCTOR: { - TdApi.UpdateChatHasScheduledMessages update = (TdApi.UpdateChatHasScheduledMessages) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.hasScheduledMessages = update.hasScheduledMessages; - } - break; - } - - case TdApi.UpdateUserFullInfo.CONSTRUCTOR: - TdApi.UpdateUserFullInfo updateUserFullInfo = (TdApi.UpdateUserFullInfo) object; - usersFullInfo.put(updateUserFullInfo.userId, updateUserFullInfo.userFullInfo); - break; - case TdApi.UpdateBasicGroupFullInfo.CONSTRUCTOR: - TdApi.UpdateBasicGroupFullInfo updateBasicGroupFullInfo = (TdApi.UpdateBasicGroupFullInfo) object; - basicGroupsFullInfo.put(updateBasicGroupFullInfo.basicGroupId, updateBasicGroupFullInfo.basicGroupFullInfo); - break; - case TdApi.UpdateSupergroupFullInfo.CONSTRUCTOR: - TdApi.UpdateSupergroupFullInfo updateSupergroupFullInfo = (TdApi.UpdateSupergroupFullInfo) object; - supergroupsFullInfo.put(updateSupergroupFullInfo.supergroupId, updateSupergroupFullInfo.supergroupFullInfo); - break; - default: - // print("Unsupported update:" + newLine + object); - } - } - } - - private static class AuthorizationRequestHandler implements Client.ResultHandler { - @Override - public void onResult(TdApi.Object object) { - switch (object.getConstructor()) { - case TdApi.Error.CONSTRUCTOR: - System.err.println("Receive an error:" + newLine + object); - onAuthorizationStateUpdated(null); // repeat last action - break; - case TdApi.Ok.CONSTRUCTOR: - // result is already received through UpdateAuthorizationState, nothing to do - break; - default: - System.err.println("Receive wrong response from TDLib:" + newLine + object); - } - } - } - - private static class LogMessageHandler implements Client.LogMessageHandler { - @Override - public void onLogMessage(int verbosityLevel, String message) { - if (verbosityLevel == 0) { - onFatalError(message); - return; - } - System.err.println(message); - } - } - - private static void onFatalError(String errorMessage) { - final class ThrowError implements Runnable { - private final String errorMessage; - private final AtomicLong errorThrowTime; - - private ThrowError(String errorMessage, AtomicLong errorThrowTime) { - this.errorMessage = errorMessage; - this.errorThrowTime = errorThrowTime; - } - - @Override - public void run() { - if (isDatabaseBrokenError(errorMessage) || isDiskFullError(errorMessage) || isDiskError(errorMessage)) { - processExternalError(); - return; - } - - errorThrowTime.set(System.currentTimeMillis()); - throw new ClientError("TDLib fatal error: " + errorMessage); - } - - private void processExternalError() { - errorThrowTime.set(System.currentTimeMillis()); - throw new ExternalClientError("Fatal error: " + errorMessage); - } - - final class ClientError extends Error { - private ClientError(String message) { - super(message); - } - } - - final class ExternalClientError extends Error { - public ExternalClientError(String message) { - super(message); - } - } - - private boolean isDatabaseBrokenError(String message) { - return message.contains("Wrong key or database is corrupted") || - message.contains("SQL logic error or missing database") || - message.contains("database disk image is malformed") || - message.contains("file is encrypted or is not a database") || - message.contains("unsupported file format") || - message.contains("Database was corrupted and deleted during execution and can't be recreated"); - } - - private boolean isDiskFullError(String message) { - return message.contains("PosixError : No space left on device") || - message.contains("database or disk is full"); - } - - private boolean isDiskError(String message) { - return message.contains("I/O error") || message.contains("Structure needs cleaning"); - } - } - - final AtomicLong errorThrowTime = new AtomicLong(Long.MAX_VALUE); - new Thread(new ThrowError(errorMessage, errorThrowTime), "TDLib fatal error thread").start(); - - // wait at least 10 seconds after the error is thrown - while (errorThrowTime.get() >= System.currentTimeMillis() - 10000) { - try { - Thread.sleep(1000 /* milliseconds */); - } catch (InterruptedException ignore) { - Thread.currentThread().interrupt(); - } - } - } -} |