mirror of https://github.com/NekoX-Dev/NekoX.git
216 lines
10 KiB
Java
216 lines
10 KiB
Java
package tw.nekomimi.nekogram;
|
|
|
|
import org.telegram.messenger.AccountInstance;
|
|
import org.telegram.messenger.BuildConfig;
|
|
import org.telegram.messenger.BuildVars;
|
|
import org.telegram.messenger.FileLog;
|
|
import org.telegram.messenger.UserConfig;
|
|
import org.telegram.tgnet.TLRPC;
|
|
import org.webrtc.EglBase;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.function.Consumer;
|
|
|
|
import tw.nekomimi.nekogram.utils.FileUtil;
|
|
|
|
//TODO use UpdateAppAlertDialog / BlockingUpdateView?
|
|
|
|
public class InternalUpdater {
|
|
|
|
static final int UPDATE_METADATA_START_FROM = 0;
|
|
static final int MAX_READ_COUNT = 20;
|
|
static final long CHANNEL_METADATA_ID = 1359638116;
|
|
static final String CHANNEL_METADATA_NAME = "nekox_update_metadata";
|
|
static final long CHANNEL_APKS_ID = 1137038259;
|
|
static final String CHANNEL_APKS_NAME = "NekoXApks";
|
|
|
|
static void retrieveUpdateMetadata(retrieveUpdateMetadataCallback callback) {
|
|
final int localVersionCode = BuildVars.BUILD_VERSION;
|
|
AccountInstance accountInstance = AccountInstance.getInstance(UserConfig.selectedAccount);
|
|
TLRPC.TL_messages_getHistory req = new TLRPC.TL_messages_getHistory();
|
|
req.peer = accountInstance.getMessagesController().getInputPeer(-CHANNEL_METADATA_ID);
|
|
req.offset_id = 0;
|
|
req.limit = MAX_READ_COUNT;
|
|
Runnable sendReq = () -> accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> {
|
|
if (error != null) {
|
|
FileLog.e("Error when retrieving update metadata from channel " + error);
|
|
callback.apply(null, true);
|
|
return;
|
|
}
|
|
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
|
|
List<UpdateMetadata> metas = new ArrayList<>();
|
|
for (TLRPC.Message message : res.messages) {
|
|
if (!(message instanceof TLRPC.TL_message)) continue;
|
|
if (!message.message.startsWith("v")) continue;
|
|
String[] split = message.message.split(",");
|
|
if (split.length < 4) continue;
|
|
UpdateMetadata metaData = new UpdateMetadata(message.id, split);
|
|
metas.add(metaData);
|
|
}
|
|
Collections.sort(metas, (o1, o2) -> o2.versionCode - o1.versionCode); // versionCode Desc
|
|
UpdateMetadata found = null;
|
|
for (UpdateMetadata metaData : metas) {
|
|
if (metaData.versionCode <= localVersionCode) break;
|
|
if (NekoXConfig.autoUpdateReleaseChannel < 3 && metaData.versionName.contains("preview"))
|
|
continue;
|
|
if (NekoXConfig.autoUpdateReleaseChannel < 2 && metaData.versionName.contains("rc"))
|
|
continue;
|
|
found = metaData;
|
|
break;
|
|
}
|
|
if (found != null) {
|
|
for (TLRPC.Message message : res.messages) {
|
|
if (!(message instanceof TLRPC.TL_message)) continue;
|
|
if (message.id == found.UpdateLogMessageID) {
|
|
found.updateLog = message.message;
|
|
found.updateLogEntities = message.entities;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (found == null) {
|
|
FileLog.d("Cannot find Update Metadata");
|
|
callback.apply(null, false);
|
|
return;
|
|
}
|
|
FileLog.w("Found Update Metadata " + found.versionName + " " + found.versionCode);
|
|
callback.apply(found, false);
|
|
});
|
|
if (req.peer.access_hash != 0) sendReq.run();
|
|
else {
|
|
TLRPC.TL_contacts_resolveUsername resolve = new TLRPC.TL_contacts_resolveUsername();
|
|
resolve.username = CHANNEL_METADATA_NAME;
|
|
accountInstance.getConnectionsManager().sendRequest(resolve, (response1, error1) -> {
|
|
if (error1 != null) {
|
|
FileLog.e("Error when checking update, unable to resolve metadata channel " + error1.text);
|
|
callback.apply(null, true);
|
|
return;
|
|
}
|
|
if (!(response1 instanceof TLRPC.TL_contacts_resolvedPeer)) {
|
|
FileLog.e("Error when checking update, unable to resolve metadata channel, unexpected responseType " + response1.getClass().getName());
|
|
callback.apply(null, true);
|
|
return;
|
|
}
|
|
TLRPC.TL_contacts_resolvedPeer resolvedPeer = (TLRPC.TL_contacts_resolvedPeer) response1;
|
|
accountInstance.getMessagesController().putUsers(resolvedPeer.users, false);
|
|
accountInstance.getMessagesController().putChats(resolvedPeer.chats, false);
|
|
accountInstance.getMessagesStorage().putUsersAndChats(resolvedPeer.users, resolvedPeer.chats, false, true);
|
|
if ((resolvedPeer.chats == null || resolvedPeer.chats.size() == 0)) {
|
|
FileLog.e("Error when checking update, unable to resolve metadata channel, unexpected resolvedChat ");
|
|
callback.apply(null, true);
|
|
return;
|
|
}
|
|
req.peer = new TLRPC.TL_inputPeerChannel();
|
|
req.peer.channel_id = resolvedPeer.chats.get(0).id;
|
|
req.peer.access_hash = resolvedPeer.chats.get(0).access_hash;
|
|
sendReq.run();
|
|
});
|
|
}
|
|
}
|
|
|
|
public static void checkUpdate(checkUpdateCallback callback) {
|
|
AccountInstance accountInstance = AccountInstance.getInstance(UserConfig.selectedAccount);
|
|
retrieveUpdateMetadata((metadata, err) -> {
|
|
if (metadata == null) {
|
|
callback.apply(null, err);
|
|
return;
|
|
}
|
|
TLRPC.TL_messages_getHistory req = new TLRPC.TL_messages_getHistory();
|
|
req.peer = accountInstance.getMessagesController().getInputPeer(-CHANNEL_APKS_ID);
|
|
req.min_id = metadata.apkChannelMessageID;
|
|
req.limit = MAX_READ_COUNT;
|
|
|
|
Runnable sendReq = () -> accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> {
|
|
if (error != null) {
|
|
FileLog.e("Error when getting update document " + error.text);
|
|
callback.apply(null, true);
|
|
return;
|
|
}
|
|
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
|
|
FileLog.d("Retrieve update messages, size:" + res.messages.size());
|
|
final String target = BuildConfig.FLAVOR + "-" + FileUtil.getAbi() + "-" + ("debug".equals(BuildConfig.BUILD_TYPE) ? "release" : BuildConfig.BUILD_TYPE) + ".apk";
|
|
for (int i = 0; i < res.messages.size(); i++) {
|
|
if (res.messages.get(i).media == null) continue;
|
|
|
|
TLRPC.Document apkDocument = res.messages.get(i).media.document;
|
|
String fileName = apkDocument.attributes.size() == 0 ? "" : apkDocument.attributes.get(0).file_name;
|
|
if (!(fileName.contains(target) && fileName.contains(metadata.versionName) ))
|
|
continue;
|
|
TLRPC.TL_help_appUpdate update = new TLRPC.TL_help_appUpdate();
|
|
update.version = metadata.versionName;
|
|
update.document = apkDocument;
|
|
update.can_not_skip = false;
|
|
update.flags |= 2;
|
|
if (metadata.updateLog != null) {
|
|
update.text = metadata.updateLog;
|
|
update.entities = metadata.updateLogEntities;
|
|
}
|
|
callback.apply(update, false);
|
|
return;
|
|
}
|
|
callback.apply(null, false);
|
|
});
|
|
if (req.peer.access_hash != 0) sendReq.run();
|
|
else {
|
|
TLRPC.TL_contacts_resolveUsername resolve = new TLRPC.TL_contacts_resolveUsername();
|
|
resolve.username = CHANNEL_APKS_NAME;
|
|
accountInstance.getConnectionsManager().sendRequest(resolve, (response1, error1) -> {
|
|
if (error1 != null) {
|
|
FileLog.e("Error when checking update, unable to resolve metadata channel " + error1);
|
|
callback.apply(null, true);
|
|
return;
|
|
}
|
|
if (!(response1 instanceof TLRPC.TL_contacts_resolvedPeer)) {
|
|
FileLog.e("Error when checking update, unable to resolve metadata channel, unexpected responseType " + response1.getClass().getName());
|
|
callback.apply(null, true);
|
|
return;
|
|
}
|
|
TLRPC.TL_contacts_resolvedPeer resolvedPeer = (TLRPC.TL_contacts_resolvedPeer) response1;
|
|
accountInstance.getMessagesController().putUsers(resolvedPeer.users, false);
|
|
accountInstance.getMessagesController().putChats(resolvedPeer.chats, false);
|
|
accountInstance.getMessagesStorage().putUsersAndChats(resolvedPeer.users, resolvedPeer.chats, false, true);
|
|
if ((resolvedPeer.chats == null || resolvedPeer.chats.size() == 0)) {
|
|
FileLog.e("Error when checking update, unable to resolve metadata channel, unexpected resolvedChat ");
|
|
callback.apply(null, true);
|
|
return;
|
|
}
|
|
req.peer = new TLRPC.TL_inputPeerChannel();
|
|
req.peer.channel_id = resolvedPeer.chats.get(0).id;
|
|
req.peer.access_hash = resolvedPeer.chats.get(0).access_hash;
|
|
sendReq.run();
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
}
|
|
|
|
public interface retrieveUpdateMetadataCallback {
|
|
void apply(UpdateMetadata metadata, boolean error);
|
|
}
|
|
|
|
public interface checkUpdateCallback {
|
|
void apply(TLRPC.TL_help_appUpdate resp, boolean error);
|
|
}
|
|
|
|
static class UpdateMetadata {
|
|
int messageID;
|
|
String versionName;
|
|
int versionCode;
|
|
int apkChannelMessageID;
|
|
int UpdateLogMessageID;
|
|
String updateLog = null;
|
|
ArrayList<TLRPC.MessageEntity> updateLogEntities = null;
|
|
|
|
UpdateMetadata(int messageID, String[] split) {
|
|
this.messageID = messageID;
|
|
versionName = split[0];
|
|
versionCode = Integer.parseInt(split[1]);
|
|
apkChannelMessageID = Integer.parseInt(split[2]);
|
|
UpdateLogMessageID = Integer.parseInt(split[3]);
|
|
}
|
|
}
|
|
|
|
} |