├── settings.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .deepsource.toml ├── .gitignore ├── README.md ├── src └── main │ ├── java │ └── com │ │ └── vegazsdev │ │ └── bobobot │ │ ├── exception │ │ └── BotTokenException.java │ │ ├── core │ │ ├── command │ │ │ ├── annotations │ │ │ │ └── DisableCommand.java │ │ │ ├── CommandWithClass.java │ │ │ └── Command.java │ │ ├── shell │ │ │ └── ShellStatus.java │ │ ├── bot │ │ │ ├── BuildInfo.java │ │ │ └── Bot.java │ │ └── gsi │ │ │ ├── GSICmdObj.java │ │ │ └── SourceForgeUpload.java │ │ ├── db │ │ ├── PrefObj.java │ │ └── DbThings.java │ │ ├── commands │ │ ├── fun │ │ │ └── Echo.java │ │ ├── owner │ │ │ ├── LeaveChat.java │ │ │ ├── Eval.java │ │ │ └── Chat2Shell.java │ │ ├── info │ │ │ ├── About.java │ │ │ └── Start.java │ │ ├── moderative │ │ │ ├── ChangeLang.java │ │ │ └── ChangeHotkey.java │ │ ├── gsi │ │ │ ├── SourceForgeSetup.java │ │ │ ├── Request.java │ │ │ └── ErfanGSIs.java │ │ └── android │ │ │ └── StatiXOS.java │ │ ├── utils │ │ ├── XMLs.java │ │ ├── Config.java │ │ ├── FileTools.java │ │ └── JSONs.java │ │ ├── Main.java │ │ └── TelegramBot.java │ └── resources │ ├── logback.xml │ └── strings │ ├── core-strings.xml │ ├── strings-br.xml │ └── strings-en.xml ├── .github └── dependabot.yml ├── gradlew.bat └── gradlew /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'BoboBot' 2 | 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TrebleExperience/Bot3/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[analyzers]] 4 | name = "java" 5 | enabled = true 6 | 7 | [analyzers.meta] 8 | runtime_version = "8" 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | !/.gitignore 3 | out/ 4 | downloads/ 5 | databases/ 6 | credentials/ 7 | configs/ 8 | build/ 9 | gradlew 10 | gradlew.bat 11 | bobot.log 12 | ErfanGSIs/ 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bo³+t - Treble Experience 2 | 3 | The successor to the Bot³+t fork from TrebleExperience/Projekt YuMi is [Hakalle](https://github.com/Hakalle/Haka). A more modern, modular and easy bot. 4 | 5 | This repository is abandoned and archived. 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/exception/BotTokenException.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.exception; 2 | 3 | public class BotTokenException extends Exception { 4 | public BotTokenException(String message) { 5 | super(message); 6 | } 7 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/core/command/annotations/DisableCommand.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.core.command.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | public @interface DisableCommand {} -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/core/command/CommandWithClass.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.core.command; 2 | 3 | @SuppressWarnings("rawtypes") 4 | /* 5 | * Don't need to warn about unused methods, it's useless for now, 6 | * and it is unnecessary to warn about classes that are 'parameterized' 7 | */ 8 | public record CommandWithClass(Class clazz, String alias) { 9 | public Class getClazz() { 10 | return clazz; 11 | } 12 | public String getAlias() { 13 | return alias; 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | [%boldYellow(%d{HH:mm:ss.SSS})] %boldCyan(%-34.-34thread) %red(%10.10X{jda.shard}) [%boldGreen(%-15.-15logger{0}) · %highlight(%-6level)] -> %red(%msg%n) 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/core/command/Command.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.core.command; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.db.PrefObj; 5 | import org.telegram.telegrambots.meta.api.objects.Update; 6 | 7 | /** 8 | * That class serves as a basis for command. 9 | */ 10 | public abstract class Command { 11 | private final String alias; 12 | 13 | public Command(String alias) { 14 | this.alias = alias; 15 | } 16 | 17 | public String getAlias() { 18 | return alias; 19 | } 20 | 21 | public abstract void botReply(Update update, TelegramBot bot, PrefObj prefs); 22 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/core/shell/ShellStatus.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.core.shell; 2 | 3 | public class ShellStatus { 4 | private boolean isRunning; 5 | private boolean canRun; 6 | 7 | public ShellStatus() { 8 | isRunning = true; 9 | canRun = false; 10 | } 11 | 12 | public void unlockStatus() { 13 | isRunning = false; 14 | canRun = true; 15 | } 16 | 17 | public void lockStatus() { 18 | isRunning = true; 19 | canRun = false; 20 | } 21 | 22 | public boolean canRun() { 23 | return canRun; 24 | } 25 | 26 | public boolean isRunning() { 27 | return isRunning; 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/db/PrefObj.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.db; 2 | 3 | import com.vegazsdev.bobobot.utils.XMLs; 4 | 5 | public record PrefObj(double id, String lang, String hotkey) { 6 | public double getId() { 7 | return id; 8 | } 9 | 10 | public String getLang() { 11 | return lang; 12 | } 13 | 14 | public String getString(String value) { 15 | if (XMLs.getFromStringsXML(this.getLang(), value) == null) { 16 | return XMLs.getFromStringsXML("strings-en.xml", value); 17 | } else { 18 | return XMLs.getFromStringsXML(this.getLang(), value); 19 | } 20 | } 21 | 22 | public String getHotkey() { 23 | return hotkey; 24 | } 25 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gradle 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | ignore: 9 | - dependency-name: com.google.guava:guava 10 | versions: 11 | - "23.0" 12 | - dependency-name: org.telegram:telegrambots 13 | versions: 14 | - 5.2.0 15 | - dependency-name: org.apache.commons:commons-lang3 16 | versions: 17 | - 3.12.0 18 | - dependency-name: org.xerial:sqlite-jdbc 19 | versions: 20 | - 3.34.0 21 | - dependency-name: com.google.code.gson:gson 22 | versions: 23 | - 2.8.7 24 | - dependency-name: com.jcraft:jsch 25 | versions: 26 | - 0.1.55 27 | - dependency-name: ch.qos.logback:logback-classic 28 | versions: 29 | - 1.2.3 30 | -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/core/bot/BuildInfo.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.core.bot; 2 | 3 | /** 4 | * That class show version info about build. 5 | */ 6 | public record BuildInfo(boolean doStable) { 7 | public String getVersion() { 8 | Variables variables = new Variables(); 9 | 10 | if (doStable) { 11 | return "v" + variables.VERSION + "-" + variables.STABLE + "-" + "[" + variables.CODENAME + "]"; 12 | } else { 13 | return variables.VERSION + variables.STAGING; 14 | } 15 | } 16 | 17 | private static class Variables { 18 | public final String VERSION = "1.7.0"; 19 | public final String STABLE = "STABLE"; 20 | public final String STAGING = "BETA"; 21 | public final String CODENAME = "Tsuki"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/fun/Echo.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.fun; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.db.PrefObj; 6 | import org.telegram.telegrambots.meta.api.objects.Update; 7 | 8 | @SuppressWarnings("unused") 9 | public class Echo extends Command { 10 | public Echo() { 11 | super("echo"); 12 | } 13 | 14 | @Override 15 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 16 | String[] msgComparableRaw = update.getMessage().getText().split(" "); 17 | if (update.getMessage().getText().contains(" ")) { 18 | bot.sendReply(update.getMessage().getText().substring(msgComparableRaw[0].length()), update); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/core/bot/Bot.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.core.bot; 2 | 3 | import com.vegazsdev.bobobot.exception.BotTokenException; 4 | 5 | /** 6 | * That class create main variables to TelegramLongPollingBot class. 7 | */ 8 | public class Bot { 9 | public String token; 10 | public String username; 11 | public String versionID; 12 | 13 | public Bot(String token, String username, String versionID) throws BotTokenException { 14 | if (!(token.length() >= 46)) { 15 | throw new BotTokenException("The bot token usually has a length greater than or equal to 46 characters"); 16 | } else { 17 | this.token = token; 18 | this.username = username; 19 | this.versionID = versionID; 20 | } 21 | } 22 | 23 | public String getToken() { 24 | return token; 25 | } 26 | 27 | public String getUsername() { 28 | return username.replace("@", ""); 29 | } 30 | 31 | public String getVersionID() { 32 | return versionID; 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/core/gsi/GSICmdObj.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.core.gsi; 2 | 3 | import org.telegram.telegrambots.meta.api.objects.Update; 4 | 5 | public class GSICmdObj { 6 | 7 | private String url; 8 | private String gsi; 9 | private String param; 10 | private Update update; 11 | 12 | public GSICmdObj() { 13 | } 14 | 15 | public String getUrl() { 16 | return url; 17 | } 18 | 19 | public void setUrl(String url) { 20 | this.url = url; 21 | } 22 | 23 | public String getGsi() { 24 | return gsi; 25 | } 26 | 27 | public void setGsi(String gsi) { 28 | this.gsi = gsi; 29 | } 30 | 31 | public String getParam() { 32 | return param; 33 | } 34 | 35 | public void setParam(String param) { 36 | this.param = param; 37 | } 38 | 39 | public Update getUpdate() { 40 | return update; 41 | } 42 | 43 | public void setUpdate(Update update) { 44 | this.update = update; 45 | } 46 | 47 | public void clean() { 48 | url = null; 49 | gsi = null; 50 | param = null; 51 | update = null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/owner/LeaveChat.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.owner; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.db.PrefObj; 6 | import com.vegazsdev.bobobot.utils.Config; 7 | import org.telegram.telegrambots.meta.api.objects.Update; 8 | 9 | import java.util.Objects; 10 | 11 | /** 12 | * Make the bot leave any chat you want with one command. 13 | */ 14 | @SuppressWarnings("unused") 15 | public class LeaveChat extends Command { 16 | 17 | public LeaveChat() { 18 | super("leave"); 19 | } 20 | 21 | @Override 22 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 23 | String[] msgComparableRaw = update.getMessage().getText().split(" "); 24 | if (update.getMessage().getFrom().getId() == Float.parseFloat(Objects.requireNonNull(Config.getDefConfig("bot-master")))) { 25 | if (update.getMessage().getText().contains(" ")) { 26 | if (bot.leaveChat(msgComparableRaw[1])) { 27 | bot.sendReply(prefs.getString("done_i_left"), update); 28 | } else { 29 | bot.sendReply(prefs.getString("something_went_wrong"), update); 30 | } 31 | } else { 32 | bot.sendReply(prefs.getString("bad_usage"), update); 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/resources/strings/core-strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | configs.prop 13 | ! / ; - * \ , .' 14 | en, br 15 | 16 | 17 | Bo³+t is Ready, waiting for Telegram messages! 18 | Initializing Bo³+t... 19 | [Command Classes] Initialized: %1 20 | [Command Classes] Failed to initialize: %1 21 | [Command Classes] The %1 class is not a valid command, ignoring that class from loading 22 | The properties file exists, but it does not have the correct values, fix this problem. 23 | Config file not found, creating a new one... 24 | Exception thrown, returning null 25 | Command Failure: %1 - %2 26 | %1 used %2 command 27 | The driver name is %1 28 | A new database: %1 has been created. 29 | 30 | 31 | Run this command again, it was not possible to run because the database did not exist. 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/utils/XMLs.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.utils; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.w3c.dom.Document; 6 | import org.w3c.dom.Element; 7 | import org.w3c.dom.NodeList; 8 | 9 | import javax.xml.parsers.DocumentBuilder; 10 | import javax.xml.parsers.DocumentBuilderFactory; 11 | import java.util.Objects; 12 | 13 | public class XMLs { 14 | 15 | /** 16 | * Logger: To send warning, info & errors to terminal. 17 | */ 18 | private static final Logger logger = LoggerFactory.getLogger(JSONs.class); 19 | 20 | private static Element getElementFromStrings(String xmlFile) { 21 | try { 22 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 23 | DocumentBuilder builder = factory.newDocumentBuilder(); 24 | Document document = builder.parse(Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResourceAsStream("strings/" + xmlFile))); 25 | return document.getDocumentElement(); 26 | } catch (Exception e) { 27 | logger.error(e.getMessage(), e); 28 | return null; 29 | } 30 | } 31 | 32 | public static String getFromStringsXML(String file, String tagName) { 33 | try { 34 | Element element = getElementFromStrings(file); 35 | assert element != null; 36 | NodeList list = element.getElementsByTagName(tagName); 37 | if (list != null && list.getLength() > 0) { 38 | NodeList subList = list.item(0).getChildNodes(); 39 | if (subList != null && subList.getLength() > 0) { 40 | return subList.item(0).getNodeValue(); 41 | } 42 | } 43 | } catch (Exception e) { 44 | logger.error(e.getMessage(), e); 45 | } 46 | return null; 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/core/gsi/SourceForgeUpload.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.core.gsi; 2 | 3 | import com.jcraft.jsch.ChannelSftp; 4 | import com.jcraft.jsch.JSch; 5 | import com.jcraft.jsch.Session; 6 | import com.vegazsdev.bobobot.commands.gsi.SourceForgeSetup; 7 | import org.apache.commons.lang3.RandomStringUtils; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.util.ArrayList; 12 | 13 | public class SourceForgeUpload { 14 | 15 | private static final Logger logger = LoggerFactory.getLogger(SourceForgeSetup.class); 16 | 17 | String user; 18 | String host; 19 | String pass; 20 | String proj; 21 | 22 | public SourceForgeUpload() { 23 | this.user = SourceForgeSetup.getSfConf("bot-sf-user"); 24 | this.host = SourceForgeSetup.getSfConf("bot-sf-host"); 25 | this.pass = SourceForgeSetup.getSfConf("bot-sf-pass"); 26 | this.proj = SourceForgeSetup.getSfConf("bot-sf-proj"); 27 | } 28 | 29 | public String uploadGsi(ArrayList arrayList, String name) { 30 | 31 | if (name.contains(":")) { 32 | name = name.replace(":", " - "); 33 | } 34 | 35 | name = name + " - " + RandomStringUtils.randomAlphanumeric(10).toUpperCase(); 36 | String path = "/home/frs/project/" + proj + "/" + name; 37 | 38 | try { 39 | JSch jsch = new JSch(); 40 | 41 | Session session = jsch.getSession(user, host); 42 | session.setConfig("StrictHostKeyChecking", "no"); 43 | session.setPassword(pass); 44 | session.connect(); 45 | 46 | ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp"); 47 | 48 | sftpChannel.connect(); 49 | sftpChannel.mkdir(path); 50 | 51 | for (String s : arrayList) { 52 | if (!s.endsWith(".img")) { 53 | sftpChannel.put(s, path); 54 | } 55 | } 56 | return name; 57 | } catch (Exception exception) { 58 | logger.error(exception.getMessage()); 59 | } 60 | return null; 61 | } 62 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/info/About.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.info; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.db.PrefObj; 6 | import org.telegram.telegrambots.meta.api.methods.send.SendMessage; 7 | import org.telegram.telegrambots.meta.api.objects.Update; 8 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; 9 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** 15 | * That class show some info about bot. 16 | */ 17 | @SuppressWarnings("unused") 18 | public class About extends Command { 19 | 20 | public About() { 21 | super("about"); 22 | } 23 | 24 | @Override 25 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 26 | SendMessage sendMessage = new SendMessage(); 27 | sendMessage.setText( 28 | prefs.getString("about_bot") 29 | .replace("%1", bot.getVersionID()) 30 | ); 31 | sendMessage.setChatId(String.valueOf(update.getMessage().getChatId())); 32 | sendMessage.setDisableWebPagePreview(true); 33 | sendMessage.enableHtml(true); 34 | 35 | InlineKeyboardMarkup markupInline = new InlineKeyboardMarkup(); 36 | List> rowsInline = new ArrayList<>(); 37 | 38 | List rowInline = new ArrayList<>(); 39 | InlineKeyboardButton RIL = new InlineKeyboardButton(); 40 | RIL.setText(prefs.getString("about_source_code")); 41 | RIL.setUrl("https://github.com/TrebleExperience/Bot3"); 42 | rowInline.add(RIL); 43 | 44 | List rowInline2 = new ArrayList<>(); 45 | InlineKeyboardButton RIL2 = new InlineKeyboardButton(); 46 | RIL2.setText(prefs.getString("about_treble_channel")); 47 | RIL2.setUrl("https://t.me/trebleexperience"); 48 | rowInline2.add(RIL2); 49 | 50 | rowsInline.add(rowInline); 51 | rowsInline.add(rowInline2); 52 | markupInline.setKeyboard(rowsInline); 53 | sendMessage.setReplyMarkup(markupInline); 54 | 55 | bot.sendMessageAsyncBase(sendMessage, update); 56 | } 57 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/utils/Config.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.utils; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.io.FileInputStream; 7 | import java.io.FileOutputStream; 8 | import java.util.Properties; 9 | 10 | public class Config { 11 | 12 | /** 13 | * Logger: To send warning, info & errors to terminal. 14 | */ 15 | private static final Logger logger = LoggerFactory.getLogger(Config.class); 16 | 17 | public static String getDefConfig(String prop) { 18 | FileInputStream fileInputStream = null; 19 | try { 20 | Properties getProps = new Properties(); 21 | fileInputStream = new FileInputStream("configs/configs.prop"); 22 | getProps.load(fileInputStream); 23 | return getProps.getProperty(prop); 24 | } catch (Exception e) { 25 | logger.error(e.getMessage(), e); 26 | } finally { 27 | try { 28 | if (fileInputStream != null) fileInputStream.close(); 29 | } catch (Exception exception) { 30 | logger.error(exception.getMessage()); 31 | } 32 | } 33 | return null; 34 | } 35 | 36 | public void createDefConfig() { 37 | FileOutputStream fileOutputStream = null; 38 | try { 39 | FileTools.createFolder("configs"); 40 | Properties saveProps = new Properties(); 41 | saveProps.setProperty("bot-token", "put your telegram bot token here"); 42 | saveProps.setProperty("bot-username", "put your bot user name"); 43 | saveProps.setProperty("bot-master", "put your telegram user id here"); 44 | saveProps.setProperty("requestChat", "put your main chat id for request here"); 45 | saveProps.setProperty("publicChannel", "put id or username of channel which will be used to send GSI, ex: TrebleExperience"); 46 | saveProps.setProperty("privateChat", "put your private (adm) chat id for request here"); 47 | fileOutputStream = new FileOutputStream("configs/configs.prop"); 48 | saveProps.store(fileOutputStream, null); 49 | } catch (Exception e) { 50 | logger.error(e.getMessage(), e); 51 | } finally { 52 | try { 53 | if (fileOutputStream != null) { 54 | fileOutputStream.flush(); 55 | fileOutputStream.close(); 56 | } 57 | } catch (Exception exception) { 58 | logger.error(exception.getMessage()); 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/moderative/ChangeLang.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.moderative; 2 | 3 | import com.vegazsdev.bobobot.Main; 4 | import com.vegazsdev.bobobot.TelegramBot; 5 | import com.vegazsdev.bobobot.core.command.Command; 6 | import com.vegazsdev.bobobot.db.DbThings; 7 | import com.vegazsdev.bobobot.db.PrefObj; 8 | import com.vegazsdev.bobobot.utils.XMLs; 9 | import org.telegram.telegrambots.meta.api.objects.Update; 10 | 11 | /** 12 | * That class change language of chat. 13 | */ 14 | @SuppressWarnings({"SpellCheckingInspection", "unused"}) 15 | public class ChangeLang extends Command { 16 | 17 | public ChangeLang() { 18 | super("chlang"); 19 | } 20 | 21 | @Override 22 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 23 | if (update.getMessage().getText().contains(" ")) { 24 | if (bot.isPM(update.getMessage().getChatId().toString(), update.getMessage().getFrom().getId().toString())) { 25 | if (bot.isAdmin(update.getMessage().getFrom().getId().toString(), update.getMessage().getChatId().toString())) { 26 | if (update.getMessage().getText().equals(prefs.getHotkey() + "chlang".trim())) { 27 | bot.sendReply(prefs.getString("available_lang") + "\n" + XMLs.getFromStringsXML(Main.DEF_CORE_STRINGS_XML, "disp_lang"), update); 28 | } else { 29 | String msg = update.getMessage().getText().split(" ")[1].trim(); 30 | if (msg.contains(" ")) { 31 | msg = msg.replace(" ", ""); 32 | } 33 | if (msg.length() < 3) { 34 | String hello = XMLs.getFromStringsXML("strings-" + msg + ".xml", "hello"); 35 | if (hello == null) { 36 | bot.sendReply(prefs.getString("unknown_lang").replace("%1", prefs.getHotkey()), update); 37 | } else { 38 | DbThings.changeLanguage(prefs.getId(), "strings-" + msg + ".xml"); 39 | prefs = DbThings.selectIntoPrefsTable(prefs.getId()); 40 | bot.sendReply(prefs.getString("lang_updated"), update); 41 | } 42 | } else { 43 | bot.sendReply(prefs.getString("unknown_lang").replace("%1", prefs.getHotkey()), update); 44 | } 45 | } 46 | } else { 47 | bot.sendReply(prefs.getString("only_admin_can_run"), update); 48 | } 49 | } 50 | } else { 51 | bot.sendReply(prefs.getString("bad_usage"), update); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/moderative/ChangeHotkey.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.moderative; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.db.DbThings; 6 | import com.vegazsdev.bobobot.db.PrefObj; 7 | import com.vegazsdev.bobobot.utils.XMLs; 8 | import org.telegram.telegrambots.meta.api.objects.Update; 9 | 10 | import java.util.Objects; 11 | 12 | /** 13 | * That class change hotkey of chat. 14 | */ 15 | @SuppressWarnings({"SpellCheckingInspection", "unused"}) 16 | public class ChangeHotkey extends Command { 17 | 18 | private final String supportedHotkeys = XMLs.getFromStringsXML("core-strings.xml", "possible_hotkeys"); 19 | 20 | public ChangeHotkey() { 21 | super("chkey"); 22 | } 23 | 24 | @Override 25 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 26 | if (update.getMessage().getText().contains(" ")) { 27 | if (bot.isPM(update.getMessage().getChatId().toString(), update.getMessage().getFrom().getId().toString())) { 28 | if (bot.isAdmin(update.getMessage().getFrom().getId().toString(), update.getMessage().getChatId().toString())) { 29 | if (update.getMessage().getText().trim().equals(prefs.getHotkey() + "chkey".trim())) { 30 | bot.sendReply(prefs.getString("chkey_help") 31 | .replace("%1", prefs.getHotkey()) 32 | .replace("%2", Objects.requireNonNull(supportedHotkeys)), update); 33 | } else { 34 | if (update.getMessage().getText().contains(" ")) { 35 | String msg = update.getMessage().getText().trim().split(" ")[1]; 36 | if (Objects.requireNonNull(supportedHotkeys).contains(msg)) { 37 | DbThings.changeHotkey(prefs.getId(), msg); 38 | prefs = DbThings.selectIntoPrefsTable(prefs.getId()); 39 | bot.sendReply(prefs.getString("chkey_cur_hotkey") 40 | .replace("%1", prefs.getHotkey()), update); 41 | } else { 42 | bot.sendReply(prefs.getString("chkey_error"), update); 43 | } 44 | } else { 45 | bot.sendReply(prefs.getString("something_went_wrong"), update); 46 | } 47 | } 48 | } else { 49 | bot.sendReply(prefs.getString("only_admin_can_run"), update); 50 | } 51 | } 52 | } else { 53 | bot.sendReply(prefs.getString("bad_usage"), update); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/info/Start.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.info; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.db.PrefObj; 6 | import org.telegram.telegrambots.meta.api.methods.send.SendMessage; 7 | import org.telegram.telegrambots.meta.api.objects.Update; 8 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; 9 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | @SuppressWarnings("unused") 15 | public class Start extends Command { 16 | 17 | public Start() { 18 | super("start"); 19 | } 20 | 21 | @Override 22 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 23 | /* 24 | * Prepare SendMessage 25 | */ 26 | SendMessage message = new SendMessage(); 27 | message.setDisableWebPagePreview(true); 28 | message.enableHtml(true); 29 | message.setChatId(update.getMessage().getChatId().toString()); 30 | message.setText(prefs.getString("start")); 31 | if (update.getMessage().getReplyToMessage() != null) message.setReplyToMessageId(update.getMessage().getReplyToMessage().getMessageId()); 32 | 33 | /* 34 | * Prepare InlineKeyboardButton 35 | */ 36 | InlineKeyboardMarkup markupInline = new InlineKeyboardMarkup(); 37 | List> rowsInline = new ArrayList<>(); 38 | 39 | /* 40 | * Prepare InlineKeyboardButton: Source code 41 | */ 42 | List ListInlineKeyboardButtonSourceCode = new ArrayList<>(); 43 | InlineKeyboardButton ListInlineKeyboardButton = new InlineKeyboardButton(); 44 | ListInlineKeyboardButton.setText(prefs.getString("start_source_code")); 45 | ListInlineKeyboardButton.setUrl("https://github.com/TrebleExperience/Bot3"); 46 | ListInlineKeyboardButtonSourceCode.add(ListInlineKeyboardButton); 47 | rowsInline.add(ListInlineKeyboardButtonSourceCode); 48 | 49 | /* 50 | * Prepare InlineKeyboardButton: TrebleExperience Channel 51 | */ 52 | List ListInlineKeyboardButtonChannel = new ArrayList<>(); 53 | InlineKeyboardButton ListInlineKeyboardButtonChannelBTN = new InlineKeyboardButton(); 54 | ListInlineKeyboardButtonChannelBTN.setText(prefs.getString("start_treble_experience")); 55 | ListInlineKeyboardButtonChannelBTN.setUrl("https://t.me/TrebleExperience"); 56 | ListInlineKeyboardButtonChannel.add(ListInlineKeyboardButtonChannelBTN); 57 | rowsInline.add(ListInlineKeyboardButtonChannel); 58 | 59 | /* 60 | * Finish InlineKeyboardButton setup 61 | */ 62 | markupInline.setKeyboard(rowsInline); 63 | message.setReplyMarkup(markupInline); 64 | 65 | /* 66 | * Send the message 67 | */ 68 | bot.sendMessageAsyncBase(message, update); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/owner/Eval.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.owner; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.core.command.annotations.DisableCommand; 6 | import com.vegazsdev.bobobot.db.PrefObj; 7 | import com.vegazsdev.bobobot.utils.Config; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.telegram.telegrambots.meta.api.objects.Update; 11 | 12 | import javax.script.ScriptEngine; 13 | import javax.script.ScriptEngineManager; 14 | import java.util.Objects; 15 | 16 | import static com.vegazsdev.bobobot.Main.shellStatus; 17 | 18 | /** 19 | * Execute some commands using one command, this is Eval. 20 | * That command has been disabled. 21 | */ 22 | @DisableCommand 23 | @SuppressWarnings("unused") 24 | public class Eval extends Command { 25 | 26 | /** 27 | * Logger: To send warning, info & errors to terminal. 28 | */ 29 | private static final Logger logger = LoggerFactory.getLogger(Eval.class); 30 | 31 | public Eval() { 32 | super("eval"); 33 | } 34 | 35 | @SuppressWarnings("SpellCheckingInspection") 36 | @Override 37 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 38 | ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 39 | String[] msgComparableRaw = update.getMessage().getText().split(" "); 40 | 41 | if (update.getMessage().getFrom().getId() == Float.parseFloat(Objects.requireNonNull(Config.getDefConfig("bot-master")))) { 42 | try { 43 | engine.eval("var imports = new JavaImporter(" + 44 | "java," + 45 | "java.io," + 46 | "java.lang," + 47 | "java.util," + 48 | "Packages.com.vegazsdev.bobobot.commands" + 49 | "Packages.org.telegram.telegrambots," + 50 | "Packages.org.telegram.telegrambots.meta.api.methods," + 51 | "Packages.org.telegram.telegrambots.meta.api.objects" + 52 | ");" 53 | ); 54 | 55 | engine.put("args", msgComparableRaw); 56 | engine.put("bot", bot); 57 | engine.put("shell", shellStatus); 58 | engine.put("engine", engine); 59 | engine.put("update", update); 60 | engine.put("prefs", prefs); 61 | 62 | String command = update.getMessage().getText().substring(msgComparableRaw[0].length()); 63 | 64 | Object out = engine.eval( 65 | "(function() {" + 66 | "with (imports) {\n" + 67 | command + 68 | "\n}" + 69 | "})();" 70 | ); 71 | 72 | bot.sendMessageAsync(out == null ? "Executed without error." : out.toString(), update); 73 | } catch (Exception exception) { 74 | bot.sendMessageAsync("`" + exception.getMessage() + "`", update); 75 | logger.error(exception.getMessage()); 76 | } 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/utils/FileTools.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.utils; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.io.*; 7 | import java.util.zip.GZIPOutputStream; 8 | 9 | public class FileTools { 10 | 11 | /** 12 | * Logger: To send warning, info & errors to terminal. 13 | */ 14 | private static final Logger logger = LoggerFactory.getLogger(FileTools.class); 15 | 16 | public static boolean checkIfFolderExists(String folder) { 17 | File file = new File(folder); 18 | return file.exists() && file.isDirectory(); 19 | } 20 | 21 | public static void createFolder(String folder) { 22 | if (!checkIfFolderExists(folder)) { 23 | File dir = new File(folder); 24 | dir.mkdir(); 25 | } 26 | } 27 | 28 | public static boolean deleteFolder(String folder) { 29 | File file = new File(folder); 30 | return file.delete(); 31 | } 32 | 33 | public static boolean checkFileExistsCurPath(String file) { 34 | File f = new File(file); 35 | return f.exists() && !f.isDirectory(); 36 | } 37 | 38 | public void gzipFile(String source_filepath, String dest) { 39 | FileOutputStream fileOutputStream = null; 40 | GZIPOutputStream gzipOutputStream = null; 41 | FileInputStream fileInput = null; 42 | 43 | byte[] buffer = new byte[1024]; 44 | 45 | try { 46 | fileOutputStream = new FileOutputStream(dest); 47 | gzipOutputStream = new GZIPOutputStream(fileOutputStream); 48 | fileInput = new FileInputStream(source_filepath); 49 | 50 | int bytes_read; 51 | 52 | while ((bytes_read = fileInput.read(buffer)) > 0) { 53 | gzipOutputStream.write(buffer, 0, bytes_read); 54 | } 55 | 56 | fileInput.close(); 57 | } catch (Exception e) { 58 | logger.error(e.getMessage(), e); 59 | } finally { 60 | try { 61 | if (gzipOutputStream != null) { 62 | gzipOutputStream.finish(); 63 | gzipOutputStream.close(); 64 | } 65 | 66 | if (fileInput != null) fileInput.close(); 67 | 68 | if (fileOutputStream != null) { 69 | fileOutputStream.flush(); 70 | fileOutputStream.close(); 71 | } 72 | } catch (Exception exception) { 73 | logger.error(exception.getMessage()); 74 | } 75 | } 76 | } 77 | 78 | public String readFile(String fileName) { 79 | BufferedReader bufferedReader = null; 80 | FileReader fileReader = null; 81 | 82 | StringBuilder stringBuilder = new StringBuilder(); 83 | String line; 84 | 85 | try { 86 | fileReader = new FileReader(fileName); 87 | bufferedReader = new BufferedReader(fileReader); 88 | 89 | line = bufferedReader.readLine(); 90 | 91 | while (line != null) { 92 | stringBuilder.append(line); 93 | stringBuilder.append("\n"); 94 | line = bufferedReader.readLine(); 95 | } 96 | return stringBuilder.toString(); 97 | } catch (Exception exception) { 98 | logger.error(exception.getMessage()); 99 | } finally { 100 | try { 101 | if (fileReader != null) fileReader.close(); 102 | if (bufferedReader != null) bufferedReader.close(); 103 | } catch (Exception exception) { 104 | logger.error(exception.getMessage()); 105 | } 106 | } 107 | return null; 108 | } 109 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/gsi/SourceForgeSetup.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.gsi; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.db.PrefObj; 6 | import com.vegazsdev.bobobot.utils.Config; 7 | import com.vegazsdev.bobobot.utils.FileTools; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.telegram.telegrambots.meta.api.objects.Update; 11 | 12 | import java.io.FileInputStream; 13 | import java.io.FileOutputStream; 14 | import java.io.IOException; 15 | import java.util.Objects; 16 | import java.util.Properties; 17 | 18 | /** 19 | * This class is important for the ErfanGSI command. 20 | *

21 | * That class setup sourceforge prop file for GSI upload. 22 | */ 23 | public class SourceForgeSetup extends Command { 24 | 25 | /** 26 | * Logger: To send warning, info & errors to terminal. 27 | */ 28 | private static final Logger logger = LoggerFactory.getLogger(SourceForgeSetup.class); 29 | 30 | public SourceForgeSetup() { 31 | super("sfs"); 32 | } 33 | 34 | /** 35 | * Get prop from sourceforge config file. 36 | */ 37 | @SuppressWarnings("SpellCheckingInspection") 38 | public static String getSfConf(String prop) { 39 | FileInputStream fileInputStream = null; 40 | try { 41 | Properties getProps = new Properties(); 42 | fileInputStream = new FileInputStream("configs/sf-creds.prop"); 43 | getProps.load(fileInputStream); 44 | return getProps.getProperty(prop); 45 | } catch (Exception exception) { 46 | logger.error(exception.getMessage()); 47 | } finally { 48 | if (fileInputStream != null) { 49 | try { 50 | fileInputStream.close(); 51 | } catch (IOException ioException) { 52 | logger.error(ioException.getMessage()); 53 | } 54 | } 55 | } 56 | return null; 57 | } 58 | 59 | @SuppressWarnings("SpellCheckingInspection") 60 | @Override 61 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 62 | if (update.getMessage().getFrom().getId() == Float.parseFloat(Objects.requireNonNull(Config.getDefConfig("bot-master")))) { 63 | if (FileTools.checkFileExistsCurPath("configs/sf-creds.prop")) { 64 | bot.sendReply(prefs.getString("unable_to_create"), update); 65 | } else { 66 | mkSfConf(); 67 | bot.sendReply(prefs.getString("created_sf_folder"), update); 68 | } 69 | } 70 | } 71 | 72 | /** 73 | * Method to setup sourceforge config file. 74 | */ 75 | @SuppressWarnings("SpellCheckingInspection") 76 | public void mkSfConf() { 77 | FileOutputStream fileOutputStream = null; 78 | 79 | try { 80 | Properties saveProps = new Properties(); 81 | if (!FileTools.checkFileExistsCurPath("configs/sf-creds.prop")) { 82 | saveProps.setProperty("bot-sf-user", "put your sf username"); 83 | saveProps.setProperty("bot-sf-host", "frs.sourceforge.net"); 84 | saveProps.setProperty("bot-sf-pass", "put your sf pass"); 85 | saveProps.setProperty("bot-sf-proj", "put your sf project name"); 86 | saveProps.setProperty("bot-send-announcement", "false"); 87 | saveProps.setProperty("bot-announcement-id", "none"); 88 | 89 | fileOutputStream = new FileOutputStream("configs/sf-creds.prop"); 90 | saveProps.store(fileOutputStream, null); 91 | } 92 | } catch (Exception exception) { 93 | logger.error(exception.getMessage()); 94 | } finally { 95 | if (fileOutputStream != null) { 96 | try { 97 | fileOutputStream.flush(); 98 | fileOutputStream.close(); 99 | } catch (IOException ioException) { 100 | logger.error(ioException.getMessage()); 101 | } 102 | } 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/db/DbThings.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.db; 2 | 3 | import com.vegazsdev.bobobot.Main; 4 | import com.vegazsdev.bobobot.utils.FileTools; 5 | import com.vegazsdev.bobobot.utils.XMLs; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import java.sql.*; 10 | import java.util.Objects; 11 | 12 | public class DbThings { 13 | 14 | /** 15 | * Logger: To send warning, info & errors to terminal. 16 | */ 17 | private static final Logger logger = LoggerFactory.getLogger(DbThings.class); 18 | 19 | public static void createNewDatabase(String database) { 20 | if (!FileTools.checkIfFolderExists("databases")) { 21 | FileTools.createFolder("databases"); 22 | } 23 | try (Connection conn = connect(database)) { 24 | if (conn != null) { 25 | DatabaseMetaData meta = conn.getMetaData(); 26 | logger.info(Objects.requireNonNull( 27 | XMLs.getFromStringsXML(Main.DEF_CORE_STRINGS_XML, "sql_driver_info")) 28 | .replace("%1", meta.getDriverName())); 29 | logger.info(Objects.requireNonNull( 30 | XMLs.getFromStringsXML(Main.DEF_CORE_STRINGS_XML, "sql_db_ok")) 31 | .replace("%1", database)); 32 | } 33 | } catch (SQLException e) { 34 | logger.error(e.getMessage(), e); 35 | } 36 | } 37 | 38 | private static Connection connect(String database) { 39 | String url = "jdbc:sqlite:databases/" + database; 40 | Connection conn = null; 41 | try { 42 | conn = DriverManager.getConnection(url); 43 | } catch (SQLException e) { 44 | logger.error(e.getMessage(), e); 45 | } 46 | return conn; 47 | } 48 | 49 | public static void createTable(String database, String query) { 50 | try (Connection conn = connect(database); 51 | Statement stmt = conn.createStatement()) { 52 | stmt.execute(query); 53 | } catch (SQLException e) { 54 | logger.error(e.getMessage(), e); 55 | } 56 | } 57 | 58 | // specific prefs.db methods 59 | 60 | public static void insertIntoPrefsTable(double id) { 61 | String sql = "INSERT INTO chat_prefs(group_id) VALUES(?)"; 62 | try (Connection conn = connect("prefs.db"); 63 | PreparedStatement prepareStatement = conn.prepareStatement(sql)) { 64 | prepareStatement.setDouble(1, id); 65 | prepareStatement.executeUpdate(); 66 | } catch (SQLException e) { 67 | logger.error(e.getMessage()); 68 | } 69 | } 70 | 71 | public static PrefObj selectIntoPrefsTable(double id) { 72 | String sql = "SELECT group_id, lang, hotkey FROM chat_prefs WHERE group_id = " + id; 73 | PrefObj prefObj = null; 74 | try (Connection conn = connect("prefs.db"); 75 | Statement stmt = conn.createStatement(); 76 | ResultSet rs = stmt.executeQuery(sql)) { 77 | while (rs.next()) { 78 | prefObj = new PrefObj(rs.getDouble("group_id"), rs.getString("lang"), rs.getString("hotkey")); 79 | } 80 | } catch (SQLException e) { 81 | logger.error(e.getMessage()); 82 | } 83 | return prefObj; 84 | } 85 | 86 | public static void changeLanguage(double groupId, String newLang) { 87 | String sql = "UPDATE chat_prefs SET lang = '" + newLang + "' WHERE group_id = " + groupId; 88 | try (Connection conn = connect("prefs.db"); 89 | PreparedStatement prepareStatement = conn.prepareStatement(sql)) { 90 | prepareStatement.executeUpdate(); 91 | } catch (SQLException e) { 92 | logger.error(e.getMessage()); 93 | } 94 | } 95 | 96 | public static void changeHotkey(double groupId, String newHotkey) { 97 | String sql = "UPDATE chat_prefs SET hotkey = '" + newHotkey + "' WHERE group_id = " + groupId; 98 | try (Connection conn = connect("prefs.db"); 99 | PreparedStatement prepareStatement = conn.prepareStatement(sql)) { 100 | prepareStatement.executeUpdate(); 101 | } catch (SQLException e) { 102 | logger.error(e.getMessage()); 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/utils/JSONs.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.utils; 2 | 3 | import com.google.common.annotations.Beta; 4 | import com.google.gson.Gson; 5 | import com.vegazsdev.bobobot.Main; 6 | import org.json.JSONArray; 7 | import org.json.JSONObject; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.io.*; 12 | import java.util.ArrayList; 13 | 14 | public class JSONs { 15 | 16 | /** 17 | * Logger: To send warning, info & errors to terminal. 18 | */ 19 | private static final Logger logger = LoggerFactory.getLogger(JSONs.class); 20 | 21 | public static void writeArrayToJSON(ArrayList values, String file) { 22 | Gson gson = new Gson(); 23 | FileOutputStream fileOutputStream = null; 24 | 25 | try { 26 | fileOutputStream = new FileOutputStream(file); 27 | fileOutputStream.write(gson.toJson(values).getBytes()); 28 | fileOutputStream.close(); 29 | } catch (Exception e) { 30 | logger.error(e.getMessage(), e); 31 | } finally { 32 | if (fileOutputStream != null) { 33 | try { 34 | fileOutputStream.flush(); 35 | fileOutputStream.close(); 36 | } catch (IOException ioException) { 37 | logger.error(ioException.getMessage()); 38 | } 39 | } 40 | } 41 | } 42 | 43 | @SuppressWarnings("rawtypes") 44 | public static ArrayList getArrayFromJSON(String file) { 45 | Gson gson = new Gson(); 46 | 47 | FileInputStream fileInputStream = null; 48 | InputStreamReader inputStreamReader = null; 49 | BufferedReader bufferedReader = null; 50 | 51 | try { 52 | fileInputStream = new FileInputStream(file); 53 | inputStreamReader = new InputStreamReader(fileInputStream); 54 | bufferedReader = new BufferedReader(inputStreamReader); 55 | StringBuilder stringBuilder = new StringBuilder(); 56 | 57 | String line; 58 | 59 | while ((line = bufferedReader.readLine()) != null) { 60 | stringBuilder.append(line); 61 | } 62 | 63 | String json = stringBuilder.toString(); 64 | return gson.fromJson(json, ArrayList.class); 65 | } catch (Exception e) { 66 | logger.error(XMLs.getFromStringsXML(Main.DEF_CORE_STRINGS_XML, "config_file_not_found") + "\n" + e.getMessage(), e); 67 | return null; 68 | } finally { 69 | if (fileInputStream != null) { 70 | try { 71 | fileInputStream.close(); 72 | } catch (IOException ioException) { 73 | logger.error(ioException.getMessage(), ioException); 74 | } 75 | } 76 | 77 | if (inputStreamReader != null) { 78 | try { 79 | inputStreamReader.close(); 80 | } catch (IOException ioException) { 81 | logger.error(ioException.getMessage(), ioException); 82 | } 83 | } 84 | 85 | if (bufferedReader != null) { 86 | try { 87 | bufferedReader.close(); 88 | } catch (IOException ioException) { 89 | logger.error(ioException.getMessage(), ioException); 90 | } 91 | } 92 | } 93 | } 94 | 95 | // START: LAZY METHODS 96 | @Beta 97 | public static String getValueOfArrayFromJSONObject(String json, String array, String value) { 98 | try { 99 | JSONObject jsonObject = new JSONObject(json); 100 | JSONArray jsonArray = jsonObject.getJSONArray(array); 101 | return jsonArray.getJSONObject(0).getString(value); 102 | } catch (Exception exception) { 103 | logger.error(exception.getMessage(), exception); 104 | } 105 | return null; 106 | } 107 | 108 | @Beta 109 | public static long getLongOfArrayFromJSONObject(String json, String array, String value) { 110 | try { 111 | JSONObject jsonObject = new JSONObject(json); 112 | JSONArray jsonArray = jsonObject.getJSONArray(array); 113 | return jsonArray.getJSONObject(0).getLong(value); 114 | } catch (Exception exception) { 115 | logger.error(exception.getMessage(), exception); 116 | } 117 | return 0; 118 | } 119 | // END: LAZY METHODS 120 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/android/StatiXOS.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.android; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.db.PrefObj; 6 | import com.vegazsdev.bobobot.utils.JSONs; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.telegram.telegrambots.meta.api.methods.send.SendMessage; 10 | import org.telegram.telegrambots.meta.api.objects.Update; 11 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; 12 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; 13 | 14 | import java.net.URI; 15 | import java.net.http.HttpClient; 16 | import java.net.http.HttpRequest; 17 | import java.net.http.HttpResponse; 18 | import java.sql.Timestamp; 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | /** 23 | * That class is for StatiXOS. 24 | */ 25 | @SuppressWarnings({"unused", "SpellCheckingInspection"}) 26 | public class StatiXOS extends Command { 27 | 28 | private static final Logger logger = LoggerFactory.getLogger(StatiXOS.class); 29 | 30 | public StatiXOS() { 31 | super("sxos"); 32 | } 33 | 34 | @Override 35 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 36 | /* 37 | * Main vars 38 | */ 39 | String[] msgComparableRaw = update.getMessage().getText().split(" "); 40 | 41 | /* 42 | * Prepare sendMessage 43 | */ 44 | SendMessage sendMessage = new SendMessage(); 45 | sendMessage.setDisableWebPagePreview(true); 46 | sendMessage.enableHtml(true); 47 | 48 | /* 49 | * Prepare InlineKeyboardButton 50 | */ 51 | InlineKeyboardMarkup markupInline = new InlineKeyboardMarkup(); 52 | List> rowsInline = new ArrayList<>(); 53 | 54 | if (update.getMessage().getText().contains(" ")) { 55 | /* 56 | * Try to run 57 | */ 58 | try { 59 | /* 60 | * Prepare HttpClient base 61 | */ 62 | String urlBase = "https://downloads.statixos.com/json/"; 63 | HttpClient client = HttpClient.newHttpClient(); 64 | HttpRequest request = HttpRequest.newBuilder() 65 | .uri(URI.create(urlBase + msgComparableRaw[1].replace(".json", "") + ".json")) 66 | .build(); 67 | 68 | /* 69 | * Run the request 70 | */ 71 | client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) 72 | .thenApply(response -> { 73 | if (response.statusCode() == 200) { 74 | /* 75 | * Prepare the variables 76 | */ 77 | Timestamp timestamp = new Timestamp(JSONs.getLongOfArrayFromJSONObject(String.valueOf(response.body()), "response", "datetime")); 78 | String urlToDownload = JSONs.getValueOfArrayFromJSONObject(String.valueOf(response.body()), "response", "url"); 79 | String romType = JSONs.getValueOfArrayFromJSONObject(String.valueOf(response.body()), "response", "romtype"); 80 | String romName = JSONs.getValueOfArrayFromJSONObject(String.valueOf(response.body()), "response", "filename"); 81 | String romVersion = JSONs.getValueOfArrayFromJSONObject(String.valueOf(response.body()), "response", "version"); 82 | String ID = JSONs.getValueOfArrayFromJSONObject(String.valueOf(response.body()), "response", "id"); 83 | 84 | /* 85 | * Set download variable into Inline Keyboard Button 86 | */ 87 | List inlineKeyboardButtonArrayList = new ArrayList<>(); 88 | InlineKeyboardButton downloadROM = new InlineKeyboardButton(); 89 | 90 | downloadROM.setText("\uD83D\uDCE6 Download"); 91 | downloadROM.setUrl(urlToDownload); 92 | inlineKeyboardButtonArrayList.add(downloadROM); 93 | rowsInline.add(inlineKeyboardButtonArrayList); 94 | 95 | /* 96 | * Finish 97 | */ 98 | markupInline.setKeyboard(rowsInline); 99 | sendMessage.setReplyMarkup(markupInline); 100 | 101 | /* 102 | * Set the text 103 | */ 104 | sendMessage.setChatId(String.valueOf(update.getMessage().getChatId())); 105 | sendMessage.setText( 106 | "✉️ File name\n" 107 | + romName + "\n\n" 108 | + "❓ Status Type\n" 109 | + romType + "\n\n" 110 | + "\uD83D\uDCCD ID\n" 111 | + ID + "\n\n" 112 | + "\uD83D\uDD30 Version\n" 113 | + romVersion + "" 114 | ); 115 | bot.sendMessageAsyncBase(sendMessage, update); 116 | } else { 117 | bot.sendReply("Failed", update); 118 | } 119 | return response; 120 | }) 121 | .thenApply(HttpResponse::body); 122 | } catch (Exception exception) { 123 | logger.error(exception.getMessage()); 124 | } 125 | } else { 126 | bot.sendReply(prefs.getString("bad_usage"), update); 127 | } 128 | } 129 | } -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /src/main/resources/strings/strings-br.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Algo deu errado, Tente fazer o processo novamente 6 | Apenas o Mestre do Bot pode usar esse comando 7 | Apenas Administradores podem usar esse comando 8 | Mal uso. 9 | 10 | 11 | Olá! Como você está? 👋 Fui desenvolvido especialmente para servir de automatização para ErfanGSIs, não tenho muitas funções além disso. 12 | 🔧 Código-fonte 13 | 📫 Canal da TrebleExperience 14 | 15 | 16 | ❔<b> Sobre</b> <b>Bo³+t</b> é programado em java e originalmente desenvolvido por @VegaZS ⌨<b> Desenvolvedor/Mantenedor do Bo³+t</b> <a href="https://github.com/VegaBobo">VegaZS</a> - Desenvolvedor original <a href="https://github.com/Velosh">Velosh</a> - Mantenedor não oficial do <b>Bo³+t</b> para Treble Experience ❕<b> Info da Build</b> <code>%1</code> 17 | ❕ Código-fonte 18 | 🌐 Canal do Treble 19 | 20 | 21 | Linguagens Disponíveis: 22 | Linguagem Atualizada! 23 | Idioma não disponível, digite %1chlang para ver os idiomas disponíveis 24 | 25 | 26 | ID do usuário: <b>%1</b> agora tem permissões para portar GSIs 27 | Para adicionar permissões, responda o usuário desejado com: <code>%1%2 allowuser</code> 28 | <b>Ports na Fila:</b> %1 <i>%2</i> 29 | Port adicionado na fila. 30 | Sem ports na fila. 31 | <b>Tipo de GSI ou URL invalida!</b> ipos de GSIs suportadas no Android 10: %1 Tipos de GSIs suportadas no Android 11: %2 Tipos de GSIs suportadas no Android S: %3 32 | A pasta da ferramenta ErfanGSIs não existe. 33 | Algo está errado, cheque se você está usando a tool do ErfanGSIs atualizada. 34 | Bip bop... Algo de errado não está certo, o processo de fazer GSI falhou, cheque se tem algo errado. 35 | Pronto! A GSI <b>%1</b> foi feita com sucesso por <a href="tg://user?id=%2">%3</a>, você pode ver mais sobre essa GSI com este <a href="https://t.me/%4/%5">link</a>. 36 | 37 | 38 | ID do usuário: <b>%1</b> agora tem permissões para portar SGSIs 39 | Para adicionar permissões, responda o usuário desejado com: <code>%1%2 allowuser</code> 40 | <b>Ports na Fila:</b> %1 <i>%2</i> 41 | Port adicionado na fila. 42 | Sem ports na fila. 43 | <b>Tipo de SGSI ou URL invalida!</b> Tipos de SGSIs suportadas no Android 9: %1 Tipos de GSIs suportadas no Android 10: %2 Tipos de GSIs suportadas no Android 11: %3 Tipos de GSIs suportadas no Android 12: %4 44 | A pasta da ferramenta XiaoxindadaGSIs não existe. 45 | Algo está errado, cheque se você está usando a tool do XiaoxindadaGSIs atualizada. 46 | Bip bop... Algo de errado não está certo, o processo de fazer SGSI falhou, cheque se tem algo errado. 47 | 48 | 49 | Current bot hotkey on this chat: <b>%1</b> <b>Supported Hotkeys: %2</b> 50 | Hotkey atual deste chat: <b>%1</b> 51 | Desculpe, não é possível trocar, provavelmente essa hotkey não é compatível 52 | 53 | 54 | 📩 <b>Novo pedido de GSI recebido!</b> 55 | ❕ <b>Informação adicional</b> 56 | ❔ <b>Info do usuário</b> 57 | Olá <a href="tg://user?id=%2">%1</a> (<code>%3</code>), sua solicitação foi enviada! Espere agora. 58 | <b>• Nome:</b> <code>%1</code> 59 | <b>• Nome de usuário:</b> <code>%1</code> 60 | <b>• ID do usuário:</b> <code>%1</code> 61 | Não tem 62 | Informação não compartilhada pelo usuário. 63 | Olá <a href="tg://user?id=%2">%1</a> (<code>%3</code>), o link que você enviou parece ser inválido! Use com parâmetros http e tente novamente. 64 | Este bot não pode ser usado em outros locais! 65 | Não é possível enviar o pedido, a variável de chat privado não existe ou não tem valor. 66 | Não é possível enviar o pedido, a variável de chat público não existe ou não tem valor. 67 | As variáveis do chat (público e privado) devem ser utilizadas e implementadas na forma de Bot API, verifique se está correto. 68 | 69 | 70 | É impossível criar, pois já existe um arquivo de propriedades do SourceForge 71 | Verifique sua pasta de configuração 72 | 73 | 74 | Desculpe, o comando <code>shell</code> está bloqueado (provavelmente existe outro comando <code>shell</code> em execução). 75 | Código de retorno: <code>%1</code>, comando shell desbloqueado. 76 | 77 | 78 | Pronto. 79 | 80 | -------------------------------------------------------------------------------- /src/main/resources/strings/strings-en.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | Something went wrong, try to do the process again 22 | Only Bot Master can use this command 23 | Only Administrators can use this command 24 | Bad usage. 25 | 26 | 27 | Hey there! How are you? 👋 I was developed especially to serve as an automation for ErfanGSIs, I don't have many functions beyond that. 28 | 🔧 Source Code 29 | 📫 TrebleExperience Channel 30 | 31 | 32 | ❔<b> About</b> <b>Bo³+t</b> is written in java and originally developed by @VegaZS ⌨<b> Developer/Maintainer of Bo³+t</b> <a href="https://github.com/VegaBobo">VegaZS</a> - Original dev <a href="https://github.com/Velosh">Velosh</a> - Unofficial maintainer of <b>Bo³+t</b> for Treble Experience ❕<b> Build Info</b> <code>%1</code> 33 | ❕ Source code 34 | 🌐 Treble Channel 35 | 36 | 37 | Available Languages: 38 | Language Updated! 39 | Language not available, type %1chlang to see available languages 40 | 41 | 42 | UserID: <b>%1</b> now has port permissions 43 | To add permissions, reply to user that you wanna add permissions, by using <code>%1%2 allowuser</code> 44 | <b>Ports on Queue:</b> %1 <i>%2</i> 45 | Added to queue. 46 | No ports on queue. 47 | <b>GSI Type or URL is not valid!</b> Supported types on Android 10: %1 Supported types on Android 11: %2 Supported types on Android 12: %3 48 | The ErfanGSIs tool folder does not exist. 49 | Something is wrong, check if you are using the updated ErfanGSIs tool. 50 | Beep bop... Something wrong isn't correct, the GSI process failed, check if something is wrong. 51 | Done! <b>%1</b> GSI was successfully built by <a href="tg://user?id=%2">%3</a>, you can see more about this GSI with this <a href="https://t.me/%4/%5">link</a>. 52 | 53 | 54 | UserID: <b>%1</b> now has port permissions 55 | To add permissions, reply to user that you wanna add permissions, by using <code>%1%2 allowuser</code> 56 | <b>Ports on Queue:</b> %1 <i>%2</i> 57 | Added to queue. 58 | No ports on queue. 59 | <b>SGSI Type or URL is not valid!</b> Supported types on Android 9: %1 Supported types on Android 10: %2 Supported types on Android 11: %3 Supported types on Android 12: %4 60 | The XiaoxindadaSGSIs tool folder does not exist. 61 | Something is wrong, check if you are using the updated XiaoxindadaSGSIs tool. 62 | Beep bop... Something wrong isn't correct, the GSI process failed, check if something is wrong. 63 | 64 | 65 | Current bot hotkey on this chat: <code>%1</code> <b>Supported Hotkeys: %2</b> 66 | Current hotkey now is: <b>%1</b> 67 | Sorry, it is not possible to change, this hotkey is probably not compatible 68 | 69 | 70 | 📩 <b>New GSI order received!</b> 71 | ❕ <b>Additional information</b> 72 | ❔ <b>User info</b> 73 | Hello <a href="tg://user?id=%2">%1</a> (<code>%3</code>) your request has been sent! Just wait now. 74 | <b>• Name:</b> <code>%1</code> 75 | <b>• Username:</b> <code>%1</code> 76 | <b>• User ID:</b> <code>%1</code> 77 | Don't have 78 | Information not shared by the user. 79 | Hello <a href="tg://user?id=%2">%1</a> (<code>%3</code>), the link you sent appears to be invalid! Use with http parameters and try again. 80 | This bot cannot be used in other locations! 81 | Can't send request, the private chat variable does not exist or has no value. 82 | Can't send request, the public chat variable does not exist or has no value. 83 | The chat (public and private) variables must be used and implemented in the form of Bot API, check if it is correct. 84 | 85 | 86 | It is impossible to create, as a SourceForge properties file already exists 87 | Check your config folder 88 | 89 | 90 | Sorry, the <code>shell</code> command is locked (Probably exists other shell command running). 91 | Return code: <code>%1</code>, shell command unlocked. 92 | 93 | 94 | Done. 95 | 96 | -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/owner/Chat2Shell.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.owner; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.db.PrefObj; 6 | import com.vegazsdev.bobobot.utils.Config; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.telegram.telegrambots.meta.api.objects.Update; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.io.InputStreamReader; 15 | import java.util.Objects; 16 | 17 | import static com.vegazsdev.bobobot.Main.shellStatus; 18 | 19 | /** 20 | * This class is for shell command, don't need to say anything. 21 | */ 22 | @SuppressWarnings("unused") 23 | public class Chat2Shell extends Command { 24 | 25 | /** 26 | * Logger: To send warning, info & errors to terminal. 27 | */ 28 | private static final Logger logger = LoggerFactory.getLogger(Chat2Shell.class); 29 | 30 | public Chat2Shell() { 31 | super("shell"); 32 | } 33 | 34 | /** 35 | * Run bash command with this method. 36 | */ 37 | public static String runBash(String command) { 38 | StringBuilder baseCommand = new StringBuilder(); 39 | InputStream inputStream = null; 40 | InputStreamReader inputStreamReader = null; 41 | BufferedReader bufferedReader = null; 42 | try { 43 | /* 44 | * Process base 45 | */ 46 | ProcessBuilder pb; 47 | pb = new ProcessBuilder("/bin/bash", "-c", command); 48 | pb.redirectErrorStream(true); 49 | Process process = pb.start(); 50 | 51 | /* 52 | * Stream base 53 | */ 54 | inputStream = process.getInputStream(); 55 | inputStreamReader = new InputStreamReader(inputStream); 56 | bufferedReader = new BufferedReader(inputStreamReader); 57 | 58 | String line; 59 | 60 | while ((line = bufferedReader.readLine()) != null) { 61 | baseCommand.append(line); 62 | } 63 | return String.valueOf(baseCommand); 64 | } catch (Exception exception) { 65 | logger.error(exception.getMessage(), exception); 66 | } finally { 67 | if (inputStream != null) { 68 | try { 69 | inputStream.close(); 70 | } catch (IOException ioException) { 71 | logger.error(ioException.getMessage(), ioException); 72 | } 73 | } 74 | 75 | if (inputStreamReader != null) { 76 | try { 77 | inputStreamReader.close(); 78 | } catch (IOException ioException) { 79 | logger.error(ioException.getMessage(), ioException); 80 | } 81 | } 82 | 83 | if (bufferedReader != null) { 84 | try { 85 | bufferedReader.close(); 86 | } catch (IOException ioException) { 87 | logger.error(ioException.getMessage(), ioException); 88 | } 89 | } 90 | } 91 | return null; 92 | } 93 | 94 | @SuppressWarnings("SpellCheckingInspection") 95 | @Override 96 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 97 | if (update.getMessage().getFrom().getId() == Float.parseFloat(Objects.requireNonNull(Config.getDefConfig("bot-master")))) { 98 | if (shellStatus.canRun() && !shellStatus.isRunning()) { 99 | /* 100 | * Lock status, until the Shell process ends 101 | */ 102 | shellStatus.lockStatus(); 103 | 104 | String msg = update.getMessage().getText().substring(7); 105 | 106 | ProcessBuilder processBuilder; 107 | processBuilder = new ProcessBuilder("/bin/bash", "-c", msg); 108 | 109 | StringBuilder fullLogs = new StringBuilder(); 110 | fullLogs.append("").append(runBash("whoami")).append("").append(" (").append(runBash("uname -n")).append(")").append(" ~ ").append(update.getMessage().getText().substring(7)).append("\n"); 111 | 112 | int id = bot.sendReply(fullLogs.toString(), update); 113 | 114 | InputStream inputStream = null; 115 | InputStreamReader inputStreamReader = null; 116 | BufferedReader bufferedReader = null; 117 | try { 118 | processBuilder.redirectErrorStream(true); 119 | Process process = processBuilder.start(); 120 | 121 | inputStream = process.getInputStream(); 122 | inputStreamReader = new InputStreamReader(inputStream); 123 | bufferedReader = new BufferedReader(inputStreamReader); 124 | 125 | String line; 126 | 127 | while ((line = bufferedReader.readLine()) != null) { 128 | fullLogs.append("").append(line).append("").append("\n"); 129 | if (!(line.length() > 4096)) bot.editMessage(fullLogs.toString(), update, id); 130 | } 131 | 132 | process.waitFor(); 133 | bot.sendReply2ID(prefs.getString("return_code_shell") 134 | .replace("%1", String.valueOf(process.exitValue())), id, update 135 | ); 136 | shellStatus.unlockStatus(); 137 | } catch (Exception e) { 138 | if (!shellStatus.canRun()) 139 | shellStatus.unlockStatus(); 140 | 141 | bot.sendMessageAsync(prefs.getString("something_went_wrong"), update); 142 | logger.error(e.getMessage()); 143 | } finally { 144 | if (inputStream != null) { 145 | try { 146 | inputStream.close(); 147 | } catch (IOException ioException) { 148 | logger.error(ioException.getMessage(), ioException); 149 | } 150 | } 151 | 152 | if (inputStreamReader != null) { 153 | try { 154 | inputStreamReader.close(); 155 | } catch (IOException ioException) { 156 | logger.error(ioException.getMessage(), ioException); 157 | } 158 | } 159 | 160 | if (bufferedReader != null) { 161 | try { 162 | bufferedReader.close(); 163 | } catch (IOException ioException) { 164 | logger.error(ioException.getMessage(), ioException); 165 | } 166 | } 167 | } 168 | } else { 169 | bot.sendReply(prefs.getString("cant_run_shell"), update); 170 | } 171 | } 172 | } 173 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/gsi/Request.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.gsi; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.db.PrefObj; 6 | import com.vegazsdev.bobobot.utils.Config; 7 | import org.telegram.telegrambots.meta.api.methods.send.SendMessage; 8 | import org.telegram.telegrambots.meta.api.objects.Update; 9 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; 10 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.Objects; 15 | import java.util.concurrent.TimeUnit; 16 | import java.util.regex.Pattern; 17 | 18 | /** 19 | * That class send GSI order to private group, the order is obtained from the public group. 20 | */ 21 | @SuppressWarnings({"SpellCheckingInspection", "unused"}) 22 | public class Request extends Command { 23 | 24 | private String dontHaveUsername; 25 | 26 | public Request() { 27 | super("request"); 28 | } 29 | 30 | @Override 31 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 32 | /* 33 | * Check if the privateChat/publicChat values is ok or nah 34 | */ 35 | if (Config.getDefConfig("privateChat") == null || Objects.equals(Config.getDefConfig("privateChat"), "")) { 36 | bot.sendReply(prefs.getString("issue_with_privatechat"), update); 37 | } else if (!(Config.getDefConfig("requestChat") == null) || !Objects.equals(Config.getDefConfig("requestChat"), "")) { 38 | if (Objects.requireNonNull(Config.getDefConfig("requestChat")).startsWith("-") && Objects.requireNonNull(Config.getDefConfig("privateChat")).startsWith("-")) { 39 | // General base: message/id and some tricks 40 | String chatId = update.getMessage().getChatId().toString(); 41 | String[] msgComparableRaw = update.getMessage().getText().split(" "); 42 | String msgSwitchPrefix = msgComparableRaw[0]; 43 | String msgBaseRaw = update.getMessage().getText(); 44 | 45 | // Request message id 46 | int id = 0; 47 | 48 | // Regex for valid link 49 | String validLink = "^(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; 50 | 51 | // General base: SendMessage() and switch() things 52 | SendMessage message = new SendMessage(); 53 | message.setDisableWebPagePreview(true); 54 | message.enableHtml(true); 55 | message.setChatId(chatId); 56 | 57 | if (!(update.getMessage().getFrom().getId() == Float.parseFloat(String.valueOf(777000)))) { 58 | if (Objects.requireNonNull(Config.getDefConfig("requestChat")).contains(String.valueOf(update.getMessage().getChatId()))) { 59 | if (Pattern.matches(validLink, msgComparableRaw[1])) { 60 | // Delete the message who user sent 61 | bot.deleteMessage(chatId, update.getMessage().getMessageId(), update); 62 | 63 | // Set to thank message 64 | message.setText(prefs.getString("request_done") 65 | .replace("%1", update.getMessage().getFrom().getFirstName()) 66 | .replace("%2", String.valueOf(update.getMessage().getFrom().getId())) 67 | .replace("%3", String.valueOf(update.getMessage().getFrom().getId())) 68 | ); 69 | 70 | message.setChatId(chatId); // Get to stock chat id 71 | id = bot.sendMessageAsyncBase(message, update); 72 | 73 | // Set dontHaveUsername 74 | dontHaveUsername = prefs.getString("dont_have"); 75 | 76 | // workaround to info 77 | StringBuilder str = new StringBuilder(); 78 | String addInfo = ""; 79 | for (int i = 2; i < msgComparableRaw.length; i++) { 80 | str.append(msgComparableRaw[i]).append(" "); 81 | addInfo = String.valueOf(str); 82 | } 83 | if (addInfo.equals("")) addInfo = prefs.getString("info_not_shared"); 84 | 85 | /* 86 | * Prepare InlineKeyboardButton 87 | */ 88 | InlineKeyboardMarkup markupInline = new InlineKeyboardMarkup(); 89 | List> inlineKeyboardButton = new ArrayList<>(); 90 | 91 | List inlineKeyboardButtonArrayList = new ArrayList<>(); 92 | InlineKeyboardButton inlineKeyboardButtonAonly = new InlineKeyboardButton(); 93 | inlineKeyboardButtonAonly.setText("\uD83D\uDCE6 Firmware/ROM Link"); 94 | inlineKeyboardButtonAonly.setUrl(msgComparableRaw[1]); 95 | inlineKeyboardButtonArrayList.add(inlineKeyboardButtonAonly); 96 | inlineKeyboardButton.add(inlineKeyboardButtonArrayList); 97 | 98 | /* 99 | * Finish InlineKeyboardButton setup 100 | */ 101 | markupInline.setKeyboard(inlineKeyboardButton); 102 | message.setReplyMarkup(markupInline); 103 | 104 | // Initial to the message base 105 | message.setChatId(Objects.requireNonNull(Config.getDefConfig("privateChat"))); 106 | message.setText( 107 | prefs.getString("gsi_order") + "\n\n" 108 | + prefs.getString("addinfo") + "\n" 109 | + "" + addInfo + "" 110 | + "\n\n" 111 | + prefs.getString("user_info") + "\n\n" 112 | + prefs.getString("first_and_last_name") 113 | .replace("%1", update.getMessage().getFrom().getFirstName() + validateLastName(update.getMessage().getFrom().getLastName())) + "\n" 114 | + prefs.getString("user_name") 115 | .replace("%1", validateUsername(update.getMessage().getFrom().getUserName())) + "\n" 116 | + prefs.getString("user_id") 117 | .replace("%1", String.valueOf(update.getMessage().getFrom().getId())) 118 | ); 119 | } else { 120 | message.setText(prefs.getString("invalid_link") 121 | .replace("%1", update.getMessage().getFrom().getFirstName()) 122 | .replace("%2", String.valueOf(update.getMessage().getFrom().getId())) 123 | .replace("%3", String.valueOf(update.getMessage().getFrom().getId())) 124 | ); 125 | 126 | // Delete the message who user sent 127 | bot.deleteMessage(chatId, update.getMessage().getMessageId(), update); 128 | } 129 | } else { 130 | message.setText(prefs.getString("cant_be_used")); 131 | } 132 | 133 | /* 134 | * Send the message 135 | */ 136 | bot.sendMessageAsyncBase(message, update); 137 | 138 | /* 139 | * Delete thanks message 140 | */ 141 | try { 142 | TimeUnit.MINUTES.sleep(1); 143 | if (id != 0) bot.deleteMessage(chatId, id, update); 144 | } catch (InterruptedException e) { 145 | e.printStackTrace(); 146 | } 147 | } else { 148 | bot.deleteMessage(chatId, update.getMessage().getMessageId(), update); 149 | } 150 | } else { 151 | bot.sendReply(prefs.getString("issue_with_index_chat"), update); 152 | } 153 | } else { 154 | bot.sendReply(prefs.getString("issue_with_publicchat"), update); 155 | } 156 | } 157 | 158 | // START: Workarounds for first/last name & username 159 | private String validateUsername(String username) { 160 | if (username == null || username.equals("")) { 161 | return dontHaveUsername; 162 | } else { 163 | return "@" + username; 164 | } 165 | } 166 | 167 | private String validateLastName(String lastName) { 168 | if (lastName == null || lastName.equals("")) { 169 | return ""; 170 | } else { 171 | return " " + lastName; 172 | } 173 | } 174 | // END: Workarounds for first/last name & username 175 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/Main.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot; 2 | 3 | import com.google.common.reflect.ClassPath; 4 | import com.vegazsdev.bobobot.commands.owner.Chat2Shell; 5 | import com.vegazsdev.bobobot.core.bot.Bot; 6 | import com.vegazsdev.bobobot.core.bot.BuildInfo; 7 | import com.vegazsdev.bobobot.core.command.Command; 8 | import com.vegazsdev.bobobot.core.command.annotations.DisableCommand; 9 | import com.vegazsdev.bobobot.core.shell.ShellStatus; 10 | import com.vegazsdev.bobobot.db.DbThings; 11 | import com.vegazsdev.bobobot.db.PrefObj; 12 | import com.vegazsdev.bobobot.exception.BotTokenException; 13 | import com.vegazsdev.bobobot.utils.Config; 14 | import com.vegazsdev.bobobot.utils.FileTools; 15 | import com.vegazsdev.bobobot.utils.XMLs; 16 | import org.slf4j.Logger; 17 | import org.slf4j.LoggerFactory; 18 | import org.telegram.telegrambots.meta.TelegramBotsApi; 19 | import org.telegram.telegrambots.updatesreceivers.DefaultBotSession; 20 | 21 | import java.io.IOException; 22 | import java.util.ArrayList; 23 | import java.util.Objects; 24 | 25 | public class Main { 26 | 27 | /** 28 | * Logger: To send warning, info & errors to terminal. 29 | */ 30 | private static final Logger logger = LoggerFactory.getLogger(Main.class); 31 | 32 | /** 33 | * That variable is used to get core strings. 34 | */ 35 | public static String DEF_CORE_STRINGS_XML = "core-strings.xml"; 36 | 37 | /** 38 | * That variable is for shell command. 39 | */ 40 | public static ShellStatus shellStatus; 41 | 42 | @SuppressWarnings({"SpellCheckingInspection", "UnstableApiUsage", "rawtypes"}) 43 | public static void main(String[] args) { 44 | /* 45 | * Start-up of all 46 | */ 47 | logger.info(XMLs.getFromStringsXML(DEF_CORE_STRINGS_XML, "bot_init")); 48 | 49 | /* 50 | * Check if exists props file and other things 51 | */ 52 | if (!FileTools.checkFileExistsCurPath("configs/" + XMLs.getFromStringsXML(DEF_CORE_STRINGS_XML, "config_file"))) { 53 | logger.info(XMLs.getFromStringsXML(DEF_CORE_STRINGS_XML, "config_file_not_found")); 54 | new Config().createDefConfig(); 55 | logger.error(XMLs.getFromStringsXML(DEF_CORE_STRINGS_XML, "config_file_info")); 56 | if (!FileTools.checkFileExistsCurPath("configs/allowed2port.json")) 57 | Chat2Shell.runBash("echo \"[]\" >> configs/allowed2port.json"); 58 | System.exit(0); 59 | } 60 | 61 | /* 62 | * Create ArrayList (Class) to save classes, we'll use it to botsApi.registerBot() 63 | */ 64 | ArrayList commandClasses = new ArrayList<>(); 65 | 66 | /* 67 | * Create ClassLoader to get class name, method and other things 68 | */ 69 | final ClassLoader loader = Thread.currentThread().getContextClassLoader(); 70 | try { 71 | for (final ClassPath.ClassInfo info : ClassPath.from(loader).getTopLevelClasses()) { 72 | if (info.getName().startsWith("com.vegazsdev.bobobot.commands")) { 73 | /* 74 | * Prepare clazz var (To get class (info var of for{}) info) 75 | */ 76 | final Class clazz = info.load(); 77 | 78 | /* 79 | * Check if it is a valid command 80 | */ 81 | if (clazz.getGenericSuperclass().toString().equals(String.valueOf(Command.class))) { 82 | /* 83 | * If valid: Check if it has DisableCommand annotation, if it has, say: failed to initialize 84 | * Else, add the class into commandClasses 85 | */ 86 | if (clazz.isAnnotationPresent(DisableCommand.class)) { 87 | logger.warn(Objects.requireNonNull( 88 | XMLs.getFromStringsXML(DEF_CORE_STRINGS_XML, "cc_failed_to_init")) 89 | .replace("%1", clazz.getSimpleName())); 90 | } else { 91 | /* 92 | * If valid, add the validated class to commandClasses 93 | */ 94 | try { 95 | commandClasses.add(clazz); 96 | logger.info(Objects.requireNonNull( 97 | XMLs.getFromStringsXML(DEF_CORE_STRINGS_XML, "cc_init_cmd")) 98 | .replace("%1", clazz.getSimpleName())); 99 | } catch (Exception e) { 100 | logger.error(e.getMessage()); 101 | } 102 | } 103 | } else { 104 | /* 105 | * If the command does not have a superclass of the command (core) class, give a warning and ignore 106 | */ 107 | logger.warn(Objects.requireNonNull( 108 | XMLs.getFromStringsXML(DEF_CORE_STRINGS_XML, "cc_not_valid_command")) 109 | .replace("%1", clazz.getSimpleName())); 110 | } 111 | } 112 | } 113 | } catch (IOException e) { 114 | logger.error(e.getMessage()); 115 | } 116 | 117 | /* 118 | * Check if the props is ok or no 119 | */ 120 | if (((Config.getDefConfig("bot-token") != null && Objects.requireNonNull(Config.getDefConfig("bot-token")).contains(" ")) 121 | || (Config.getDefConfig("bot-username") != null && Objects.requireNonNull(Config.getDefConfig("bot-username")).contains(" "))) 122 | || Objects.requireNonNull(Config.getDefConfig("bot-master")).contains(" ") || (Objects.requireNonNull(Config.getDefConfig("publicChannel")).contains(" "))) { 123 | logger.error(XMLs.getFromStringsXML(DEF_CORE_STRINGS_XML, "config_file_info")); 124 | System.exit(0); 125 | } 126 | 127 | /* 128 | * Create BuildInfo object, it is used in TelegramBots class to About class, just for info (you can remove it fine) 129 | */ 130 | BuildInfo buildInfo = new BuildInfo(true); 131 | 132 | /* 133 | * Create ShellStatus object, is necesary to avoid multiples instances when using Shell command 134 | */ 135 | shellStatus = new ShellStatus(); 136 | shellStatus.unlockStatus(); 137 | 138 | /* 139 | * Create Bot object 140 | */ 141 | Bot bot = null; 142 | try { 143 | bot = new Bot( 144 | Objects.requireNonNull(Config.getDefConfig("bot-token")), 145 | Config.getDefConfig("bot-username"), 146 | buildInfo.getVersion()); 147 | } catch (BotTokenException e) { 148 | logger.error(e.getMessage()); 149 | System.exit(1); 150 | } 151 | 152 | /* 153 | * Create database if it doesn't exist 154 | */ 155 | if (!FileTools.checkFileExistsCurPath("databases/prefs.db")) { 156 | DbThings.createNewDatabase("prefs.db"); 157 | DbThings.createTable("prefs.db", 158 | "CREATE TABLE IF NOT EXISTS chat_prefs (" 159 | + "group_id real UNIQUE PRIMARY KEY," 160 | + "hotkey text DEFAULT '/'," 161 | + "lang text DEFAULT 'strings-en.xml'" 162 | + ");" 163 | ); 164 | } 165 | 166 | /* 167 | * Create some checks 168 | * Check if the private/public chats has own its prefs in database 169 | */ 170 | if ((Config.getDefConfig("privateChat") == null || Objects.equals(Config.getDefConfig("privateChat"), "")) || (Config.getDefConfig("requestChat") == null) || !Objects.requireNonNull(Config.getDefConfig("requestChat")).startsWith("-") && !Objects.requireNonNull(Config.getDefConfig("privateChat")).startsWith("-")) { 171 | logger.info(XMLs.getFromStringsXML("strings-en.xml", "issue_with_index_chat")); 172 | } else { 173 | /* 174 | * PrefObj, chatPrefs 175 | */ 176 | PrefObj chatPrefs = TelegramBot.getPrefs(Double.parseDouble(Objects.requireNonNull(Config.getDefConfig("privateChat")))); 177 | 178 | /* 179 | * Check if the database exists for private chat 180 | */ 181 | if (chatPrefs == null) { 182 | logger.info("There is no database for: " + Config.getDefConfig("privateChat") + ", creating one..."); 183 | new PrefObj(0, "strings-en.xml", "/"); 184 | } 185 | 186 | /* 187 | * Support multiple request chats 188 | */ 189 | if (Objects.requireNonNull(Config.getDefConfig("requestChat")).contains(",")) { 190 | String[] requestChats = Objects.requireNonNull(Config.getDefConfig("requestChat")).split(","); 191 | for (String requestChat : requestChats) { 192 | /* 193 | * PrefObj, chatPrefs 194 | */ 195 | chatPrefs = TelegramBot.getPrefs(Double.parseDouble(requestChat)); 196 | if (chatPrefs == null) { 197 | logger.info("There is no database for: " + requestChat + ", creating one..."); 198 | new PrefObj(0, "strings-en.xml", "/"); 199 | } 200 | } 201 | } else { 202 | chatPrefs = TelegramBot.getPrefs(Double.parseDouble(Objects.requireNonNull(Config.getDefConfig("requestChat")))); 203 | 204 | /* 205 | * Check if the database exists for request chat 206 | */ 207 | if (chatPrefs == null) { 208 | logger.info("There is no database for: " + Config.getDefConfig("requestChat") + ", creating one..."); 209 | new PrefObj(0, "strings-en.xml", "/"); 210 | } 211 | } 212 | } 213 | 214 | /* 215 | * Time to run bot 216 | */ 217 | try { 218 | TelegramBotsApi botsApi = new TelegramBotsApi(DefaultBotSession.class); 219 | botsApi.registerBot(new TelegramBot(bot, commandClasses)); 220 | logger.info(XMLs.getFromStringsXML(DEF_CORE_STRINGS_XML, "bot_started")); 221 | } catch (Exception e) { 222 | logger.error(e.toString()); 223 | } 224 | } 225 | } -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/TelegramBot.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot; 2 | 3 | import com.vegazsdev.bobobot.core.bot.Bot; 4 | import com.vegazsdev.bobobot.core.command.CommandWithClass; 5 | import com.vegazsdev.bobobot.db.DbThings; 6 | import com.vegazsdev.bobobot.db.PrefObj; 7 | import com.vegazsdev.bobobot.utils.FileTools; 8 | import com.vegazsdev.bobobot.utils.XMLs; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.telegram.telegrambots.bots.TelegramLongPollingBot; 12 | import org.telegram.telegrambots.meta.api.methods.groupadministration.GetChatMember; 13 | import org.telegram.telegrambots.meta.api.methods.groupadministration.LeaveChat; 14 | import org.telegram.telegrambots.meta.api.methods.send.SendMessage; 15 | import org.telegram.telegrambots.meta.api.methods.updatingmessages.DeleteMessage; 16 | import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageText; 17 | import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMember; 18 | import org.telegram.telegrambots.meta.api.objects.Update; 19 | import org.telegram.telegrambots.meta.exceptions.TelegramApiException; 20 | 21 | import java.lang.reflect.Method; 22 | import java.util.ArrayList; 23 | import java.util.Objects; 24 | import java.util.concurrent.ExecutionException; 25 | 26 | @SuppressWarnings("rawtypes") 27 | public class TelegramBot extends TelegramLongPollingBot { 28 | 29 | private static final Logger logger = LoggerFactory.getLogger(TelegramBot.class); 30 | 31 | private final Bot bot; 32 | private PrefObj chatPrefs; 33 | private ArrayList commandClasses; 34 | 35 | TelegramBot(Bot bot, ArrayList commandClasses) { 36 | this.bot = bot; 37 | this.commandClasses = commandClasses; 38 | } 39 | 40 | public TelegramBot(Bot bot) { 41 | this.bot = bot; 42 | } 43 | 44 | public static PrefObj getPrefs(double chatId) { 45 | PrefObj prefObj = DbThings.selectIntoPrefsTable(chatId); 46 | if (prefObj == null) { 47 | DbThings.insertIntoPrefsTable(chatId); 48 | } 49 | return prefObj; 50 | } 51 | 52 | @Override 53 | public void onUpdateReceived(Update update) { 54 | /* 55 | * Avoid hotkey problem 56 | */ 57 | if (!FileTools.checkFileExistsCurPath("databases/prefs.db")) { 58 | DbThings.createNewDatabase("prefs.db"); 59 | DbThings.createTable("prefs.db", 60 | "CREATE TABLE IF NOT EXISTS chat_prefs (" 61 | + "group_id real UNIQUE PRIMARY KEY," 62 | + "hotkey text DEFAULT '/'," 63 | + "lang text DEFAULT 'strings-en.xml'" 64 | + ");" 65 | ); 66 | } 67 | 68 | if (update.getMessage() != null) { 69 | /* 70 | * PrefObj, chatPrefs 71 | */ 72 | chatPrefs = getPrefs(Double.parseDouble(Objects.requireNonNull(update.getMessage().getChatId().toString()))); 73 | 74 | /* 75 | * Check if exists that chat in our db 76 | */ 77 | if (chatPrefs == null) { 78 | try { 79 | chatPrefs = new PrefObj(0, "strings-en.xml", "/"); 80 | } catch (Exception exception) { 81 | logger.error(exception.getMessage()); 82 | } 83 | } 84 | 85 | /* 86 | * Create thread to run commands (it can run without thread) 87 | */ 88 | new Thread(new Runnable() { 89 | private TelegramBot tBot; 90 | 91 | /* 92 | * Create TelegramBot object using init() 93 | */ 94 | Runnable init(TelegramBot tBot) { 95 | this.tBot = tBot; 96 | return this; 97 | } 98 | 99 | /* 100 | * Check conditional, command & other things 101 | */ 102 | @Override 103 | public void run() { 104 | if (update.hasMessage() && update.getMessage().getText() != null 105 | && !update.getMessage().getText().equals("") 106 | && Objects.requireNonNull(XMLs.getFromStringsXML(Main.DEF_CORE_STRINGS_XML, "possible_hotkeys")) 107 | .indexOf(update.getMessage().getText().charAt(0)) >= 0) { 108 | 109 | String msg = update.getMessage().getText(); 110 | long usrId = update.getMessage().getFrom().getId(); 111 | 112 | /* 113 | * It is ok to run and send command 114 | */ 115 | if (chatPrefs.getHotkey() != null && msg.startsWith(Objects.requireNonNull(chatPrefs.getHotkey()))) { 116 | for (CommandWithClass commandWithClass : getActiveCommandsAsCmdObject()) { 117 | String adjustCommand = msg.replace(Objects.requireNonNull(chatPrefs.getHotkey()), ""); 118 | 119 | if (adjustCommand.contains(" ")) { 120 | adjustCommand = adjustCommand.split(" ")[0]; 121 | } 122 | 123 | if (commandWithClass.getAlias().equals(adjustCommand)) { 124 | try { 125 | logger.info(Objects.requireNonNull(XMLs.getFromStringsXML(Main.DEF_CORE_STRINGS_XML, "command_ok")) 126 | .replace("%1", update.getMessage().getFrom().getFirstName() + " (" + usrId + ")") 127 | .replace("%2", adjustCommand)); 128 | runMethod(commandWithClass.getClazz(), update, tBot, chatPrefs); 129 | } catch (Exception e) { 130 | logger.error(Objects.requireNonNull(XMLs.getFromStringsXML(Main.DEF_CORE_STRINGS_XML, "command_failure")) 131 | .replace("%1", commandWithClass.getAlias()) 132 | .replace("%2", e.getMessage()), e); 133 | } 134 | } 135 | } 136 | } 137 | } 138 | } 139 | }.init(this)).start(); 140 | } 141 | } 142 | 143 | public void sendMessageAsync(String msg, Update update) { 144 | /* 145 | * Prepare SendMessage base 146 | */ 147 | SendMessage sendMessage = new SendMessage(); 148 | sendMessage.setText(msg); 149 | sendMessage.setChatId(String.valueOf(update.getMessage().getChatId())); 150 | sendMessage.enableMarkdown(true); 151 | sendMessage.disableWebPagePreview(); 152 | 153 | /* 154 | * Execute executeAsync() method 155 | */ 156 | try { 157 | executeAsync(sendMessage).get().getMessageId(); 158 | } catch (TelegramApiException | ExecutionException | InterruptedException exception) { 159 | logger.error(exception.getMessage() + " (CID: " + update.getMessage().getChat().getId() + " | UID: " + update.getMessage().getFrom().getId() + ")"); 160 | } 161 | } 162 | 163 | public int sendMessageAsyncBase(SendMessage sendMessage, Update update) { 164 | /* 165 | * Execute executeAsync() method & use existent SendMessage object 166 | */ 167 | try { 168 | return executeAsync(sendMessage).get().getMessageId(); 169 | } catch (TelegramApiException | ExecutionException | InterruptedException exception) { 170 | logger.error(exception.getMessage() + " (CID: " + update.getMessage().getChat().getId() + " | UID: " + update.getMessage().getFrom().getId() + ")"); 171 | } 172 | return 0; 173 | } 174 | 175 | public void deleteMessage(String chatID, Integer messageID, Update update) { 176 | /* 177 | * Prepare DeleteMessage base 178 | */ 179 | DeleteMessage deleteMessage = new DeleteMessage(); 180 | deleteMessage.setMessageId(messageID); 181 | deleteMessage.setChatId(chatID); 182 | 183 | /* 184 | * Execute executeAsync() method 185 | */ 186 | try { 187 | executeAsync(deleteMessage); 188 | } catch (TelegramApiException telegramApiException) { 189 | logger.error(telegramApiException.getMessage() + " (CID: " + update.getMessage().getChat().getId() + " | UID: " + update.getMessage().getFrom().getId() + ")"); 190 | } 191 | } 192 | 193 | public int sendReply(String msg, Update update) { 194 | /* 195 | * Prepare SendMessage base 196 | */ 197 | SendMessage sendMessage = new SendMessage(); 198 | sendMessage.setText(msg); 199 | sendMessage.setChatId(String.valueOf(update.getMessage().getChatId())); 200 | sendMessage.enableHtml(true); 201 | sendMessage.setReplyToMessageId(update.getMessage().getMessageId()); 202 | sendMessage.disableWebPagePreview(); 203 | 204 | /* 205 | * Execute executeAsync() method 206 | */ 207 | try { 208 | return executeAsync(sendMessage).get().getMessageId(); 209 | } catch (TelegramApiException | ExecutionException | InterruptedException exception) { 210 | logger.error(exception.getMessage() + " (CID: " + update.getMessage().getChat().getId() + " | UID: " + update.getMessage().getFrom().getId() + ")"); 211 | } 212 | return 0; 213 | } 214 | 215 | public void sendReply2ID(String msg, int id, Update update) { 216 | /* 217 | * Prepare SendMessage base 218 | */ 219 | SendMessage sendMessage = new SendMessage(); 220 | sendMessage.setText(msg); 221 | sendMessage.setChatId(String.valueOf(update.getMessage().getChatId())); 222 | sendMessage.enableHtml(true); 223 | sendMessage.setReplyToMessageId(id); 224 | sendMessage.disableWebPagePreview(); 225 | 226 | /* 227 | * Execute executeAsync() method 228 | */ 229 | try { 230 | executeAsync(sendMessage).get().getMessageId(); 231 | } catch (TelegramApiException | ExecutionException | InterruptedException exception) { 232 | logger.error(exception.getMessage() + " (CID: " + update.getMessage().getChat().getId() + " | UID: " + update.getMessage().getFrom().getId() + ")"); 233 | } 234 | } 235 | 236 | public void editMessage(String msg, Update update, int id) { 237 | /* 238 | * Prepare EditMessageText base 239 | */ 240 | EditMessageText editMessageText = new EditMessageText(); 241 | editMessageText.setText(msg); 242 | editMessageText.setChatId(String.valueOf(update.getMessage().getChatId())); 243 | editMessageText.setMessageId(id); 244 | editMessageText.enableHtml(true); 245 | 246 | /* 247 | * Execute executeAsync() method 248 | */ 249 | try { 250 | executeAsync(editMessageText); 251 | } catch (TelegramApiException telegramApiException) { 252 | logger.error(telegramApiException.getMessage() + " (CID: " + update.getMessage().getChat().getId() + " | UID: " + update.getMessage().getFrom().getId() + ")"); 253 | } 254 | } 255 | 256 | public boolean isPM(String userID, String chatID) { 257 | return !chatID.equals(userID); 258 | } 259 | 260 | public boolean isAdmin(String userID, String chatID) { 261 | if (userID.equals(chatID)) { 262 | /* 263 | * https://github.com/TrebleExperience/Bot3/commit/0f31e973edecce5ea25a92a6b3b841aaae1b333c 264 | */ 265 | return false; 266 | } else { 267 | try { 268 | /* 269 | * Create GetChatMember() object to get info of the user 270 | */ 271 | GetChatMember getChatMember = new GetChatMember(); 272 | getChatMember.setChatId(chatID); 273 | getChatMember.setUserId(Long.valueOf(userID)); 274 | 275 | /* 276 | * Execute GetChatMember() (to get info) using ChatMember().execute() 277 | */ 278 | ChatMember chatMember = execute(getChatMember); 279 | 280 | /* 281 | * If executed fine, we'll be able to check status 282 | */ 283 | return switch (chatMember.getStatus()) { 284 | case "administrator", "creator" -> true; 285 | default -> false; 286 | }; 287 | } catch (Exception exception) { 288 | logger.error(exception.getMessage() + " (CID: " + chatID + " | UID: " + userID + ")"); 289 | return false; 290 | } 291 | } 292 | } 293 | 294 | public boolean leaveChat(String chatID) { 295 | /* 296 | * Prepare LeaveChat base 297 | */ 298 | LeaveChat leaveChat = new LeaveChat(); 299 | leaveChat.setChatId(chatID); 300 | 301 | /* 302 | * Execute executeAsync() method 303 | */ 304 | try { 305 | return executeAsync(leaveChat).thenApply(response -> /* Just a workaround */ response.toString().equals("true")).get(); 306 | } catch (TelegramApiException | ExecutionException | InterruptedException telegramApiException) { 307 | logger.error(telegramApiException.getMessage() + " (CID to leave: " + chatID + ")"); 308 | return false; 309 | } 310 | } 311 | 312 | private void runMethod(Class aClass, Update update, TelegramBot tBot, PrefObj prefs) { 313 | try { 314 | Object instance = ((Class) aClass).getDeclaredConstructor().newInstance(); 315 | Method method = ((Class) aClass).getDeclaredMethod("botReply", Update.class, TelegramBot.class, PrefObj.class); 316 | method.invoke(instance, update, tBot, prefs); 317 | } catch (Exception e) { 318 | logger.error(e.getMessage()); 319 | } 320 | } 321 | 322 | public ArrayList getActiveCommandsAsCmdObject() { 323 | ArrayList allCommandsArObj = new ArrayList<>(); 324 | for (Class clazz : commandClasses) { 325 | try { 326 | Object instance = ((Class) clazz).getDeclaredConstructor().newInstance(); 327 | Method methodAli = ((Class) clazz).getSuperclass().getDeclaredMethod("getAlias"); 328 | String alias = (String) methodAli.invoke(instance); 329 | CommandWithClass c = new CommandWithClass(clazz, alias); 330 | allCommandsArObj.add(c); 331 | } catch (Exception e) { 332 | logger.error(e.getMessage()); 333 | } 334 | } 335 | return allCommandsArObj; 336 | } 337 | 338 | @Override 339 | public String getBotUsername() { 340 | return bot.getUsername(); 341 | } 342 | 343 | @Override 344 | public String getBotToken() { 345 | return bot.getToken(); 346 | } 347 | 348 | public String getVersionID() { 349 | return bot.getVersionID(); 350 | } 351 | } 352 | -------------------------------------------------------------------------------- /src/main/java/com/vegazsdev/bobobot/commands/gsi/ErfanGSIs.java: -------------------------------------------------------------------------------- 1 | package com.vegazsdev.bobobot.commands.gsi; 2 | 3 | import com.vegazsdev.bobobot.TelegramBot; 4 | import com.vegazsdev.bobobot.core.command.Command; 5 | import com.vegazsdev.bobobot.core.gsi.GSICmdObj; 6 | import com.vegazsdev.bobobot.core.gsi.SourceForgeUpload; 7 | import com.vegazsdev.bobobot.db.PrefObj; 8 | import com.vegazsdev.bobobot.utils.Config; 9 | import com.vegazsdev.bobobot.utils.FileTools; 10 | import com.vegazsdev.bobobot.utils.JSONs; 11 | import okio.BufferedSource; 12 | import okio.Okio; 13 | import okio.Source; 14 | import org.apache.commons.io.FileUtils; 15 | import org.apache.commons.io.FilenameUtils; 16 | import org.apache.commons.lang3.ArrayUtils; 17 | import org.slf4j.Logger; 18 | import org.slf4j.LoggerFactory; 19 | import org.telegram.telegrambots.meta.api.methods.send.SendMessage; 20 | import org.telegram.telegrambots.meta.api.objects.Update; 21 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; 22 | import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; 23 | 24 | import java.io.*; 25 | import java.nio.file.Files; 26 | import java.nio.file.Path; 27 | import java.nio.file.Paths; 28 | import java.util.ArrayList; 29 | import java.util.Arrays; 30 | import java.util.List; 31 | import java.util.Objects; 32 | import java.util.concurrent.atomic.AtomicReference; 33 | import java.util.stream.Stream; 34 | 35 | /** 36 | * Main command of the bot specialized in making GSI (Erfan tool). 37 | *

38 | * This class consists of doing GSI using the Erfan Abdi tool, named ErfanGSIs. 39 | *

40 | * Some methods: 41 | *

    42 | *
  • {@link #isCommandValid(Update)}
  • 43 | *
  • {@link #try2AvoidCodeInjection(String)}
  • 44 | *
  • {@link #isGSIValid(String)}
  • 45 | *
  • {@link #createGSI(GSICmdObj, TelegramBot)}
  • 46 | *
  • {@link #userHasPortPermissions(String)}
  • 47 | *
  • {@link #getModelOfOutput(String)}
  • 48 | *
  • {@link #addPortPerm(String)}
  • 49 | * 50 | *
51 | */ 52 | @SuppressWarnings({"SpellCheckingInspection", "unused"}) 53 | public class ErfanGSIs extends Command { 54 | 55 | /** 56 | * Logger: To send warning, info & errors to terminal. 57 | */ 58 | private static final Logger logger = LoggerFactory.getLogger(ErfanGSIs.class); 59 | 60 | /** 61 | * Main variables to GSI process. 62 | */ 63 | private static final ArrayList queue = new ArrayList<>(); 64 | private static boolean isPorting = false; 65 | private final String toolPath = "ErfanGSIs/"; 66 | 67 | /** 68 | * Get supported versions from ErfanGSIs tool. 69 | */ 70 | private final File[] supportedGSIs10 = new File(toolPath + "roms/10").listFiles(File::isDirectory); 71 | private final File[] supportedGSIs11 = new File(toolPath + "roms/11").listFiles(File::isDirectory); 72 | private final File[] supportedGSIs12 = new File(toolPath + "roms/12").listFiles(File::isDirectory); 73 | 74 | /** 75 | * Some workarounds. 76 | */ 77 | private String messageError = ""; 78 | private String infoGSI = ""; 79 | private String noticeGSI = ""; 80 | private String developerNoticeGSI = ""; 81 | 82 | /** 83 | * Create dummy PrefObj 84 | */ 85 | private PrefObj prefObj; 86 | 87 | public ErfanGSIs() { 88 | super("url2gsi"); 89 | } 90 | 91 | private static String[] listFilesForFolder(final File folder) { 92 | StringBuilder paths = new StringBuilder(); 93 | for (final File fileEntry : Objects.requireNonNull(folder.listFiles())) { 94 | if (fileEntry.isDirectory()) { 95 | listFilesForFolder(fileEntry); 96 | } else { 97 | if (fileEntry.getName().contains(".img")) { 98 | paths.append(fileEntry.getAbsolutePath()).append("\n"); 99 | } 100 | } 101 | } 102 | return paths.toString().split("\n"); 103 | } 104 | 105 | @Override 106 | public void botReply(Update update, TelegramBot bot, PrefObj prefs) { 107 | String[] msgComparableRaw = update.getMessage().getText().split(" "); 108 | if (update.getMessage().getText().contains(" ")) { 109 | switch (msgComparableRaw[1]) { 110 | case "allowuser" -> { 111 | if (update.getMessage().getReplyToMessage() != null) { 112 | String userid = update.getMessage().getReplyToMessage().getFrom().getId().toString(); 113 | if (addPortPerm(userid)) { 114 | bot.sendReply(prefs.getString("egsi_allowed").replace("%1", userid), update); 115 | } 116 | } else { 117 | bot.sendReply(prefs.getString("egsi_allow_by_reply").replace("%1", prefs.getHotkey()) 118 | .replace("%2", this.getAlias()), update); 119 | } 120 | } 121 | case "queue" -> { 122 | if (!queue.isEmpty()) { 123 | StringBuilder v = new StringBuilder(); 124 | for (int i = 0; i < queue.size(); i++) { 125 | v.append("#").append(i + 1).append(": ").append(queue.get(i).getGsi()).append("\n"); 126 | } 127 | bot.sendReply(prefs.getString("egsi_current_queue") 128 | .replace("%2", v.toString()) 129 | .replace("%1", String.valueOf(queue.size())), update); 130 | } else { 131 | bot.sendReply(prefs.getString("egsi_no_ports_queue"), update); 132 | } 133 | } 134 | case "cancel" -> { 135 | if (isPorting) { 136 | ProcessBuilder pb; 137 | pb = new ProcessBuilder("/bin/bash", "-c", "kill -TERM -- -$(ps ax | grep url2GSI.sh | grep -v grep | awk '{print $1;}')"); 138 | try { 139 | pb.start(); 140 | } catch (IOException ignored) {} 141 | 142 | if (FileTools.checkIfFolderExists(toolPath + "output")) { 143 | if (FileTools.deleteFolder(toolPath + "output")) { 144 | logger.info("Output folder deleted"); 145 | } 146 | } 147 | } else { 148 | bot.sendReply(prefs.getString("egsi_no_ports_queue"), update); 149 | } 150 | } 151 | case "list", "roms", "gsis" -> sendSupportedROMs(update, bot, prefs); 152 | default -> { 153 | messageError = prefs.getString("egsi_fail_to_build_gsi"); 154 | prefObj = prefs; 155 | if (userHasPortPermissions(update.getMessage().getFrom().getId().toString())) { 156 | if (!FileTools.checkIfFolderExists("ErfanGSIs")) { 157 | bot.sendReply(prefs.getString("egsi_dont_exists_tool_folder"), update); 158 | } else { 159 | GSICmdObj gsiCommand = isCommandValid(update); 160 | if (gsiCommand != null) { 161 | boolean isGSITypeValid = isGSIValid(gsiCommand.getGsi()); 162 | if (isGSITypeValid) { 163 | if (!isPorting) { 164 | isPorting = true; 165 | createGSI(gsiCommand, bot); 166 | while (queue.size() != 0) { 167 | GSICmdObj portNow = queue.get(0); 168 | queue.remove(0); 169 | createGSI(portNow, bot); 170 | } 171 | isPorting = false; 172 | } else { 173 | queue.add(gsiCommand); 174 | bot.sendReply(prefs.getString("egsi_added_to_queue"), update); 175 | } 176 | } else { 177 | sendSupportedROMs(update, bot, prefs); 178 | } 179 | } 180 | } 181 | } 182 | } 183 | } 184 | } else { 185 | bot.sendReply(prefs.getString("bad_usage"), update); 186 | } 187 | } 188 | 189 | /** 190 | * Avoid shell usage on jurl2gsi command. 191 | */ 192 | private String try2AvoidCodeInjection(String parameters) { 193 | try { 194 | parameters = parameters.replace("&", "") 195 | .replace("\\", "").replace(";", "").replace("<", "") 196 | .replace(">", "").replace("|", ""); 197 | } catch (Exception e) { 198 | return parameters; 199 | } 200 | return parameters; 201 | } 202 | 203 | /** 204 | * Check if the args passed to jurl2gsi command is valid. 205 | */ 206 | private GSICmdObj isCommandValid(Update update) { 207 | GSICmdObj gsiCmdObj = new GSICmdObj(); 208 | String msg = update.getMessage().getText().replace(Config.getDefConfig("bot-hotkey") + this.getAlias() + " ", ""); 209 | String[] msgComparableRaw = update.getMessage().getText().split(" "), paramComparableRaw; 210 | boolean canContinueLoop = false; 211 | String url, gsi, param; 212 | 213 | if (msgComparableRaw.length >= 3) { 214 | try { 215 | url = msg.split(" ")[1]; 216 | gsiCmdObj.setUrl(url); 217 | gsi = msg.split(" ")[2]; 218 | gsiCmdObj.setGsi(gsi); 219 | param = msg.replace(msgComparableRaw[0], "").replace(msgComparableRaw[1], "").replace(msgComparableRaw[2], "").trim(); 220 | param = try2AvoidCodeInjection(param); 221 | paramComparableRaw = param.split(" "); 222 | 223 | if (param.contains("-nv")) { 224 | noticeGSI = "GSI Notice\nThis GSI requires the vendor to have the same version of the system, check this.\n\n"; 225 | } else { 226 | noticeGSI = "GSI Notice\nNo information for this GSI was reported. Read the Developer Notice and check if there is any additional information directly from the builder.\n\n"; 227 | } 228 | 229 | StringBuilder stringBuilder = new StringBuilder(); 230 | for (String string : paramComparableRaw) { 231 | if (string.startsWith("-")) canContinueLoop = true; 232 | if (!string.startsWith("-")) break; 233 | if (canContinueLoop) stringBuilder.append(string).append(" "); 234 | } 235 | 236 | developerNoticeGSI = param.replace(String.valueOf(stringBuilder), ""); 237 | if (developerNoticeGSI.contains(param)) developerNoticeGSI = ""; 238 | if (!developerNoticeGSI.equals("")) { 239 | developerNoticeGSI = 240 | "Developer Notice\n" 241 | + param.replace(String.valueOf(stringBuilder), "") 242 | + "\n\n"; 243 | } else { 244 | developerNoticeGSI = 245 | "Developer Notice\n" 246 | + "No additional information was reported by the builder, if you think this is a mistake, report it directly to the builder." 247 | + "\n\n"; 248 | } 249 | 250 | param = String.valueOf(stringBuilder); 251 | 252 | gsiCmdObj.setParam(param); 253 | gsiCmdObj.setUpdate(update); 254 | return gsiCmdObj; 255 | } catch (Exception e) { 256 | logger.error(e.getMessage()); 257 | return null; 258 | } 259 | } else { 260 | return null; 261 | } 262 | } 263 | 264 | /** 265 | * Check if the GSI is valid. 266 | * It checks if the tool is updated (if it has R/S support), check if the ROM exists too. 267 | */ 268 | // FIX-ME 269 | private boolean isGSIValid(String gsi) { 270 | return true; 271 | } 272 | 273 | /** 274 | * Avoid users abuse, only users with port permission can use jurl2gsi command. 275 | */ 276 | private boolean userHasPortPermissions(String idAsString) { 277 | if (Objects.equals(Config.getDefConfig("bot-master"), idAsString)) { 278 | return true; 279 | } 280 | String portConfigFile = "configs/allowed2port.json"; 281 | return Arrays.asList(Objects.requireNonNull(JSONs.getArrayFromJSON(portConfigFile)).toArray()).contains(idAsString); 282 | } 283 | 284 | /** 285 | * Get model/codename of the device. 286 | */ 287 | public String getModelOfOutput(String folder) { 288 | /* 289 | * Initialize core variables 290 | */ 291 | File outputFolder = new File(folder); 292 | File file = null; 293 | String modelName = null; 294 | String buildType = null; 295 | String brand = null; 296 | 297 | /* 298 | * List the files 299 | */ 300 | for (final File fileEntry : Objects.requireNonNull(outputFolder.listFiles())) { 301 | if (fileEntry.getName().endsWith(".txt") && !fileEntry.getName().contains("System-Tree")) { 302 | file = new File(String.valueOf(fileEntry)); 303 | } 304 | } 305 | 306 | /* 307 | * Try to get codename 308 | */ 309 | try (Source fileSource = Okio.source(Objects.requireNonNull(file)); 310 | BufferedSource bufferedSource = Okio.buffer(fileSource)) { 311 | 312 | /* 313 | * Get codename 314 | */ 315 | while (true) { 316 | String line = bufferedSource.readUtf8Line(); 317 | if (line == null) break; 318 | if (line.startsWith("Brand")) brand = line.substring(7); 319 | if (line.startsWith("Model")) modelName = line.substring(7); 320 | if (line.startsWith("Build Type")) buildType = line.substring(12); 321 | } 322 | 323 | /* 324 | * Check if the model have special codename 325 | */ 326 | if (Objects.requireNonNull(modelName).length() < 1) 327 | modelName = "Generic"; 328 | else if (modelName.toLowerCase().contains("x00qd")) 329 | modelName = "Asus Zenfone 5"; 330 | else if (modelName.toLowerCase().contains("qssi")) 331 | modelName = "Qualcomm Single System Image"; 332 | else if (modelName.toLowerCase().contains("miatoll")) 333 | modelName = "Redmi Note 9S/Redmi Note 9 Pro/Redmi Note 9 Pro Max/POCO M2 Pro"; 334 | else if (modelName.toLowerCase().contains("surya")) 335 | modelName = "Poco X3"; 336 | else if (modelName.toLowerCase().contains("lavender")) 337 | modelName = "Redmi Note 7"; 338 | else if (modelName.toLowerCase().contains("ginkgo")) 339 | modelName = "Redmi Note 8"; 340 | else if (modelName.toLowerCase().contains("raphael")) 341 | modelName = "Mi 9T Pro"; 342 | else if (modelName.toLowerCase().contains("mainline")) 343 | modelName = "AOSP/Pixel (Mainline) Device"; 344 | else if (modelName.toLowerCase().contains("sm6250")) 345 | modelName = "Atoll device"; 346 | else if (modelName.toLowerCase().contains("msi")) 347 | modelName = "Motorola System Image"; 348 | else if (modelName.toLowerCase().contains("mssi")) 349 | modelName = "MIUI Single System Image"; 350 | else if (modelName.equals("a30")) 351 | modelName = "Samsung Galaxy A30"; 352 | else if (modelName.equals("a20")) 353 | modelName = "Samsung Galaxy A20"; 354 | else if (modelName.equals("a10")) 355 | modelName = "Samsung Galaxy A10"; 356 | else if (modelName.equals("LE2123")) 357 | modelName = "OnePlus 9 Pro"; 358 | else if (modelName.toLowerCase().contains("apollo")) 359 | modelName = "Mi 10T/Mi 10T Pro/Redmi K30S"; 360 | else if (modelName.toLowerCase().contains("gauguin")) 361 | modelName = "Mi 10T Lite/Mi 10i 5G/Redmi Note 9 5G"; 362 | else if (modelName.equals(" ")) 363 | modelName = "Generic"; 364 | 365 | if (Objects.requireNonNull(brand).equals("google") || Objects.requireNonNull(brand).equals("Android")) { 366 | if (modelName.equals("AOSP/Pixel (Mainline) Device")) { 367 | switch (Objects.requireNonNull(buildType)) { 368 | // only Pixel which have QP, RP & SP (Q, R & S) 369 | case "raven-user", "aosp_raven-user", "aosp_raven-userdebug", "aosp_raven-eng" 370 | -> modelName = "Google Pixel 6 Pro"; 371 | case "oriel-user", "aosp_oriel-user", "aosp_oriel-userdebug", "aosp_oriel-eng" 372 | -> modelName = "Google Pixel 6"; 373 | case "barbet-user", "aosp_barbet-user", "aosp_barbet-userdebug", "aosp_barbet-eng" 374 | -> modelName = "Google Pixel 5a"; 375 | case "redfin-user", "aosp_redfin-user", "aosp_redfin-userdebug", "aosp_redfin-eng" 376 | -> modelName = "Google Pixel 5"; 377 | case "bramble-user", "aosp_bramble-user", "aosp_bramble-userdebug", "aosp_bramble-eng" 378 | -> modelName = "Google Pixel 4a 5G"; 379 | case "sunfish-user", "aosp_sunfish-user", "aosp_sunfish-userdebug", "aosp_sunfish-eng" 380 | -> modelName = "Google Pixel 4a"; 381 | case "coral-user", "aosp_coral-user", "aosp_coral-userdebug", "aosp_coral-eng" 382 | -> modelName = "Google Pixel 4 XL"; 383 | case "flame-user", "aosp_flame-user", "aosp_flame-userdebug", "aosp_flame-eng" 384 | -> modelName = "Google Pixel 4"; 385 | case "bonito-user", "aosp_bonito-user", "aosp_bonito-userdebug", "aosp_bonito-eng" 386 | -> modelName = "Google Pixel 3a XL"; 387 | case "sargo-user", "aosp_sargo-user", "aosp_sargo-userdebug", "aosp_sargo-eng" 388 | -> modelName = "Google Pixel 3a"; 389 | case "crosshatch-user", "aosp_crosshatch-user", "aosp_crosshatch-userdebug", "aosp_crosshatch-eng" 390 | -> modelName = "Google Pixel 3 XL"; 391 | case "blueline-user", "aosp_blueline-user", "aosp_blueline-userdebug", "aosp_blueline-eng" 392 | -> modelName = "Google Pixel 3"; 393 | case "taimen-user", "aosp_taimen-user", "aosp_taimen-userdebug", "aosp_taimen-eng" 394 | -> modelName = "Google Pixel 2 XL"; 395 | case "walleye-user", "aosp_walleye-user", "aosp_walleye-userdebug", "aosp_walleye-eng" 396 | -> modelName = "Google Pixel 2"; 397 | case "marlin-user", "aosp_marlin-user", "aosp_marlin-userdebug", "aosp_marlin-eng" 398 | -> modelName = "Google Pixel XL"; 399 | case "sailfish-user", "aosp_sailfish-user", "aosp_sailfish-userdebug", "aosp_sailfish-eng" 400 | -> modelName = "Google Pixel"; 401 | default 402 | -> modelName = "Google Pixel (?)"; 403 | } 404 | } 405 | } else if (Objects.requireNonNull(brand).equals("Redmi")) { 406 | if (modelName.equals("Atoll device")) { 407 | modelName = "Redmi Note 9S/Redmi Note 9 Pro/Redmi Note 9 Pro Max/POCO M2 Pro"; 408 | } 409 | } 410 | 411 | /* 412 | * First check 413 | */ 414 | String stringToCheck = modelName.toLowerCase(); 415 | boolean testPass = false; 416 | 417 | char[] characterSearch = { 418 | 'q', 'w', 'e', 'r', 't', 'y', 'u', 419 | 'i', 'o', 'p', 'a', 's', 'd', 'f', 420 | 'g', 'h', 'j', 'k', 'l', 'z', 'x', 421 | 'c', 'v', 'b', 'n', 'm' 422 | }; 423 | 424 | for (int i = 0; i < stringToCheck.length(); i++) { 425 | char character = stringToCheck.charAt(i); 426 | for (char search : characterSearch) { 427 | if (search == character) { 428 | testPass = true; 429 | break; 430 | } 431 | } 432 | } 433 | 434 | if (!testPass) return "Generic"; 435 | return modelName; 436 | } catch (IOException e) { 437 | return "Generic"; 438 | } 439 | } 440 | 441 | /** 442 | * Create a GSI with one method. 443 | */ 444 | private void createGSI(GSICmdObj gsiCmdObj, TelegramBot bot) { 445 | /* 446 | * Variables to bash 447 | */ 448 | ProcessBuilder pb; 449 | InputStream inputStream = null; 450 | InputStreamReader inputStreamReader = null; 451 | BufferedReader bufferedReader = null; 452 | 453 | /* 454 | * Pre-final GSI process variables 455 | */ 456 | boolean success = false; 457 | Update update = gsiCmdObj.getUpdate(); 458 | StringBuilder fullLogs = new StringBuilder(); 459 | String builder = update.getMessage().getFrom().getFirstName(); 460 | Long builderID = update.getMessage().getFrom().getId(); 461 | 462 | /* 463 | * Start the GSI process 464 | */ 465 | pb = new ProcessBuilder("/bin/bash", "-c", 466 | "cd " + toolPath + " ; ./url2GSI.sh '" + gsiCmdObj.getUrl() + "' " + gsiCmdObj.getGsi() + " " + gsiCmdObj.getParam() 467 | ); 468 | fullLogs.append("-> Starting process..."); 469 | 470 | /* 471 | * Send the message, it's GSI time! 472 | */ 473 | int id = bot.sendReply(fullLogs.toString(), update); 474 | 475 | /* 476 | * GSI build process 477 | */ 478 | try { 479 | /* 480 | * Start process 481 | */ 482 | pb.redirectErrorStream(true); 483 | Process process = pb.start(); 484 | 485 | /* 486 | * Prepare in/output log 487 | */ 488 | inputStream = process.getInputStream(); 489 | inputStreamReader = new InputStreamReader(inputStream); 490 | bufferedReader = new BufferedReader(inputStreamReader); 491 | 492 | /* 493 | * Some variables (to get buffer output using readLine()) 494 | */ 495 | String line; 496 | 497 | while ((line = bufferedReader.readLine()) != null) { 498 | line = "" + line + ""; 499 | fullLogs.append("\n").append(line); 500 | bot.editMessage(fullLogs.toString(), update, id); 501 | } 502 | 503 | process.waitFor(); 504 | if (process.exitValue() == 0) { 505 | success = true; 506 | } 507 | 508 | /* 509 | * If the GSI got true boolean, it will create gzip, upload, prepare message and send it to channel/group 510 | */ 511 | if (success) { 512 | bot.editMessage(fullLogs.toString(), update, id); 513 | 514 | /* 515 | * Get files inside ErfanGSIs/output 516 | */ 517 | String[] gzipFiles = listFilesForFolder(new File("ErfanGSIs" + "/output")); 518 | 519 | /* 520 | * Gzip the files 521 | */ 522 | for (String gzipFile : gzipFiles) { 523 | fullLogs.append("\n").append("-> Gzipping: ").append(gzipFile).append(".gz").append(""); 524 | bot.editMessage(fullLogs.toString(), update, id); 525 | new FileTools().gzipFile(gzipFile, gzipFile + ".gz"); 526 | } 527 | 528 | /* 529 | * Create ArrayList to save A/B, Aonly & vendorOverlays files 530 | */ 531 | ArrayList arr = new ArrayList<>(); 532 | 533 | /* 534 | * A/B, Aonly & vendorOverlay Atomic variables 535 | */ 536 | AtomicReference aonly = new AtomicReference<>(""); 537 | AtomicReference ab = new AtomicReference<>(""); 538 | AtomicReference vendorOverlays = new AtomicReference<>(""); 539 | AtomicReference odmOverlays = new AtomicReference<>(""); 540 | 541 | /* 542 | * Try to get files inside ErfanGSIs/output and set into correct variable (ex: A/B image to A/B variable) 543 | */ 544 | try (Stream paths = Files.walk(Paths.get("ErfanGSIs/output/"))) { 545 | paths 546 | .filter(Files::isRegularFile) 547 | .forEach(fileName -> { 548 | if (fileName.toString().endsWith(".gz") || fileName.toString().endsWith("System-Tree.txt")) { 549 | arr.add(fileName.toString()); 550 | if (fileName.toString().contains("Aonly")) { 551 | aonly.set(FilenameUtils.getBaseName(fileName.toString()) + "." + FilenameUtils.getExtension(fileName.toString())); 552 | } else if (fileName.toString().contains("AB")) { 553 | ab.set(FilenameUtils.getBaseName(fileName.toString()) + "." + FilenameUtils.getExtension(fileName.toString())); 554 | } else if (fileName.toString().contains("VendorOverlays")) { 555 | vendorOverlays.set(FilenameUtils.getBaseName(fileName.toString()) + "." + FilenameUtils.getExtension(fileName.toString())); 556 | } else if (fileName.toString().contains("ODMOverlays")) { 557 | odmOverlays.set(FilenameUtils.getBaseName(fileName.toString()) + "." + FilenameUtils.getExtension(fileName.toString())); 558 | } 559 | } 560 | if (fileName.toString().contains(".txt") && !fileName.toString().contains("System-Tree")) { 561 | infoGSI = fileName.toString(); 562 | } 563 | }); 564 | } catch (IOException e) { 565 | logger.error(e.getMessage()); 566 | } 567 | 568 | /* 569 | * Now say the bot will upload files to SourceForge 570 | */ 571 | fullLogs.append("\n").append("-> Uploading compressed files from GSI to SourceForge..."); 572 | bot.editMessage(fullLogs.toString(), update, id); 573 | 574 | /* 575 | * SourceForge upload time 576 | */ 577 | String re = new SourceForgeUpload().uploadGsi(arr, gsiCmdObj.getGsi()); 578 | re = re + "/"; 579 | 580 | /* 581 | * Check the GSI name has special name, like this: 582 | * !jurl2gsi Generic:StatiXOS-Nuclear 583 | * The name of this ROM is 'StatiXOS Nuclear' (without quotes), the '-' (char) will be the replacement char, to be used as a space 584 | */ 585 | if (gsiCmdObj.getGsi().contains(":")) { 586 | gsiCmdObj.setGsi(gsiCmdObj.getGsi().split(":")[1]); 587 | gsiCmdObj.setGsi(gsiCmdObj.getGsi().replace("-", " ")); 588 | gsiCmdObj.setGsi(gsiCmdObj.getGsi().replace("_", " ")); 589 | } 590 | 591 | /* 592 | * Prepare GSI message 593 | */ 594 | SendMessage sendMessage = new SendMessage(); 595 | sendMessage.setDisableWebPagePreview(true); 596 | sendMessage.enableHtml(true); 597 | 598 | /* 599 | * Prepare InlineKeyboardButton 600 | */ 601 | InlineKeyboardMarkup markupInline = new InlineKeyboardMarkup(); 602 | List> rowsInline = new ArrayList<>(); 603 | 604 | if (!aonly.toString().trim().equals("")) { 605 | List rowInline2 = new ArrayList<>(); 606 | InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton(); 607 | inlineKeyboardButton.setText("Aonly Download"); 608 | inlineKeyboardButton.setUrl("https://sourceforge.net/projects/" + SourceForgeSetup.getSfConf("bot-sf-proj") + "/files/" + re + aonly); 609 | rowInline2.add(inlineKeyboardButton); 610 | rowsInline.add(rowInline2); 611 | } 612 | 613 | if (!ab.toString().trim().equals("")) { 614 | List rowInline = new ArrayList<>(); 615 | InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton(); 616 | inlineKeyboardButton.setText("A/B Download"); 617 | inlineKeyboardButton.setUrl("https://sourceforge.net/projects/" + SourceForgeSetup.getSfConf("bot-sf-proj") + "/files/" + re + ab); 618 | rowInline.add(inlineKeyboardButton); 619 | rowsInline.add(rowInline); 620 | } 621 | 622 | if (!vendorOverlays.toString().trim().equals("")) { 623 | List rowInline = new ArrayList<>(); 624 | InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton(); 625 | inlineKeyboardButton.setText("Vendor Overlays Download"); 626 | inlineKeyboardButton.setUrl("https://sourceforge.net/projects/" + SourceForgeSetup.getSfConf("bot-sf-proj") + "/files/" + re + vendorOverlays); 627 | rowInline.add(inlineKeyboardButton); 628 | rowsInline.add(rowInline); 629 | } 630 | 631 | if (!odmOverlays.toString().trim().equals("")) { 632 | List rowInline = new ArrayList<>(); 633 | InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton(); 634 | inlineKeyboardButton.setText("ODM Overlays Download"); 635 | inlineKeyboardButton.setUrl("https://sourceforge.net/projects/" + SourceForgeSetup.getSfConf("bot-sf-proj") + "/files/" + re + odmOverlays); 636 | rowInline.add(inlineKeyboardButton); 637 | rowsInline.add(rowInline); 638 | } 639 | 640 | /* 641 | * Finish InlineKeyboardButton setup 642 | */ 643 | markupInline.setKeyboard(rowsInline); 644 | sendMessage.setReplyMarkup(markupInline); 645 | 646 | /* 647 | * Info of GSI image 648 | */ 649 | String descGSI = "" + new FileTools().readFile(infoGSI).trim(); 650 | 651 | /* 652 | * Prepare message id 653 | */ 654 | int idGSI; 655 | 656 | /* 657 | * Send GSI message 658 | */ 659 | sendMessage.setText("Requested " + gsiCmdObj.getGsi() + " | GSI + SGSI" 660 | + "\nFrom " + getModelOfOutput(toolPath + "output") 661 | + "\nBuilt by " + builder + "" 662 | + "\n\nInformation\n" + descGSI 663 | + "\n\n" 664 | + noticeGSI 665 | + developerNoticeGSI 666 | + "Credits" + "\n" 667 | + "Erfan Abdi" + " | " 668 | + "Xiaoxindada" + " | " 669 | + "Husson" + " | " 670 | + "Bo³+t" + "\n\n" 671 | + "Treble Experience" + "\n" 672 | + "Channel | Chat | GitHub" 673 | ); 674 | sendMessage.setChatId(Objects.requireNonNull(SourceForgeSetup.getSfConf("bot-announcement-id"))); 675 | idGSI = bot.sendMessageAsyncBase(sendMessage, update); 676 | 677 | fullLogs.append("\n").append("-> Finished!"); 678 | bot.editMessage(fullLogs.toString(), update, id); 679 | 680 | /* 681 | * Reply kthx 682 | */ 683 | if (idGSI != 0) bot.sendReply(prefObj.getString("egsi_done") 684 | .replace("%1", gsiCmdObj.getGsi()) 685 | .replace("%2", String.valueOf(builderID)) 686 | .replace("%3", builder) 687 | .replace("%4", Objects.requireNonNull(Config.getDefConfig("publicChannel"))) 688 | .replace("%5", String.valueOf(idGSI)), update); 689 | 690 | /* 691 | * Delete output/input folder with two codes (The first seems not worked so to make sure, use other code for it) 692 | */ 693 | FileUtils.deleteDirectory(new File(toolPath + "output")); 694 | if (FileTools.checkIfFolderExists(toolPath + "output")) { 695 | if (FileTools.deleteFolder(toolPath + "output")) { 696 | logger.info("Output folder deleted"); 697 | } 698 | } 699 | 700 | FileUtils.deleteDirectory(new File(toolPath + "input")); 701 | if (FileTools.checkIfFolderExists(toolPath + "input")) { 702 | if (FileTools.deleteFolder(toolPath + "input")) { 703 | logger.info("Input folder deleted"); 704 | } 705 | } 706 | 707 | /* 708 | * Cleanup variables 709 | */ 710 | ab.set(null); 711 | aonly.set(null); 712 | vendorOverlays.set(null); 713 | odmOverlays.set(null); 714 | infoGSI = null; 715 | developerNoticeGSI = null; 716 | arr.clear(); 717 | gsiCmdObj.clean(); 718 | } else { 719 | bot.sendReply(messageError, update); 720 | } 721 | } catch (Exception ex) { 722 | bot.sendReply(messageError, update); 723 | } finally { 724 | if (inputStream != null) { 725 | try { 726 | inputStream.close(); 727 | } catch (IOException ioException) { 728 | logger.error(ioException.getMessage()); 729 | } 730 | } 731 | 732 | if (inputStreamReader != null) { 733 | try { 734 | inputStreamReader.close(); 735 | } catch (IOException ioException) { 736 | logger.error(ioException.getMessage()); 737 | } 738 | } 739 | 740 | if (bufferedReader != null) { 741 | try { 742 | bufferedReader.close(); 743 | } catch (IOException ioException) { 744 | logger.error(ioException.getMessage()); 745 | } 746 | } 747 | } 748 | } 749 | 750 | /** 751 | * Add port permission using user id. 752 | */ 753 | @SuppressWarnings({"rawtypes", "unchecked"}) 754 | private boolean addPortPerm(String id) { 755 | try { 756 | if (FileTools.checkFileExistsCurPath("configs/allowed2port.json")) { 757 | ArrayList arrayList = JSONs.getArrayFromJSON("configs/allowed2port.json"); 758 | if (arrayList != null) { 759 | arrayList.add(id); 760 | } 761 | JSONs.writeArrayToJSON(arrayList, "configs/allowed2port.json"); 762 | } else { 763 | ArrayList arrayList = new ArrayList<>(); 764 | arrayList.add(id); 765 | JSONs.writeArrayToJSON(arrayList, "configs/allowed2port.json"); 766 | } 767 | return true; 768 | } catch (Exception e) { 769 | logger.error(e.getMessage(), e); 770 | return false; 771 | } 772 | } 773 | 774 | /** 775 | * Common message for list/jurl2gsi args 776 | */ 777 | public void sendSupportedROMs(Update update, TelegramBot bot, PrefObj prefs) { 778 | File[] supportedGSIsPandQ = ArrayUtils.addAll(supportedGSIs10); 779 | File[] supportedGSIsRandS = ArrayUtils.addAll(supportedGSIs11, supportedGSIs12); 780 | 781 | if (supportedGSIsPandQ != null && supportedGSIsRandS != null) { 782 | bot.sendReply(prefs.getString("egsi_supported_types") 783 | .replace("%1", 784 | Arrays.toString(supportedGSIs10).replace(toolPath + "roms/10/", "") 785 | .replace("[", "") 786 | .replace("]", "")) 787 | .replace("%2", 788 | Arrays.toString(supportedGSIs11).replace(toolPath + "roms/11/", "") 789 | .replace("[", "") 790 | .replace("]", "")) 791 | .replace("%3", 792 | Arrays.toString(supportedGSIs12).replace(toolPath + "roms/12/", "") 793 | .replace("[", "") 794 | .replace("]", "")), update); 795 | } else { 796 | bot.sendReply(prefs.getString("egsi_something_is_wrong"), update); 797 | } 798 | } 799 | } 800 | --------------------------------------------------------------------------------