├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src └── main ├── java └── me │ └── fabriziocoder │ ├── database │ └── MongoDB.java │ └── luxanna │ ├── Luxanna.java │ ├── commands │ ├── core │ │ ├── BotInfoSubCommand.java │ │ ├── CoreCommand.java │ │ ├── HelpCommand.java │ │ └── PingSubCommand.java │ └── league │ │ ├── champion │ │ ├── ChampionCommand.java │ │ ├── InformationSubCommand.java │ │ ├── MasterySubCommand.java │ │ ├── RotationSubCommand.java │ │ └── SkinsSubCommand.java │ │ └── summoner │ │ ├── AddSubCommand.java │ │ ├── CurrentSubCommand.java │ │ ├── LastMatchSubCommand.java │ │ ├── ProfileSubCommand.java │ │ ├── RemoveSubCommand.java │ │ └── SummonerCommand.java │ └── utils │ ├── ChampionUtils.java │ ├── EmojiUtils.java │ ├── MatchUtils.java │ └── SummonerUtils.java └── resources ├── META-INF └── MANIFEST.MF └── logback.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | src/main/resources/bot.properties 3 | # Project exclude paths 4 | target/ 5 | l4j8cache/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2022 Fabrizio Coder 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Banner](https://i.imgur.com/biAW7gB.png)](https://discord.com/api/oauth2/authorize?client_id=949565943275720736&permissions=2147796992&scope=bot%20applications.commands) 2 | 3 | This is the source code for the Discord bot portions that compromise Luxanna Bot. 4 | 5 | ## Authors 6 | 7 | - [@FabrizioCoder](https://www.github.com/FabrizioCoder). 8 | - Inspired on [Zoe Bot](https://github.com/Zoe-Discord-Bot/Zoe-Discord-Bot) by [@KaluNight](https://github.com/KaluNight). 9 | 10 | 11 | ## Built with 12 | 13 | * [JDA](https://github.com/DV8FromTheWorld/JDA) 14 | * [R4J](https://github.com/stelar7/R4J) 15 | * [Orianna](https://github.com/meraki-analytics/orianna) 16 | 17 | 18 | ## Command's examples 19 | 20 | See Luxanna's commands with its "/" slash integration. Try some commands like "/summoner lastmatch" or get more information with "/help". 21 | 22 | ![Profile Command](https://user-images.githubusercontent.com/74118796/185774404-1a7377cd-df88-4db8-8778-433018facbdb.png) 23 | 24 | ![LastMatch Command](https://user-images.githubusercontent.com/74118796/185774418-249094e9-9749-46fc-bc40-bd10484683f4.png) 25 | 26 | ## License 27 | 28 | [Apache License 2.0](https://choosealicense.com/licenses/apache-2.0/). 29 | 30 | 31 | ## Feedback 32 | 33 | If you have any feedback, please reach out to me at Discord: `FabrizioCoder#6030`. 34 | 35 | ## Links 36 | 37 | - Top.gg: [click here](https://top.gg/bot/949565943275720736) 38 | - Discord bots: [click here](https://discord.bots.gg/bots/949565943275720736) 39 | - Support server: [click here](https://discord.gg/AcruVkyYHm) 40 | - Github repository: [click here]( https://github.com/FabrizioCoder/LuxannaBot) 41 | 42 | 43 | ## Legal information 44 | Luxanna isn't endorsed by Riot Games. 45 | League of Legends and Riot Games are trademarks or registered trademarks of Riot Games, Inc. League of Legends © Riot Games, Inc. 46 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | me.fabriziocoder 8 | LuxannaBot 9 | 1.0.0-ALPHA 10 | 11 | 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-shade-plugin 17 | 3.3.0 18 | 19 | 20 | package 21 | 22 | shade 23 | 24 | 25 | false 26 | 27 | 28 | 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-jar-plugin 34 | 2.4 35 | 36 | 37 | 38 | me.fabriziocoder.luxanna.Luxanna 39 | 40 | 41 | 42 | 43 | 44 | 45 | org.apache.maven.plugins 46 | maven-dependency-plugin 47 | 2.8 48 | 49 | 50 | copy-dependencies 51 | package 52 | 53 | copy-dependencies 54 | 55 | 56 | 57 | ${project.build.directory}/dependency-jars/ 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | src/main/resources 68 | true 69 | 70 | 71 | 72 | 73 | 74 | 18 75 | 18 76 | UTF-8 77 | 78 | 79 | 80 | 81 | chew-m2-snapshots 82 | https://m2.chew.pro/snapshots/ 83 | 84 | 85 | jitpack.io 86 | https://jitpack.io 87 | 88 | 89 | 90 | 91 | 92 | net.dv8tion 93 | JDA 94 | 5.0.0-alpha.18 95 | 96 | 97 | 98 | pw.chew 99 | jda-chewtils 100 | 2.0-SNAPSHOT 101 | compile 102 | pom 103 | 104 | 105 | 106 | com.merakianalytics.orianna 107 | orianna 108 | 4.0.0-rc8 109 | 110 | 111 | 112 | com.github.stelar7 113 | R4J 114 | 2.1.22 115 | 116 | 117 | 118 | ch.qos.logback 119 | logback-classic 120 | 1.2.11 121 | 122 | 123 | 124 | org.mongodb 125 | mongodb-driver-sync 126 | 4.7.1 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/database/MongoDB.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.database; 2 | 3 | import com.mongodb.client.MongoClient; 4 | import com.mongodb.client.MongoClients; 5 | import com.mongodb.client.MongoCollection; 6 | import com.mongodb.client.MongoDatabase; 7 | import org.bson.Document; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public class MongoDB { 11 | 12 | private static final org.slf4j.Logger logger = LoggerFactory.getLogger(MongoDB.class); 13 | static MongoClient client; 14 | 15 | public static void start(String host) { 16 | client = MongoClients.create(host); 17 | logger.info("MongoDB client created"); 18 | } 19 | 20 | private static MongoCollection getCollection() { 21 | MongoDatabase database = client.getDatabase("luxanna"); 22 | return database.getCollection("summoners"); 23 | } 24 | 25 | public static void addUserProfile(long userId, String summonerName, String summonerPlatform) { 26 | Document userProfileDocument = new Document("_id", String.valueOf(userId)).append("summonerName", summonerName).append("summonerPlatform", summonerPlatform); 27 | getCollection().insertOne(userProfileDocument); 28 | } 29 | 30 | public static boolean removeUserProfile(long userId) { 31 | if (getCollection().find(new Document("_id", String.valueOf(userId))).first() != null) { 32 | getCollection().deleteOne(new Document("_id", String.valueOf(userId))); 33 | return true; 34 | } 35 | return false; 36 | } 37 | 38 | public static com.mongodb.client.FindIterable userProfileExists(long userId) { 39 | return getCollection().find(new Document("_id", String.valueOf(userId))); 40 | } 41 | 42 | public static Document getUserProfile(long userId) { 43 | return getCollection().find(new Document("_id", String.valueOf(userId))).first(); 44 | } 45 | 46 | public static void updateUserProfile(long userId, String summonerName, String summonerPlatform) { 47 | getCollection().updateOne(new Document("_id", String.valueOf(userId)), new Document("$set", new Document("summonerName", summonerName).append("summonerPlatform", summonerPlatform))); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/Luxanna.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna; 2 | 3 | import com.jagrosh.jdautilities.command.CommandClient; 4 | import com.jagrosh.jdautilities.command.CommandClientBuilder; 5 | import com.merakianalytics.orianna.Orianna; 6 | import com.merakianalytics.orianna.types.common.Platform; 7 | import me.fabriziocoder.database.MongoDB; 8 | import me.fabriziocoder.luxanna.commands.core.CoreCommand; 9 | import me.fabriziocoder.luxanna.commands.core.HelpCommand; 10 | import me.fabriziocoder.luxanna.commands.league.champion.ChampionCommand; 11 | import me.fabriziocoder.luxanna.commands.league.summoner.SummonerCommand; 12 | import net.dv8tion.jda.api.JDABuilder; 13 | import net.dv8tion.jda.api.OnlineStatus; 14 | import net.dv8tion.jda.api.entities.Activity; 15 | import net.dv8tion.jda.api.requests.GatewayIntent; 16 | import no.stelar7.api.r4j.basic.APICredentials; 17 | import no.stelar7.api.r4j.impl.R4J; 18 | import no.stelar7.api.r4j.impl.lol.raw.DDragonAPI; 19 | 20 | import javax.security.auth.login.LoginException; 21 | import java.io.File; 22 | import java.io.IOException; 23 | import java.util.Properties; 24 | 25 | public class Luxanna { 26 | 27 | public static void main(String[] args) throws LoginException, IOException { 28 | Properties properties = new Properties(); 29 | properties.load(new File("classes/bot.properties").toURI().toURL().openStream()); 30 | 31 | CommandClientBuilder builder = new CommandClientBuilder().setOwnerId(properties.getProperty("OWNER_ID")).setCoOwnerIds(properties.getProperty("CO_OWNER_1_ID"), properties.getProperty("CO_OWNER_2_ID")).setStatus(OnlineStatus.DO_NOT_DISTURB).useHelpBuilder(false).setServerInvite(properties.getProperty("SERVER_INVITE")).setActivity(Activity.watching("the summoner rift")); 32 | 33 | builder.addSlashCommands(new HelpCommand(), new CoreCommand(), new SummonerCommand(), new ChampionCommand()); 34 | CommandClient commandClient = builder.build(); 35 | 36 | JDABuilder.createLight(properties.getProperty("BOT_TOKEN"), GatewayIntent.GUILD_MEMBERS).disableIntents(GatewayIntent.GUILD_MESSAGE_TYPING, GatewayIntent.DIRECT_MESSAGES, GatewayIntent.DIRECT_MESSAGE_REACTIONS, GatewayIntent.DIRECT_MESSAGE_TYPING, GatewayIntent.GUILD_BANS, GatewayIntent.GUILD_MESSAGE_TYPING, GatewayIntent.GUILD_INVITES).addEventListeners(commandClient).build(); 37 | 38 | Orianna.setDefaultPlatform(Platform.NORTH_AMERICA); 39 | Orianna.setRiotAPIKey(properties.getProperty("RIOT_API_KEY")); 40 | Orianna.setDefaultLocale(properties.getProperty("DEFAULT_LOCALE")); 41 | new R4J(new APICredentials(properties.getProperty("RIOT_API_KEY"))); 42 | DDragonAPI.getInstance().getChampions(); 43 | MongoDB.start(properties.getProperty("MONGO_URI")); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/core/BotInfoSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.core; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import com.jagrosh.jdautilities.commons.JDAUtilitiesInfo; 6 | import net.dv8tion.jda.api.EmbedBuilder; 7 | import net.dv8tion.jda.api.JDAInfo; 8 | 9 | public class BotInfoSubCommand extends SlashCommand { 10 | 11 | public BotInfoSubCommand() { 12 | this.name = "botinfo"; 13 | this.cooldown = 15; 14 | this.help = "Shows info about the bot"; 15 | this.guildOnly = true; 16 | } 17 | 18 | 19 | @Override 20 | public void execute(SlashCommandEvent event) { 21 | event.deferReply().queue(); 22 | EmbedBuilder messageEmbed = new EmbedBuilder().setTitle(String.format("%s - your League of Legends bot", event.getJDA().getSelfUser().getName()), "https://top.gg/bot/949565943275720736").setColor(0x2564f4).setFooter("Last restart", null).setTimestamp(event.getClient().getStartTime()).setThumbnail(event.getJDA().getSelfUser().getAvatarUrl()).setImage("https://i.imgur.com/XTgkUlF.png"); 23 | 24 | String[] botStats = {String.format("`Servers:` %,7d", event.getJDA().getGuilds().size()), String.format("`Gateway ping:` %sms", event.getJDA().getGatewayPing()), String.format("`Rest ping:` %sms", event.getJDA().getRestPing().complete())}; 25 | messageEmbed.addField("> Bot stats", String.join("\n", botStats), false); 26 | 27 | String[] librariesInfoDescription = {String.format("`JDA:` [%s](%s)", JDAInfo.VERSION, JDAInfo.GITHUB), String.format("`JDA-Utilities:` [%s](%s)", JDAUtilitiesInfo.VERSION, JDAUtilitiesInfo.GITHUB), String.format("`Orianna:` [%s](%s)", "4.0.0-rc8", "https://github.com/meraki-analytics/orianna"), String.format("`R4J:` [%s](%s)", "2.1.22", "https://github.com/stelar7/R4J")}; 28 | messageEmbed.addField("> Libraries versions", String.join("\n", librariesInfoDescription), false); 29 | messageEmbed.addField("> Developer", event.getJDA().retrieveApplicationInfo().complete().getOwner().getAsMention(), true); 30 | messageEmbed.addField("> Links", String.format("[Support Server](%s)\n[Bot Invite](%s)", event.getClient().getServerInvite(), "https://discord.com/api/oauth2/authorize?client_id=949565943275720736&permissions=2147796992&scope=bot%20applications.commands"), true); 31 | 32 | event.getHook().sendMessageEmbeds(messageEmbed.build()).queue(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/core/CoreCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.core; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | 6 | public class CoreCommand extends SlashCommand { 7 | 8 | public CoreCommand() { 9 | this.name = "core"; 10 | this.help = "Core commands"; 11 | this.category = new Category("Core"); 12 | this.children = new SlashCommand[]{new PingSubCommand(), new BotInfoSubCommand()}; 13 | } 14 | 15 | @Override 16 | public void execute(SlashCommandEvent event) { 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/core/HelpCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.core; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import net.dv8tion.jda.api.EmbedBuilder; 6 | import net.dv8tion.jda.api.entities.MessageEmbed; 7 | 8 | import java.util.Arrays; 9 | 10 | public class HelpCommand extends SlashCommand { 11 | 12 | public static final String COMMAND_NAME = "help"; 13 | public static final String COMMAND_DESCRIPTION = "Shows help options for all commands"; 14 | 15 | @Override 16 | public String getName() { 17 | return COMMAND_NAME; 18 | } 19 | 20 | @Override 21 | public String getHelp() { 22 | return COMMAND_DESCRIPTION; 23 | } 24 | 25 | @Override 26 | public void execute(SlashCommandEvent event) { 27 | event.deferReply().queue(); 28 | StringBuilder leagueCommands = new StringBuilder(); 29 | StringBuilder coreCommands = new StringBuilder(); 30 | event.getClient().getSlashCommands().forEach(command -> { 31 | if (command.getName().equals("summoner") || command.getName().equals("champion")) { 32 | Arrays.stream(command.getChildren()).map(SlashCommand::getName).forEach((it) -> leagueCommands.append("`").append(String.format("/%s %s", command.getName(), it)).append("` ")); 33 | } else if (command.getName().equals("core")) { 34 | Arrays.stream(command.getChildren()).map(SlashCommand::getName).forEach((it) -> coreCommands.append("`").append(String.format("/%s %s", command.getName(), it)).append("` ")); 35 | } else { 36 | coreCommands.append("`").append(String.format("/%s", command.getName())).append("` "); 37 | } 38 | }); 39 | 40 | MessageEmbed messageEmbed = new EmbedBuilder().setColor(0x2564f4).setTitle(String.format("%s — Commands", event.getJDA().getSelfUser().getName()), "https://top.gg/bot/949565943275720736").setDescription(String.format("Hi! I'm %s, the perfect way to play your games.", event.getJDA().getSelfUser().getName())).addField("» League of Legends", String.join("", leagueCommands), false).addField("» Core", String.join("", coreCommands), false).setThumbnail(event.getJDA().getSelfUser().getAvatarUrl()).setImage("https://i.imgur.com/ntMRhP0.png").build(); 41 | 42 | event.getHook().sendMessageEmbeds(messageEmbed).queue(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/core/PingSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.core; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import net.dv8tion.jda.api.Permission; 6 | 7 | public class PingSubCommand extends SlashCommand { 8 | public PingSubCommand() { 9 | this.name = "ping"; 10 | this.cooldown = 5; 11 | this.help = "Returns the latency of the bot"; 12 | this.botPermissions = new Permission[]{Permission.MESSAGE_SEND}; 13 | } 14 | 15 | @Override 16 | public void execute(SlashCommandEvent event) { 17 | long gateway = event.getJDA().getGatewayPing(); 18 | long rest = event.getJDA().getRestPing().complete(); 19 | event.deferReply().queue( 20 | hook -> hook.editOriginal(String.format("Pong! (gateway: %sms, rest: %sms)", gateway, rest)).queue() 21 | ); 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/champion/ChampionCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.champion; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | 6 | public class ChampionCommand extends SlashCommand { 7 | 8 | public ChampionCommand() { 9 | this.name = "champion"; 10 | this.help = "[LoL] Champion commands"; 11 | this.category = new Category("Champion"); 12 | this.children = new SlashCommand[]{new MasterySubCommand(), new RotationSubCommand(), new SkinsSubCommand(), new InformationSubCommand()}; 13 | } 14 | 15 | @Override 16 | public void execute(SlashCommandEvent event) { 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/champion/InformationSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.champion; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import com.merakianalytics.orianna.Orianna; 6 | import com.merakianalytics.orianna.types.core.staticdata.Champion; 7 | import me.fabriziocoder.luxanna.utils.EmojiUtils; 8 | import net.dv8tion.jda.api.EmbedBuilder; 9 | import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; 10 | import net.dv8tion.jda.api.interactions.commands.Command; 11 | import net.dv8tion.jda.api.interactions.commands.OptionType; 12 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 13 | import no.stelar7.api.r4j.impl.lol.raw.DDragonAPI; 14 | import no.stelar7.api.r4j.pojo.lol.staticdata.champion.StaticChampion; 15 | 16 | import java.util.List; 17 | import java.util.Map; 18 | import java.util.Objects; 19 | 20 | public class InformationSubCommand extends SlashCommand { 21 | static final String COMMAND_NAME = "information"; 22 | static final String COMMAND_DESCRIPTION = "Get information about a champion"; 23 | 24 | public InformationSubCommand() { 25 | this.name = COMMAND_NAME; 26 | this.help = COMMAND_DESCRIPTION; 27 | this.guildOnly = false; 28 | this.cooldown = 10; 29 | this.options = List.of(new OptionData(OptionType.STRING, "champion", "Champion's name", true).setAutoComplete(true)); 30 | } 31 | 32 | @Override 33 | public void onAutoComplete(CommandAutoCompleteInteractionEvent event) { 34 | Map allChampions = DDragonAPI.getInstance().getChampions(); 35 | if (event.getFocusedOption().getName().equals("champion")) { 36 | List choiceList; 37 | choiceList = allChampions.values().stream().filter(champion -> champion.getName().toLowerCase().startsWith(event.getFocusedOption().getValue().toLowerCase())).map(championData -> new Command.Choice(championData.getName(), championData.getId())).limit(15).toList(); 38 | event.replyChoices(choiceList).queue(); 39 | } 40 | } 41 | 42 | @Override 43 | public String getHelp() { 44 | return COMMAND_DESCRIPTION; 45 | } 46 | 47 | @Override 48 | public String getName() { 49 | return COMMAND_NAME; 50 | } 51 | 52 | @Override 53 | public void execute(SlashCommandEvent event) { 54 | event.deferReply().queue(); 55 | int championId = Integer.parseInt(Objects.requireNonNull(event.optString("champion"))); 56 | final Champion championData = Orianna.championWithId(championId).get(); 57 | if (!championData.exists()) { 58 | event.getHook().editOriginal(String.format("%s This champion doesn't exist, or you misspelled it.", EmojiUtils.Discord.X)).queue(); 59 | return; 60 | } 61 | 62 | EmbedBuilder messageEmbed = new EmbedBuilder().setColor(0x2564f4).setThumbnail(championData.getImage().getURL()).setTitle(String.format("`%s`, `%s`", championData.getName(), championData.getTitle())).setDescription(championData.getLore()); 63 | 64 | messageEmbed.addField("> Ally tips", championData.getAllyTips().toString().replace("[", "").replace("]", ""), true); 65 | messageEmbed.addField("> Enemy tips", championData.getEnemyTips().toString().replace("[", "").replace("]", ""), true); 66 | messageEmbed.setFooter("Vote for me | https://top.gg/bot/949565943275720736/vote"); 67 | 68 | event.getHook().sendMessageEmbeds(messageEmbed.build()).queue(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/champion/MasterySubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.champion; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import me.fabriziocoder.database.MongoDB; 6 | import me.fabriziocoder.luxanna.utils.ChampionUtils; 7 | import me.fabriziocoder.luxanna.utils.EmojiUtils; 8 | import me.fabriziocoder.luxanna.utils.SummonerUtils; 9 | import net.dv8tion.jda.api.EmbedBuilder; 10 | import net.dv8tion.jda.api.interactions.commands.Command; 11 | import net.dv8tion.jda.api.interactions.commands.OptionType; 12 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 13 | import no.stelar7.api.r4j.basic.constants.api.regions.LeagueShard; 14 | import no.stelar7.api.r4j.pojo.lol.championmastery.ChampionMastery; 15 | import no.stelar7.api.r4j.pojo.lol.summoner.Summoner; 16 | import org.bson.Document; 17 | 18 | import java.text.DecimalFormat; 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | public class MasterySubCommand extends SlashCommand { 23 | 24 | public static final String COMMAND_NAME = "mastery"; 25 | public static final String COMMAND_DESCRIPTION = "Shows the best summoner champions"; 26 | private static final DecimalFormat oneDecimal = new DecimalFormat("0.0"); 27 | 28 | public MasterySubCommand() { 29 | this.name = COMMAND_NAME; 30 | this.help = COMMAND_DESCRIPTION; 31 | this.cooldown = 15; 32 | this.guildOnly = false; 33 | this.options = List.of(new OptionData(OptionType.STRING, "summoner-name", "The name of the summoner to search for").setRequired(false), new OptionData(OptionType.STRING, "region", "The region of the account").addChoices(regionChoices()).setRequired(false)); 34 | } 35 | 36 | public static String humanReadableInt(long number) { 37 | long absNumber = Math.abs(number); 38 | double result; 39 | String suffix = ""; 40 | if (absNumber < 1024) { 41 | result = number; 42 | } else if (absNumber < 1024 * 1024) { 43 | result = number / 1024.0; 44 | suffix = "K"; 45 | } else if (absNumber < 1024 * 1024 * 1024) { 46 | result = number / (1024.0 * 1024); 47 | suffix = "M"; 48 | } else { 49 | result = number / (1024.0 * 1024 * 1024); 50 | suffix = "B"; 51 | } 52 | return oneDecimal.format(result) + suffix; 53 | } 54 | 55 | private List regionChoices() { 56 | List options = new ArrayList<>(); 57 | LeagueShard[] leagueShards = LeagueShard.values(); 58 | for (int i = 1; i < leagueShards.length; i++) { 59 | if (i >= 12) break; 60 | LeagueShard leagueShard = leagueShards[i]; 61 | String keyName = leagueShard.getKeys()[1]; 62 | if (keyName.isEmpty()) continue; 63 | options.add(new Command.Choice(keyName.toUpperCase(), leagueShard.name())); 64 | } 65 | return options; 66 | } 67 | 68 | @Override 69 | public String getHelp() { 70 | return COMMAND_DESCRIPTION; 71 | } 72 | 73 | @Override 74 | public String getName() { 75 | return COMMAND_NAME; 76 | } 77 | 78 | @Override 79 | public void execute(SlashCommandEvent event) { 80 | event.deferReply().queue(); 81 | 82 | String summonerName = event.optString("summoner-name"); 83 | String region = event.optString("region"); 84 | if (summonerName == null && region == null) { 85 | Document existUserProfile = MongoDB.userProfileExists(event.getUser().getIdLong()).first(); 86 | if (existUserProfile != null) { 87 | summonerName = existUserProfile.getString("summonerName"); 88 | region = existUserProfile.getString("summonerPlatform"); 89 | } else { 90 | event.getHook().editOriginal(String.format("%s You don't yet have an account registered to use the no-argument command.", EmojiUtils.Discord.X)).queue(); 91 | return; 92 | } 93 | } else if (summonerName == null) { 94 | event.getHook().editOriginal(String.format("%s You need to specify a summoner name.", EmojiUtils.Discord.X)).queue(); 95 | return; 96 | } else if (region == null) { 97 | event.getHook().editOriginal(String.format("%s You need to specify a region.", EmojiUtils.Discord.X)).queue(); 98 | return; 99 | } 100 | 101 | final Summoner summonerData = SummonerUtils.getSummonerByName(summonerName, LeagueShard.valueOf(region)); 102 | 103 | if (summonerData == null) { 104 | event.getHook().editOriginal(String.format("%s That summoner couldn't be found, at least on that region.", EmojiUtils.Discord.X)).queue(); 105 | return; 106 | } 107 | 108 | final List summonerTopChampions = SummonerUtils.getSummonerTopChampionsSummonerId(summonerData.getSummonerId(), LeagueShard.valueOf(region), 15); 109 | 110 | if (summonerTopChampions == null) { 111 | event.getHook().editOriginal("This summoner has not played champions.").queue(); 112 | return; 113 | } 114 | 115 | StringBuilder str = new StringBuilder(); 116 | 117 | for (int i = 0; i < summonerTopChampions.size(); i++) { 118 | ChampionMastery mastery = summonerTopChampions.get(i); 119 | String championName = ChampionUtils.getChampionNameById(mastery.getChampionId()); 120 | str.append(String.format("`%3d.` [`%5s`] [`%d`] %s %s%n", i + 1, humanReadableInt(mastery.getChampionPoints()), mastery.getChampionLevel(), EmojiUtils.getChampionEmojiByChampionName(championName), championName)); 121 | } 122 | EmbedBuilder messageEmbed = new EmbedBuilder().setColor(0x2564f4).setAuthor(String.format("Top %s Champion%s", summonerTopChampions.size(), summonerTopChampions.size() == 1 ? "" : "s")).setTitle(String.format("`%s` - `%s`", summonerData.getName(), summonerData.getPlatform().prettyName())).setThumbnail(SummonerUtils.makeProfileIconURL(String.valueOf(summonerData.getProfileIconId()))).setDescription(str.toString()); 123 | messageEmbed.setFooter("Vote for me | https://top.gg/bot/949565943275720736/vote"); 124 | event.getHook().sendMessageEmbeds(messageEmbed.build()).queue(); 125 | } 126 | } -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/champion/RotationSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.champion; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import me.fabriziocoder.luxanna.utils.EmojiUtils; 6 | import net.dv8tion.jda.api.EmbedBuilder; 7 | import net.dv8tion.jda.api.interactions.commands.Command; 8 | import net.dv8tion.jda.api.interactions.commands.OptionType; 9 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 10 | import no.stelar7.api.r4j.basic.constants.api.regions.LeagueShard; 11 | import no.stelar7.api.r4j.impl.lol.raw.ChampionAPI; 12 | import no.stelar7.api.r4j.pojo.lol.staticdata.champion.StaticChampion; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class RotationSubCommand extends SlashCommand { 18 | public static final String COMMAND_NAME = "rotation"; 19 | public static final String COMMAND_DESCRIPTION = "Displays the champion rotation"; 20 | 21 | public RotationSubCommand() { 22 | this.name = COMMAND_NAME; 23 | this.help = COMMAND_DESCRIPTION; 24 | this.guildOnly = false; 25 | this.cooldown = 20; 26 | this.options = List.of(new OptionData(OptionType.STRING, "region", "The region from which you want to obtain the free champion rotation").addChoices(regionChoices()).setRequired(true)); 27 | } 28 | 29 | private List regionChoices() { 30 | List options = new ArrayList<>(); 31 | LeagueShard[] leagueShards = LeagueShard.values(); 32 | for (int i = 1; i < leagueShards.length; i++) { 33 | if (i >= 12) break; 34 | LeagueShard leagueShard = leagueShards[i]; 35 | String keyName = leagueShard.getKeys()[1]; 36 | if (keyName.isEmpty()) continue; 37 | options.add(new Command.Choice(keyName.toUpperCase(), leagueShard.name())); 38 | } 39 | return options; 40 | } 41 | 42 | @Override 43 | public String getHelp() { 44 | return COMMAND_DESCRIPTION; 45 | } 46 | 47 | @Override 48 | public String getName() { 49 | return COMMAND_NAME; 50 | } 51 | 52 | @Override 53 | public void execute(SlashCommandEvent event) { 54 | event.deferReply().queue(); 55 | 56 | List freeChampions = ChampionAPI.getInstance().getFreeToPlayRotation(LeagueShard.valueOf(event.optString("region"))).getFreeChampions(); 57 | 58 | StringBuilder freeChampionsToPLayText = new StringBuilder(); 59 | for (int i = 0; i < freeChampions.size(); i++) { 60 | StaticChampion freeChampion = freeChampions.get(i); 61 | freeChampionsToPLayText.append(String.format("`%3d.` %s %s\n", i + 1, EmojiUtils.getChampionEmojiByChampionName(freeChampion.getName()), freeChampion.getName())); 62 | } 63 | EmbedBuilder messageEmbed = new EmbedBuilder().setColor(0x2564f4).setThumbnail(event.getJDA().getSelfUser().getAvatarUrl()).setTitle(String.format("Free champions rotation to play in `%s`", LeagueShard.valueOf(event.optString("region")).prettyName())).setDescription(freeChampionsToPLayText.toString()); 64 | messageEmbed.setFooter("Vote for me | https://top.gg/bot/949565943275720736/vote"); 65 | event.getHook().sendMessageEmbeds(messageEmbed.build()).queue(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/champion/SkinsSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.champion; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import com.merakianalytics.orianna.types.core.searchable.SearchableList; 6 | import com.merakianalytics.orianna.types.core.staticdata.Champion; 7 | import com.merakianalytics.orianna.types.core.staticdata.Skin; 8 | import me.fabriziocoder.luxanna.utils.EmojiUtils; 9 | import net.dv8tion.jda.api.EmbedBuilder; 10 | import net.dv8tion.jda.api.entities.MessageEmbed; 11 | import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; 12 | import net.dv8tion.jda.api.interactions.commands.Command; 13 | import net.dv8tion.jda.api.interactions.commands.OptionType; 14 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 15 | import no.stelar7.api.r4j.impl.lol.raw.DDragonAPI; 16 | import no.stelar7.api.r4j.pojo.lol.staticdata.champion.StaticChampion; 17 | 18 | import java.util.List; 19 | import java.util.Map; 20 | import java.util.Objects; 21 | 22 | public class SkinsSubCommand extends SlashCommand { 23 | 24 | public static final String COMMAND_NAME = "skins"; 25 | public static final String COMMAND_DESCRIPTION = "Displays the champion skins"; 26 | 27 | public SkinsSubCommand() { 28 | this.name = COMMAND_NAME; 29 | this.help = COMMAND_DESCRIPTION; 30 | this.guildOnly = false; 31 | this.cooldown = 20; 32 | this.options = List.of(new OptionData(OptionType.STRING, "champion", "Champion's name", true).setAutoComplete(true)); 33 | } 34 | 35 | @Override 36 | public void onAutoComplete(CommandAutoCompleteInteractionEvent event) { 37 | Map allChampions = DDragonAPI.getInstance().getChampions(); 38 | if (event.getFocusedOption().getName().equals("champion")) { 39 | List choiceList; 40 | choiceList = allChampions.values().stream().filter(champion -> champion.getName().toLowerCase().startsWith(event.getFocusedOption().getValue().toLowerCase())).map(championData -> new Command.Choice(championData.getName(), championData.getId())).limit(15).toList(); 41 | event.replyChoices(choiceList).queue(); 42 | } 43 | } 44 | 45 | @Override 46 | public String getHelp() { 47 | return COMMAND_DESCRIPTION; 48 | } 49 | 50 | @Override 51 | public String getName() { 52 | return COMMAND_NAME; 53 | } 54 | 55 | @Override 56 | public void execute(SlashCommandEvent event) { 57 | event.deferReply().queue(); 58 | int championId = Integer.parseInt(Objects.requireNonNull(event.optString("champion"))); 59 | Champion championData = Champion.withId(championId).get(); 60 | if (championData == null) { 61 | event.getHook().editOriginal(String.format("%s This champion doesn't exist, or you misspelled it.", EmojiUtils.Discord.X)).queue(); 62 | return; 63 | } 64 | 65 | SearchableList championSkins = championData.getSkins(); 66 | StringBuilder skinsText = new StringBuilder(); 67 | for (int i = 1; i < championSkins.size(); i++) { 68 | Skin skin = championSkins.get(i); 69 | skinsText.append(String.format("`%3d.` [%s](%s)\n", (i - 1) + 1, skin.getName(), skin.getSplashImageURL())); 70 | } 71 | 72 | MessageEmbed messageEmbed = new EmbedBuilder().setColor(0x2564f4).setTitle(String.format("Skins for `%s`", championData.getName())).setThumbnail(championData.getImage().getURL()).setDescription(skinsText.toString()).setFooter("Vote for me | https://top.gg/bot/949565943275720736/vote").build(); 73 | 74 | event.getHook().sendMessageEmbeds(messageEmbed).queue(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/summoner/AddSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.summoner; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import me.fabriziocoder.database.MongoDB; 6 | import me.fabriziocoder.luxanna.utils.EmojiUtils; 7 | import me.fabriziocoder.luxanna.utils.SummonerUtils; 8 | import net.dv8tion.jda.api.interactions.commands.Command; 9 | import net.dv8tion.jda.api.interactions.commands.OptionType; 10 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 11 | import no.stelar7.api.r4j.basic.constants.api.regions.LeagueShard; 12 | import no.stelar7.api.r4j.pojo.lol.summoner.Summoner; 13 | import org.bson.Document; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | public class AddSubCommand extends SlashCommand { 19 | public static final String COMMAND_NAME = "add"; 20 | public static final String COMMAND_DESCRIPTION = "Add a summoner to the database for automatic lookup"; 21 | 22 | public AddSubCommand() { 23 | this.name = COMMAND_NAME; 24 | this.help = COMMAND_DESCRIPTION; 25 | this.cooldown = 15; 26 | this.options = List.of(new OptionData(OptionType.STRING, "summoner-name", "The name of the summoner to search for").setRequired(true), new OptionData(OptionType.STRING, "region", "The region of the account").addChoices(regionChoices()).setRequired(true)); 27 | } 28 | 29 | private List regionChoices() { 30 | List options = new ArrayList<>(); 31 | LeagueShard[] leagueShards = LeagueShard.values(); 32 | for (int i = 1; i < leagueShards.length; i++) { 33 | if (i >= 12) break; 34 | LeagueShard leagueShard = leagueShards[i]; 35 | String keyName = leagueShard.getKeys()[1]; 36 | if (keyName.isEmpty()) continue; 37 | options.add(new Command.Choice(keyName.toUpperCase(), leagueShard.name())); 38 | } 39 | return options; 40 | } 41 | 42 | @Override 43 | public String getHelp() { 44 | return COMMAND_DESCRIPTION; 45 | } 46 | 47 | @Override 48 | public String getName() { 49 | return COMMAND_NAME; 50 | } 51 | 52 | @Override 53 | public void execute(SlashCommandEvent event) { 54 | event.deferReply().queue(); 55 | 56 | String summonerName = event.optString("summoner-name"); 57 | String region = event.optString("region"); 58 | 59 | final Summoner summonerData = SummonerUtils.getSummonerByName(summonerName, LeagueShard.valueOf(region)); 60 | 61 | if (summonerData == null) { 62 | event.getHook().editOriginal(String.format("%s That summoner couldn't be found, at least on that region.", EmojiUtils.Discord.X)).queue(); 63 | return; 64 | } 65 | 66 | Document existUserProfile = MongoDB.userProfileExists(event.getUser().getIdLong()).first(); 67 | if (existUserProfile == null) { 68 | MongoDB.addUserProfile(event.getUser().getIdLong(), summonerData.getName(), region); 69 | event.getHook().editOriginal(String.format("%s The summoner (`%s`, `%s`) added to the database.", EmojiUtils.Discord.CHECK, summonerData.getName(), region)).queue(); 70 | } else { 71 | event.getHook().editOriginal(String.format("%s You already have a summoner in the database, use `/summoner remove` to update it.", EmojiUtils.Discord.X)).queue(); 72 | } 73 | 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/summoner/CurrentSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.summoner; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import me.fabriziocoder.database.MongoDB; 6 | import me.fabriziocoder.luxanna.utils.ChampionUtils; 7 | import me.fabriziocoder.luxanna.utils.EmojiUtils; 8 | import me.fabriziocoder.luxanna.utils.SummonerUtils; 9 | import net.dv8tion.jda.api.EmbedBuilder; 10 | import net.dv8tion.jda.api.interactions.commands.Command; 11 | import net.dv8tion.jda.api.interactions.commands.OptionType; 12 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 13 | import no.stelar7.api.r4j.basic.constants.api.regions.LeagueShard; 14 | import no.stelar7.api.r4j.basic.constants.types.lol.TeamType; 15 | import no.stelar7.api.r4j.pojo.lol.spectator.SpectatorGameInfo; 16 | import no.stelar7.api.r4j.pojo.lol.summoner.Summoner; 17 | import org.bson.Document; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | public class CurrentSubCommand extends SlashCommand { 23 | 24 | public static final String COMMAND_NAME = "current"; 25 | public static final String COMMAND_DESCRIPTION = "Get the current game of a summoner"; 26 | 27 | public CurrentSubCommand() { 28 | this.name = COMMAND_NAME; 29 | this.help = COMMAND_DESCRIPTION; 30 | this.cooldown = 30; 31 | this.options = List.of(new OptionData(OptionType.STRING, "summoner-name", "The name of the summoner to search for").setRequired(false), new OptionData(OptionType.STRING, "region", "The region of the account").addChoices(regionChoices()).setRequired(false)); 32 | } 33 | 34 | private List regionChoices() { 35 | List options = new ArrayList<>(); 36 | LeagueShard[] leagueShards = LeagueShard.values(); 37 | for (int i = 1; i < leagueShards.length; i++) { 38 | if (i >= 12) break; 39 | LeagueShard leagueShard = leagueShards[i]; 40 | String keyName = leagueShard.getKeys()[1]; 41 | if (keyName.isEmpty()) continue; 42 | options.add(new Command.Choice(keyName.toUpperCase(), leagueShard.name())); 43 | } 44 | return options; 45 | } 46 | 47 | @Override 48 | public String getHelp() { 49 | return COMMAND_DESCRIPTION; 50 | } 51 | 52 | @Override 53 | public String getName() { 54 | return COMMAND_NAME; 55 | } 56 | 57 | @Override 58 | public void execute(SlashCommandEvent event) { 59 | event.deferReply().queue(); 60 | 61 | String summonerName = event.optString("summoner-name"); 62 | String region = event.optString("region"); 63 | if (summonerName == null && region == null) { 64 | Document existUserProfile = MongoDB.userProfileExists(event.getUser().getIdLong()).first(); 65 | if (existUserProfile != null) { 66 | summonerName = existUserProfile.getString("summonerName"); 67 | region = existUserProfile.getString("summonerPlatform"); 68 | } else { 69 | event.getHook().editOriginal(String.format("%s You don't yet have an account registered to use the no-argument command.", EmojiUtils.Discord.X)).queue(); 70 | return; 71 | } 72 | } else if (summonerName == null) { 73 | event.getHook().editOriginal(String.format("%s You need to specify a summoner name.", EmojiUtils.Discord.X)).queue(); 74 | return; 75 | } else if (region == null) { 76 | event.getHook().editOriginal(String.format("%s You need to specify a region.", EmojiUtils.Discord.X)).queue(); 77 | return; 78 | } 79 | 80 | final Summoner summonerData = SummonerUtils.getSummonerByName(summonerName, LeagueShard.valueOf(region)); 81 | 82 | 83 | if (summonerData == null) { 84 | event.getHook().editOriginal(String.format("%s That summoner couldn't be found, at least on that region.", EmojiUtils.Discord.X)).queue(); 85 | return; 86 | } 87 | 88 | SpectatorGameInfo summonerCurrentGame = summonerData.getCurrentGame(); 89 | if (summonerCurrentGame == null) { 90 | event.getHook().editOriginal(String.format("%s That summoner is not currently in a game.", EmojiUtils.Discord.X)).queue(); 91 | return; 92 | } 93 | 94 | EmbedBuilder messageEmbed = new EmbedBuilder().setColor(0x2564f4).setThumbnail(SummonerUtils.makeProfileIconURL(String.valueOf(summonerData.getProfileIconId()))).setAuthor("Current match").setTitle(String.format("`%s` - `%s`", summonerData.getName(), summonerData.getPlatform().prettyName())); 95 | 96 | String[] gameInformation = {String.format("`Map:` %s", summonerCurrentGame.getMap().prettyName()), String.format("`Game mode:` %s", summonerCurrentGame.getGameMode().prettyName()), String.format("`Game type:` %s", summonerCurrentGame.getGameType().prettyName()), String.format("`Queue type:` %s", summonerCurrentGame.getGameQueueConfig().prettyName()), String.format("`Game started:` ", summonerCurrentGame.getGameStart() / 1000)}; 97 | messageEmbed.addField("> Match infomation", String.join("\n", gameInformation), false); 98 | 99 | if (!summonerCurrentGame.getBannedChampions().isEmpty()) { 100 | StringBuilder bannedChampionsByBlueTeam = new StringBuilder(); 101 | StringBuilder bannedChampionsByRedTeam = new StringBuilder(); 102 | 103 | for (int i = 0; i < summonerCurrentGame.getBannedChampions().size(); i++) { 104 | if (!(summonerCurrentGame.getBannedChampions().get(i).getChampionId() == -1)) { 105 | int teamId = summonerCurrentGame.getBannedChampions().get(i).getTeamId(); 106 | String championName = ChampionUtils.getChampionNameById(summonerCurrentGame.getBannedChampions().get(i).getChampionId()); 107 | switch (teamId) { 108 | case 100 -> 109 | bannedChampionsByBlueTeam.append(String.format("%s %s ", EmojiUtils.getChampionEmojiByChampionName(championName), championName)); 110 | case 200 -> 111 | bannedChampionsByRedTeam.append(String.format("%s %s ", EmojiUtils.getChampionEmojiByChampionName(championName), championName)); 112 | } 113 | } 114 | } 115 | 116 | String[] bannedChampions = {String.format("`Blue team:` %s", String.join("", bannedChampionsByBlueTeam)), String.format("`Red team:` %s", String.join(", ", bannedChampionsByRedTeam)),}; 117 | messageEmbed.addField("> Banned champions", String.join("\n", bannedChampions), false); 118 | } 119 | 120 | StringBuilder blueTeamParticipants = new StringBuilder(); 121 | StringBuilder redTeamParticipants = new StringBuilder(); 122 | 123 | for (int i = 0; i < summonerCurrentGame.getParticipants().size(); i++) { 124 | TeamType teamType = summonerCurrentGame.getParticipants().get(i).getTeam(); 125 | String championName = ChampionUtils.getChampionNameById(summonerCurrentGame.getParticipants().get(i).getChampionId()); 126 | String summonerNameInCurrentGame = summonerCurrentGame.getParticipants().get(i).getSummonerName(); 127 | boolean isThisSummoner = summonerCurrentGame.getParticipants().get(i).getSummonerId().equals(summonerData.getSummonerId()); 128 | switch (teamType) { 129 | case BLUE -> 130 | blueTeamParticipants.append(String.format("%s | %s%s%s\n", EmojiUtils.getChampionEmojiByChampionName(championName), isThisSummoner ? "__**" : "", summonerNameInCurrentGame, isThisSummoner ? "**__" : "")); 131 | case RED -> 132 | redTeamParticipants.append(String.format("%s | %s%s%s\n", EmojiUtils.getChampionEmojiByChampionName(championName), isThisSummoner ? "__**" : "", summonerNameInCurrentGame, isThisSummoner ? "**__" : "")); 133 | } 134 | } 135 | 136 | 137 | messageEmbed.addField("> Blue team", String.join("", blueTeamParticipants), true); 138 | messageEmbed.addField("> Red team", String.join("", redTeamParticipants), true); 139 | messageEmbed.setFooter("Vote for me | https://top.gg/bot/949565943275720736/vote"); 140 | 141 | event.getHook().sendMessageEmbeds(messageEmbed.build()).queue(); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/summoner/LastMatchSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.summoner; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import me.fabriziocoder.database.MongoDB; 6 | import me.fabriziocoder.luxanna.utils.ChampionUtils; 7 | import me.fabriziocoder.luxanna.utils.EmojiUtils; 8 | import me.fabriziocoder.luxanna.utils.SummonerUtils; 9 | import net.dv8tion.jda.api.EmbedBuilder; 10 | import net.dv8tion.jda.api.interactions.commands.Command; 11 | import net.dv8tion.jda.api.interactions.commands.OptionType; 12 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 13 | import no.stelar7.api.r4j.basic.constants.api.regions.LeagueShard; 14 | import no.stelar7.api.r4j.basic.constants.types.lol.TeamType; 15 | import no.stelar7.api.r4j.impl.lol.builders.matchv5.match.MatchBuilder; 16 | import no.stelar7.api.r4j.pojo.lol.match.v5.LOLMatch; 17 | import no.stelar7.api.r4j.pojo.lol.match.v5.MatchParticipant; 18 | import no.stelar7.api.r4j.pojo.lol.match.v5.MatchTeam; 19 | import no.stelar7.api.r4j.pojo.lol.summoner.Summoner; 20 | import org.bson.Document; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | public class LastMatchSubCommand extends SlashCommand { 26 | 27 | public static final String COMMAND_NAME = "lastmatch"; 28 | public static final String COMMAND_DESCRIPTION = "Get the last match of a summoner"; 29 | 30 | public LastMatchSubCommand() { 31 | this.name = COMMAND_NAME; 32 | this.help = COMMAND_DESCRIPTION; 33 | this.cooldown = 15; 34 | this.options = List.of(new OptionData(OptionType.STRING, "summoner-name", "The name of the summoner to search for").setRequired(false), new OptionData(OptionType.STRING, "region", "The region of the account").addChoices(regionChoices()).setRequired(false)); 35 | } 36 | 37 | private List regionChoices() { 38 | List options = new ArrayList<>(); 39 | LeagueShard[] leagueShards = LeagueShard.values(); 40 | for (int i = 1; i < leagueShards.length; i++) { 41 | if (i >= 12) break; 42 | LeagueShard leagueShard = leagueShards[i]; 43 | String keyName = leagueShard.getKeys()[1]; 44 | if (keyName.isEmpty()) continue; 45 | options.add(new Command.Choice(keyName.toUpperCase(), leagueShard.name())); 46 | } 47 | return options; 48 | } 49 | 50 | @Override 51 | public String getHelp() { 52 | return COMMAND_DESCRIPTION; 53 | } 54 | 55 | @Override 56 | public String getName() { 57 | return COMMAND_NAME; 58 | } 59 | 60 | @Override 61 | public void execute(SlashCommandEvent event) { 62 | event.deferReply().queue(); 63 | 64 | String summonerName = event.optString("summoner-name"); 65 | String region = event.optString("region"); 66 | if (summonerName == null && region == null) { 67 | Document existUserProfile = MongoDB.userProfileExists(event.getUser().getIdLong()).first(); 68 | if (existUserProfile != null) { 69 | summonerName = existUserProfile.getString("summonerName"); 70 | region = existUserProfile.getString("summonerPlatform"); 71 | } else { 72 | event.getHook().editOriginal(String.format("%s You don't yet have an account registered to use the no-argument command.", EmojiUtils.Discord.X)).queue(); 73 | return; 74 | } 75 | } else if (summonerName == null) { 76 | event.getHook().editOriginal(String.format("%s You need to specify a summoner name.", EmojiUtils.Discord.X)).queue(); 77 | return; 78 | } else if (region == null) { 79 | event.getHook().editOriginal(String.format("%s You need to specify a region.", EmojiUtils.Discord.X)).queue(); 80 | return; 81 | } 82 | 83 | final Summoner summonerData = SummonerUtils.getSummonerByName(summonerName, LeagueShard.valueOf(region)); 84 | 85 | if (summonerData == null) { 86 | event.getHook().editOriginal(String.format("%s That summoner couldn't be found, at least on that region.", EmojiUtils.Discord.X)).queue(); 87 | return; 88 | } 89 | 90 | String matchId = summonerData.getLeagueGames().getLazy().get(0); 91 | if (matchId == null) { 92 | event.getHook().editOriginal(String.format("%s That summoner hasn't played any games yet.", EmojiUtils.Discord.X)).queue(); 93 | return; 94 | } 95 | 96 | LOLMatch summonerLastMatch = new MatchBuilder(summonerData.getPlatform()).withId(matchId).getMatch(); 97 | 98 | EmbedBuilder messageEmbed = new EmbedBuilder().setAuthor("Last match").setThumbnail(SummonerUtils.makeProfileIconURL(String.valueOf(summonerData.getProfileIconId()))); 99 | 100 | String[] matchInformation = {String.format("`Map:` %s", summonerLastMatch.getMap().prettyName()), String.format("`Queue type:` %s", summonerLastMatch.getQueue().prettyName()), String.format("`Game start:` ", summonerLastMatch.getGameStartTimestamp() / 1000), String.format("`Game end:` ", summonerLastMatch.getGameEndTimestamp() / 1000)}; 101 | messageEmbed.addField("> Match information", String.join("\n", matchInformation), false); 102 | 103 | StringBuilder blueTeamBans = new StringBuilder(); 104 | StringBuilder redTeamBans = new StringBuilder(); 105 | 106 | List matchTeams = summonerLastMatch.getTeams(); 107 | for (MatchTeam matchTeam : matchTeams) { 108 | if (matchTeam.getBans().isEmpty()) break; 109 | for (int i = 0; i < matchTeam.getBans().size(); i++) { 110 | int teamBansSize = matchTeam.getBans().size(); 111 | if (teamBansSize > 0) { 112 | if (!(matchTeam.getBans().get(i).getChampionId() == -1)) { 113 | String championName = ChampionUtils.getChampionNameById(matchTeam.getBans().get(i).getChampionId()); 114 | switch (matchTeam.getTeamId()) { 115 | case BLUE -> 116 | blueTeamBans.append(String.format("%s %s ", EmojiUtils.getChampionEmojiByChampionName(championName), championName)); 117 | case RED -> 118 | redTeamBans.append(String.format("%s %s ", EmojiUtils.getChampionEmojiByChampionName(championName), championName)); 119 | } 120 | } 121 | } else { 122 | break; 123 | } 124 | } 125 | } 126 | 127 | if (!blueTeamBans.isEmpty() && !redTeamBans.isEmpty()) { 128 | String[] bannedChampions = {String.format("`Blue team:` %s", String.join("", blueTeamBans)), String.format("`Red team:` %s", String.join(", ", redTeamBans)),}; 129 | messageEmbed.addField("> Banned champions", String.join("\n", bannedChampions), false); 130 | } 131 | 132 | StringBuilder blueTeamParticipants = new StringBuilder(); 133 | StringBuilder redTeamParticipants = new StringBuilder(); 134 | 135 | boolean didWin = false; 136 | for (int i = 0; i < summonerLastMatch.getParticipants().size(); i++) { 137 | TeamType teamType = summonerLastMatch.getParticipants().get(i).getTeam(); 138 | String championName = ChampionUtils.getChampionNameById(summonerLastMatch.getParticipants().get(i).getChampionId()); 139 | MatchParticipant participant = summonerLastMatch.getParticipants().get(i); 140 | 141 | if (participant.getSummonerId().equals(summonerData.getSummonerId())) { 142 | didWin = participant.didWin(); 143 | } 144 | 145 | int summonerKills = participant.getKills(); 146 | int summonerDeaths = participant.getDeaths(); 147 | int summonerAssists = participant.getAssists(); 148 | int totalCS = participant.getTotalMinionsKilled() + participant.getNeutralMinionsKilled(); 149 | String formattedTotalSummonerStats = String.format("(**%s**/**%s**/**%s**, **%s CS**)", summonerKills, summonerDeaths, summonerAssists, totalCS); 150 | boolean isThisSummoner = summonerLastMatch.getParticipants().get(i).getSummonerId().equals(summonerData.getSummonerId()); 151 | switch (teamType) { 152 | case BLUE -> 153 | blueTeamParticipants.append(String.format("%s | %s%s%s %s\n", EmojiUtils.getChampionEmojiByChampionName(championName), isThisSummoner ? "__**" : "", championName, isThisSummoner ? "**__" : "", formattedTotalSummonerStats)); 154 | case RED -> 155 | redTeamParticipants.append(String.format("%s | %s%s%s %s\n", EmojiUtils.getChampionEmojiByChampionName(championName), isThisSummoner ? "__**" : "", championName, isThisSummoner ? "**__" : "", formattedTotalSummonerStats)); 156 | } 157 | } 158 | 159 | messageEmbed.setTitle(String.format("`%s` - `%s` - `%s`", summonerData.getName(), summonerData.getPlatform().prettyName(), didWin ? "Victory" : "Defeat")).addField("> Blue team", String.join("", blueTeamParticipants), true).addField("> Red team", String.join("", redTeamParticipants), true).setColor(didWin ? 0x2564f4 : 0xff2424); 160 | messageEmbed.setFooter("Vote for me | https://top.gg/bot/949565943275720736/vote"); 161 | event.getHook().sendMessageEmbeds(messageEmbed.build()).queue(); 162 | 163 | 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/summoner/ProfileSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.summoner; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import me.fabriziocoder.database.MongoDB; 6 | import me.fabriziocoder.luxanna.utils.ChampionUtils; 7 | import me.fabriziocoder.luxanna.utils.EmojiUtils; 8 | import me.fabriziocoder.luxanna.utils.SummonerUtils; 9 | import net.dv8tion.jda.api.EmbedBuilder; 10 | import net.dv8tion.jda.api.interactions.commands.Command; 11 | import net.dv8tion.jda.api.interactions.commands.OptionType; 12 | import net.dv8tion.jda.api.interactions.commands.build.OptionData; 13 | import no.stelar7.api.r4j.basic.constants.api.regions.LeagueShard; 14 | import no.stelar7.api.r4j.basic.constants.types.lol.GameQueueType; 15 | import no.stelar7.api.r4j.impl.lol.builders.matchv5.match.MatchBuilder; 16 | import no.stelar7.api.r4j.pojo.lol.championmastery.ChampionMastery; 17 | import no.stelar7.api.r4j.pojo.lol.league.LeagueEntry; 18 | import no.stelar7.api.r4j.pojo.lol.match.v5.LOLMatch; 19 | import no.stelar7.api.r4j.pojo.lol.match.v5.MatchParticipant; 20 | import no.stelar7.api.r4j.pojo.lol.summoner.Summoner; 21 | import org.bson.Document; 22 | 23 | import java.text.DecimalFormat; 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | 27 | 28 | public class ProfileSubCommand extends SlashCommand { 29 | 30 | public static final String COMMAND_NAME = "profile"; 31 | public static final String COMMAND_DESCRIPTION = "Summoner profile with ranks, champions, last game, etc"; 32 | 33 | private static final DecimalFormat oneDecimal = new DecimalFormat("0.0"); 34 | 35 | public ProfileSubCommand() { 36 | this.name = COMMAND_NAME; 37 | this.help = COMMAND_DESCRIPTION; 38 | this.cooldown = 15; 39 | this.options = List.of(new OptionData(OptionType.STRING, "summoner-name", "The name of the summoner to search for").setRequired(false), new OptionData(OptionType.STRING, "region", "The region of the account").addChoices(regionChoices()).setRequired(false)); 40 | } 41 | 42 | public static String capitalize(String str) { 43 | if (str == null || str.length() <= 1) return str; 44 | return str.substring(0, 1).toUpperCase() + str.substring(1); 45 | } 46 | 47 | public static String humanReadableInt(long number) { 48 | long absNumber = Math.abs(number); 49 | double result; 50 | String suffix = ""; 51 | if (absNumber < 1024) { 52 | result = number; 53 | } else if (absNumber < 1024 * 1024) { 54 | result = number / 1024.0; 55 | suffix = "K"; 56 | } else if (absNumber < 1024 * 1024 * 1024) { 57 | result = number / (1024.0 * 1024); 58 | suffix = "M"; 59 | } else { 60 | result = number / (1024.0 * 1024 * 1024); 61 | suffix = "B"; 62 | } 63 | return oneDecimal.format(result) + suffix; 64 | } 65 | 66 | private List regionChoices() { 67 | List options = new ArrayList<>(); 68 | LeagueShard[] leagueShards = LeagueShard.values(); 69 | for (int i = 1; i < leagueShards.length; i++) { 70 | if (i >= 12) break; 71 | LeagueShard leagueShard = leagueShards[i]; 72 | String keyName = leagueShard.getKeys()[1]; 73 | if (keyName.isEmpty()) continue; 74 | options.add(new Command.Choice(keyName.toUpperCase(), leagueShard.name())); 75 | } 76 | return options; 77 | } 78 | 79 | @Override 80 | public String getHelp() { 81 | return COMMAND_DESCRIPTION; 82 | } 83 | 84 | @Override 85 | public String getName() { 86 | return COMMAND_NAME; 87 | } 88 | 89 | @Override 90 | public void execute(SlashCommandEvent event) { 91 | event.deferReply().queue(); 92 | 93 | String summonerName = event.optString("summoner-name"); 94 | String region = event.optString("region"); 95 | if (summonerName == null && region == null) { 96 | Document existUserProfile = MongoDB.userProfileExists(event.getUser().getIdLong()).first(); 97 | if (existUserProfile != null) { 98 | summonerName = existUserProfile.getString("summonerName"); 99 | region = existUserProfile.getString("summonerPlatform"); 100 | } else { 101 | event.getHook().editOriginal(String.format("%s You don't yet have an account registered to use the no-argument command.", EmojiUtils.Discord.X)).queue(); 102 | return; 103 | } 104 | } else if (summonerName == null) { 105 | event.getHook().editOriginal(String.format("%s You need to specify a summoner name.", EmojiUtils.Discord.X)).queue(); 106 | return; 107 | } else if (region == null) { 108 | event.getHook().editOriginal(String.format("%s You need to specify a region.", EmojiUtils.Discord.X)).queue(); 109 | return; 110 | } 111 | 112 | final Summoner summonerData = SummonerUtils.getSummonerByName(summonerName, LeagueShard.valueOf(region)); 113 | 114 | 115 | if (summonerData == null) { 116 | event.getHook().editOriginal(String.format("%s That summoner couldn't be found, at least on that region.", EmojiUtils.Discord.X)).queue(); 117 | return; 118 | } 119 | 120 | 121 | final List summonerTopChampions = SummonerUtils.getSummonerTopChampionsSummonerId(summonerData.getSummonerId(), LeagueShard.valueOf(region), 3); 122 | final List summonerLeagueEntries = SummonerUtils.getSummonerLeagueEntryBySummonerId(summonerData.getSummonerId(), LeagueShard.valueOf(region)); 123 | // final List summonerRecentThreeMatches = MatchUtils.getSummonerThreeRecentGames(summonerData); 124 | 125 | 126 | // Make embedBuilder 127 | final EmbedBuilder messageEmbed = new EmbedBuilder().setColor(0x2564f4).setThumbnail(SummonerUtils.makeProfileIconURL(String.valueOf(summonerData.getProfileIconId()))).setTitle(String.format("%s Profile", event.getJDA().getSelfUser().getName())); 128 | 129 | String[] summonerBasicInformation = {String.format("`Name:` %s", summonerData.getName()), String.format("`Level:` %s", summonerData.getSummonerLevel()), String.format("`Platform:` %s", summonerData.getPlatform().prettyName()), String.format("`Icon URL:` [View here](%s)", SummonerUtils.makeProfileIconURL(String.valueOf(summonerData.getProfileIconId())))}; 130 | messageEmbed.addField("> Basic Information", String.join("\n", summonerBasicInformation), true); 131 | 132 | // Top Mastery Champions for the Summoner 133 | if (summonerTopChampions == null) { 134 | messageEmbed.addField("> Top 3 Champions", "This summoner has not played champions", true); 135 | } else { 136 | StringBuilder summonerTopChampionsText = new StringBuilder(); 137 | for (int i = 0; i < summonerTopChampions.size(); i++) { 138 | ChampionMastery championMastery = summonerTopChampions.get(i); 139 | String championName = ChampionUtils.getChampionNameById(championMastery.getChampionId()); 140 | summonerTopChampionsText.append(String.format("`%d.` %s %s (Level %s, **%s**)\n", i + 1, EmojiUtils.getChampionEmojiByChampionName(championName), championName, championMastery.getChampionLevel(), humanReadableInt(championMastery.getChampionPoints()))); 141 | } 142 | messageEmbed.addField(String.format("> Top %s Champions", summonerTopChampions.size()), summonerTopChampionsText.toString(), true); 143 | } 144 | 145 | // Ranked stats for the Summoner 146 | if (summonerLeagueEntries == null) { 147 | messageEmbed.addField("> Ranked Stats", "This summoner has not played ranked games", false); 148 | } else { 149 | String soloQText = "*Unranked*"; 150 | String flexSRText = "*Unranked*"; 151 | String tftText = "*Unranked*"; 152 | 153 | for (final LeagueEntry entry : summonerLeagueEntries) { 154 | GameQueueType queue = entry.getQueueType(); 155 | 156 | switch (queue) { 157 | case RANKED_SOLO_5X5 -> 158 | soloQText = String.format("%s %s %s (**%s LP**) (**%s W** / **%s L**, %s", EmojiUtils.getRankEmojiByRankName(entry.getTier()), capitalize(entry.getTier().toLowerCase()), entry.getTierDivisionType().getDivision(), entry.getLeaguePoints(), entry.getWins(), entry.getLosses(), Math.round((entry.getWins() * 100d) / (entry.getWins() + entry.getLosses())) + "%)"); 159 | case RANKED_FLEX_SR -> 160 | flexSRText = String.format("%s %s %s (**%s LP**) (**%s W** / **%s L**, %s", EmojiUtils.getRankEmojiByRankName(entry.getTier()), capitalize(entry.getTier().toLowerCase()), entry.getTierDivisionType().getDivision(), entry.getLeaguePoints(), entry.getWins(), entry.getLosses(), Math.round((entry.getWins() * 100d) / (entry.getWins() + entry.getLosses())) + "%)"); 161 | case TEAMFIGHT_TACTICS_RANKED -> 162 | tftText = String.format("%s %s %s (**%s LP**) (**%s W** / **%s L**, %s", EmojiUtils.getRankEmojiByRankName(entry.getTier()), capitalize(entry.getTier().toLowerCase()), entry.getTierDivisionType().getDivision(), entry.getLeaguePoints(), entry.getWins(), entry.getLosses(), Math.round((entry.getWins() * 100d) / (entry.getWins() + entry.getLosses())) + "%)"); 163 | } 164 | } 165 | String[] summonerRankedStatsText = {String.format("`Solo/Duo:` %s", soloQText), String.format("`Flex SR:` %s", flexSRText), String.format("`TFT:` %s", tftText)}; 166 | messageEmbed.addField("> Ranked Stats", String.join("\n", summonerRankedStatsText), false); 167 | } 168 | 169 | // Recent Matches for the Summoner 170 | List recentGamesId = summonerData.getLeagueGames().get(); 171 | if (recentGamesId.size() == 0) { 172 | messageEmbed.addField("> Recent Matches", "This summoner has not played any matches", false); 173 | } else { 174 | StringBuilder summonerRecentMatchesText = new StringBuilder(); 175 | MatchBuilder matchBuilder = new MatchBuilder(summonerData.getPlatform()); 176 | 177 | for (int i = 0; i < recentGamesId.size(); i++) { 178 | if (i >= 3) break; 179 | LOLMatch matchData = matchBuilder.withId(recentGamesId.get(i)).getMatch(); 180 | 181 | for (final MatchParticipant matchParticipant : matchData.getParticipants()) { 182 | if (matchParticipant.getSummonerId().equals(summonerData.getSummonerId())) { 183 | summonerRecentMatchesText.append(String.format("`%d.` %s %s %s ()\n", i + 1, matchParticipant.didWin() ? EmojiUtils.Discord.CHECK : EmojiUtils.Discord.X, EmojiUtils.getChampionEmojiByChampionName(matchParticipant.getChampionName()), ChampionUtils.normalizeChampionName(matchParticipant.getChampionName()), (matchData.getGameStartTimestamp() / 1000) + matchParticipant.getTimePlayed())); 184 | } 185 | } 186 | } 187 | messageEmbed.addField("> Recent Matches", summonerRecentMatchesText.toString(), false); 188 | } 189 | 190 | messageEmbed.setFooter("Vote for me | https://top.gg/bot/949565943275720736/vote"); 191 | 192 | event.getHook().sendMessageEmbeds(messageEmbed.build()).queue(); 193 | 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/summoner/RemoveSubCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.summoner; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | import me.fabriziocoder.database.MongoDB; 6 | import me.fabriziocoder.luxanna.utils.EmojiUtils; 7 | import org.bson.Document; 8 | 9 | public class RemoveSubCommand extends SlashCommand { 10 | public static final String COMMAND_NAME = "remove"; 11 | public static final String COMMAND_DESCRIPTION = "Remove a summoner from the database, so it won't be automatically looked up"; 12 | 13 | public RemoveSubCommand() { 14 | this.name = COMMAND_NAME; 15 | this.help = COMMAND_DESCRIPTION; 16 | this.cooldown = 15; 17 | } 18 | 19 | @Override 20 | public String getHelp() { 21 | return COMMAND_DESCRIPTION; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return COMMAND_NAME; 27 | } 28 | 29 | @Override 30 | public void execute(SlashCommandEvent event) { 31 | event.deferReply().queue(); 32 | Document existUserProfile = MongoDB.userProfileExists(event.getUser().getIdLong()).first(); 33 | if (existUserProfile == null) { 34 | event.getHook().editOriginal(String.format("%s You don't have a summoner in the database, use `/summoner add` to add it.", EmojiUtils.Discord.X)).queue(); 35 | return; 36 | } 37 | MongoDB.removeUserProfile(event.getUser().getIdLong()); 38 | event.getHook().editOriginal(String.format("%s Your account has been removed from the database.", EmojiUtils.Discord.CHECK)).queue(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/commands/league/summoner/SummonerCommand.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.commands.league.summoner; 2 | 3 | import com.jagrosh.jdautilities.command.SlashCommand; 4 | import com.jagrosh.jdautilities.command.SlashCommandEvent; 5 | 6 | public class SummonerCommand extends SlashCommand { 7 | 8 | public SummonerCommand() { 9 | this.name = "summoner"; 10 | this.help = "[LoL] Summoner commands"; 11 | this.category = new Category("Summoner"); 12 | this.children = new SlashCommand[]{new ProfileSubCommand(), new CurrentSubCommand(), new LastMatchSubCommand(), new AddSubCommand(), new RemoveSubCommand()}; 13 | } 14 | 15 | @Override 16 | public void execute(SlashCommandEvent event) { 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/utils/ChampionUtils.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.utils; 2 | 3 | import com.merakianalytics.orianna.types.core.staticdata.Champion; 4 | 5 | public class ChampionUtils { 6 | public static String getChampionNameById(int championId) { 7 | return Champion.withId(championId).get().getName(); 8 | } 9 | 10 | public static String normalizeChampionName(String championName) { 11 | return championName.replace("LeeSin", "Lee Sin").replace("XinZhao", "Xin Zhao").replace("DrMundo", "Dr. Mundo").replace("JarvanIV", "Jarvan IV").replace("MasterYi", "Master Yi").replace("TahmKench", "Tahm Kench").replace("MissFortune", "Miss Fortune").replace("TwistedFate", "Twisted Fate").replace("RenataGlasc", "Renata Glasc").replace("Renata", "Renata Glasc").replace("AurelionSol", "Aurelion Sol"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/utils/EmojiUtils.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.utils; 2 | 3 | public class EmojiUtils { 4 | public static String getRankEmojiByRankName(String name) { 5 | String emoji = null; 6 | switch (name) { 7 | case "IRON" -> emoji = "<:IronLogo:949777641194549358>"; 8 | case "BRONZE" -> emoji = "<:BronzeLogo:949777641165180968>"; 9 | case "SILVER" -> emoji = "<:SilverLogo:949777641001586818>"; 10 | case "GOLD" -> emoji = "<:GoldLogo:949777640863203350>"; 11 | case "PLATINUM" -> emoji = "<:PlatiniumLogo:949777641039343676>"; 12 | case "DIAMOND" -> emoji = "<:DiamondLogo:949777640993226792>"; 13 | case "MASTER" -> emoji = "<:MasterLogo:949777640989003796>"; 14 | case "GRANDMASTER" -> emoji = "<:GrandMasterLogo:949777641060315176>"; 15 | case "CHALLENGER" -> emoji = "<:ChallengerLogo:949777641022570496>"; 16 | } 17 | return emoji; 18 | } 19 | 20 | public static String getChampionEmojiByChampionName(String name) { 21 | String emoji = null; 22 | switch (name) { 23 | case "None" -> emoji = "<:None:936101187533541466>"; 24 | case "Aatrox" -> emoji = "<:Aatrox:888534735498911844>"; 25 | case "Ahri" -> emoji = "<:Ahri:888534778175950868>"; 26 | case "Akali" -> emoji = "<:Akali:888534821104672778>"; 27 | case "Akshan" -> emoji = "<:Akshan:888534864079511672>"; 28 | case "Alistar" -> emoji = "<:Alistar:888534907037564928>"; 29 | case "Amumu" -> emoji = "<:Amumu:888534949681045536>"; 30 | case "Anivia" -> emoji = "<:Anivia:888534992999829564>"; 31 | case "Annie" -> emoji = "<:Annie:888535036016599100>"; 32 | case "Aphelios" -> emoji = "<:Aphelios:888535078911750185>"; 33 | case "Ashe" -> emoji = "<:Ashe:888535121651716136>"; 34 | case "Aurelion Sol" -> emoji = "<:AurelionSol:888535164517486662>"; 35 | case "AurelionSol" -> emoji = "<:AurelionSol:888535164517486662>"; 36 | case "Azir" -> emoji = "<:Azir:888535207567847424>"; 37 | case "Bard" -> emoji = "<:Bardo:888535250202939433>"; 38 | case "Bardo" -> emoji = "<:Bardo:888535250202939433>"; 39 | case "Bel'Veth" -> emoji = "<:BelVeth:994807834355191940>"; 40 | case "Blitzcrank" -> emoji = "<:Blitzcrank:888535293018406923>"; 41 | case "Brand" -> emoji = "<:Brand:888535336089714758>"; 42 | case "Braum" -> emoji = "<:Braum:888535378435387423>"; 43 | case "Caitlyn" -> emoji = "<:Caitlyn:888535421615763496>"; 44 | case "Camille" -> emoji = "<:Camille:888535464569622618>"; 45 | case "Cassiopeia" -> emoji = "<:Cassiopeia:888535507661889596>"; 46 | case "Cho'Gath" -> emoji = "<:ChoGath:888535550582206495>"; 47 | case "Corki" -> emoji = "<:Corki:888535593401872394>"; 48 | case "Darius" -> emoji = "<:Darius:888535636166979654>"; 49 | case "Diana" -> emoji = "<:Diana:888535679393472562>"; 50 | case "Draven" -> emoji = "<:Draven:888535722045374495>"; 51 | case "Dr. Mundo" -> emoji = "<:DrMundo:888535765150236712>"; 52 | case "DrMundo" -> emoji = "<:DrMundo:888535765150236712>"; 53 | case "Ekko" -> emoji = "<:Ekko:888535807827255307>"; 54 | case "Elise" -> emoji = "<:Elise:888535851112484935>"; 55 | case "Evelynn" -> emoji = "<:Evelynn:888535894041194606>"; 56 | case "Ezreal" -> emoji = "<:Ezreal:888535936638550067>"; 57 | case "Fiddlesticks" -> emoji = "<:Fiddlesticks:888535979688869898>"; 58 | case "Fiora" -> emoji = "<:Fiora:888536022575640656>"; 59 | case "Fizz" -> emoji = "<:Fizz:888536065944748112>"; 60 | case "Galio" -> emoji = "<:Galio:888536108982468679>"; 61 | case "Gangplank" -> emoji = "<:Gangplank:888536152406106172>"; 62 | case "Garen" -> emoji = "<:Garen:888536195510988800>"; 63 | case "Gnar" -> emoji = "<:Gnar:888536238775205979>"; 64 | case "Gragas" -> emoji = "<:Gragas:888536281896861807>"; 65 | case "Graves" -> emoji = "<:Graves:888536324699750412>"; 66 | case "Gwen" -> emoji = "<:Gwen:888536368094007337>"; 67 | case "Hecarim" -> emoji = "<:Hecarim:888536410871697458>"; 68 | case "Heimerdinger" -> emoji = "<:Heimerdinger:888536454358241291>"; 69 | case "Illaoi" -> emoji = "<:Illaoi:888536497387622562>"; 70 | case "Irelia" -> emoji = "<:Irelia:888536540693790750>"; 71 | case "Ivern" -> emoji = "<:Ivern:888536583626686504>"; 72 | case "Janna" -> emoji = "<:Janna:888536626270187532>"; 73 | case "Jarvan IV" -> emoji = "<:JarvanIV:888536669580587038>"; 74 | case "JarvanIV" -> emoji = "<:JarvanIV:888536669580587038>"; 75 | case "Jax" -> emoji = "<:Jax:888536711976587266>"; 76 | case "Jayce" -> emoji = "<:Jayce:888536755039522846>"; 77 | case "Jhin" -> emoji = "<:Jhin:888536798169550869>"; 78 | case "Jinx" -> emoji = "<:Jinx:888536841333125180>"; 79 | case "Kai'Sa" -> emoji = "<:KaiSa:888550808445132810>"; 80 | case "Kalista" -> emoji = "<:Kalista:888550851331887126>"; 81 | case "Karma" -> emoji = "<:Karma:888550894512250930>"; 82 | case "Karthus" -> emoji = "<:Karthus:888550937709404180>"; 83 | case "Kassadin" -> emoji = "<:Kassadin:888550980860403752>"; 84 | case "Katarina" -> emoji = "<:Katarina:888551023625502741>"; 85 | case "Kayle" -> emoji = "<:Kayle:888551066029948969>"; 86 | case "Kayn" -> emoji = "<:Kayn:888551108929290251>"; 87 | case "Kennen" -> emoji = "<:Kennen:888551152566820954>"; 88 | case "Kha'Zix" -> emoji = "<:KhaZix:888551195654885446>"; 89 | case "Kindred" -> emoji = "<:Kindred:888551238235463692>"; 90 | case "Kled" -> emoji = "<:Kled:888551281445183529>"; 91 | case "Kog'Maw" -> emoji = "<:KogMaw:888551324436791336>"; 92 | case "LeBlanc" -> emoji = "<:LeBlanc:888551367139033138>"; 93 | case "Lee Sin" -> emoji = "<:LeeSin:888551409983819776>"; 94 | case "Leona" -> emoji = "<:Leona:888551452715384852>"; 95 | case "Lillia" -> emoji = "<:Lillia:888551495400828970>"; 96 | case "Lissandra" -> emoji = "<:Lissandra:888551538572812328>"; 97 | case "Lucian" -> emoji = "<:Lucian:888551580968816732>"; 98 | case "Lulu" -> emoji = "<:Lulu:888551624077897738>"; 99 | case "Lux" -> emoji = "<:Lux:888551667585392670>"; 100 | case "Malphite" -> emoji = "<:Malphite:888551710715412480>"; 101 | case "Malzahar" -> emoji = "<:Malzahar:888551753669300305>"; 102 | case "Maokai" -> emoji = "<:Maokai:888551796107264011>"; 103 | case "Master Yi" -> emoji = "<:MaestroYi:888551839304405004>"; 104 | case "MasterYi" -> emoji = "<:MaestroYi:888551839304405004>"; 105 | case "Miss Fortune" -> emoji = "<:MissFortune:888551882677702717>"; 106 | case "MissFortune" -> emoji = "<:MissFortune:888551882677702717>"; 107 | case "Wukong" -> emoji = "<:Wukong:888551926042595369>"; 108 | case "Mordekaiser" -> emoji = "<:Mordekaiser:888551969235566652>"; 109 | case "Morgana" -> emoji = "<:Morgana:888552011920982017>"; 110 | case "Nami" -> emoji = "<:Nami:888552054941954118>"; 111 | case "Nasus" -> emoji = "<:Nasus:888552237146730536>"; 112 | case "Nautilus" -> emoji = "<:Nautilus:888552280280932392>"; 113 | case "Nilah" -> emoji = "<:Nilah:996917711068209265>"; 114 | case "Neeko" -> emoji = "<:Neeko:888552323113181244>"; 115 | case "Nidalee" -> emoji = "<:Nidalee:888552365924438016>"; 116 | case "Nocturne" -> emoji = "<:Nocturne:888552408580489267>"; 117 | case "Nunu & Willump" -> emoji = "<:Nunu:888552451626659922>"; 118 | case "Nunu" -> emoji = "<:Nunu:888552451626659922>"; 119 | case "Olaf" -> emoji = "<:Olaf:888552494467252226>"; 120 | case "Orianna" -> emoji = "<:Orianna:888552538247405580>"; 121 | case "Ornn" -> emoji = "<:Ornn:888552581163515906>"; 122 | case "Pantheon" -> emoji = "<:Pantheon:888552624939474985>"; 123 | case "Poppy" -> emoji = "<:Poppy:888552667817840651>"; 124 | case "Pyke" -> emoji = "<:Pyke:888552711044349963>"; 125 | case "Qiyana" -> emoji = "<:Qiyana:888552754002395186>"; 126 | case "Quinn" -> emoji = "<:Quinn:888552797098872862>"; 127 | case "Rakan" -> emoji = "<:Rakan:888552839905968128>"; 128 | case "Rammus" -> emoji = "<:Rammus:888552883266666546>"; 129 | case "Rek'Sai" -> emoji = "<:RekSai:888552925679484930>"; 130 | case "Rell" -> emoji = "<:Rell:888552968956293162>"; 131 | case "Renata Glasc" -> emoji = "<:RenataGlasc:1006260533168717894>"; 132 | case "RenataGlasc" -> emoji = "<:RenataGlasc:1006260533168717894>"; 133 | case "Renekton" -> emoji = "<:Renekton:888553011893391390>"; 134 | case "Rengar" -> emoji = "<:Rengar:888553054423629877>"; 135 | case "Riven" -> emoji = "<:Riven:888553348851175516>"; 136 | case "Rumble" -> emoji = "<:Rumble:888553392056696852>"; 137 | case "Ryze" -> emoji = "<:Ryze:888553435107053578>"; 138 | case "Samira" -> emoji = "<:Samira:888553477754716171>"; 139 | case "Sejuani" -> emoji = "<:Sejuani:888553520792481844>"; 140 | case "Senna" -> emoji = "<:Senna:888553563666673674>"; 141 | case "Seraphine" -> emoji = "<:Seraphine:888553606268190732>"; 142 | case "Sett" -> emoji = "<:Sett:888553649280778302>"; 143 | case "Shaco" -> emoji = "<:Shaco:888553692784103474>"; 144 | case "Shen" -> emoji = "<:Shen:888553735419211858>"; 145 | case "Shyvana" -> emoji = "<:Shyvana:888553778146590722>"; 146 | case "Singed" -> emoji = "<:Singed:888553821452767324>"; 147 | case "Sion" -> emoji = "<:Sion:888553864519880724>"; 148 | case "Sivir" -> emoji = "<:Sivir:888553907247284265>"; 149 | case "Skarner" -> emoji = "<:Skarner:888553949945270303>"; 150 | case "Sona" -> emoji = "<:Sona:888553992500682763>"; 151 | case "Soraka" -> emoji = "<:Soraka:888554037669167144>"; 152 | case "Swain" -> emoji = "<:Swain:888554080757239868>"; 153 | case "Sylas" -> emoji = "<:Sylas:888554123631419414>"; 154 | case "Syndra" -> emoji = "<:Syndra:888554167180861501>"; 155 | case "TahmKench" -> emoji = "<:TahmKench:888554210218631229>"; 156 | case "Tahm Kench" -> emoji = "<:TahmKench:888554210218631229>"; 157 | case "Taliyah" -> emoji = "<:Taliyah:888554253243805756>"; 158 | case "Talon" -> emoji = "<:Talon:888554296604508190>"; 159 | case "Taric" -> emoji = "<:Taric:888554339541590078>"; 160 | case "Teemo" -> emoji = "<:Teemo:888554382692581427>"; 161 | case "Thresh" -> emoji = "<:Thresh:888554425789063168>"; 162 | case "Tristana" -> emoji = "<:Tristana:888554468789063730>"; 163 | case "Trundle" -> emoji = "<:Trundle:888554511352885249>"; 164 | case "Tryndamere" -> emoji = "<:Tryndamere:888554554092830762>"; 165 | case "Twisted Fate" -> emoji = "<:TwistedFate:888554597298372708>"; 166 | case "TwistedFate" -> emoji = "<:TwistedFate:888554597298372708>"; 167 | case "Twitch" -> emoji = "<:Twitch:888554639908298763>"; 168 | case "Udyr" -> emoji = "<:Udyr:888554683369660477>"; 169 | case "Urgot" -> emoji = "<:Urgot:888554726638092328>"; 170 | case "Varus" -> emoji = "<:Varus:888554769524863036>"; 171 | case "Vayne" -> emoji = "<:Vayne:888554812520689695>"; 172 | case "Veigar" -> emoji = "<:Veigar:888554855457783850>"; 173 | case "Vel'Koz" -> emoji = "<:VelKoz:888554898373886003>"; 174 | case "Vex" -> emoji = "<:Vex:890700471805837352>"; 175 | case "Vi" -> emoji = "<:Vi:888554941164159008>"; 176 | case "Viego" -> emoji = "<:Viego:888554984512315422>"; 177 | case "Viktor" -> emoji = "<:Viktor:888555027537485854>"; 178 | case "Vladimir" -> emoji = "<:Vladimir:888555070285824071>"; 179 | case "Volibear" -> emoji = "<:Volibear:888555113000611920>"; 180 | case "Warwick" -> emoji = "<:Warwick:888555155744780298>"; 181 | case "Xayah" -> emoji = "<:Xayah:888555198698635294>"; 182 | case "Xerath" -> emoji = "<:Xerath:888555241514102794>"; 183 | case "Xin Zhao" -> emoji = "<:XinZhao:888555284354699284>"; 184 | case "XinZhao" -> emoji = "<:XinZhao:888555284354699284>"; 185 | case "Yasuo" -> emoji = "<:Yasuo:888555327367299082>"; 186 | case "Yone" -> emoji = "<:Yone:888555370220519445>"; 187 | case "Yorick" -> emoji = "<:Yorick:888555413837062176>"; 188 | case "Yuumi" -> emoji = "<:Yuumi:888555457382318150>"; 189 | case "Zac" -> emoji = "<:Zac:888555751948316702>"; 190 | case "Zed" -> emoji = "<:Zed:888555795170619394>"; 191 | case "Zeri" -> emoji = "<:Zeri:994813016245813248>"; 192 | case "Ziggs" -> emoji = "<:Ziggs:888555838497751070>"; 193 | case "Zilean" -> emoji = "<:Zilean:888555881267073035>"; 194 | case "Zoe" -> emoji = "<:Zoe:888555924652982282>"; 195 | case "Zyra" -> emoji = "<:Zyra:888555967594250290>"; 196 | } 197 | return emoji; 198 | } 199 | 200 | public enum Discord { 201 | CHECK("<:check_mark:1006378529916719134>"), X("<:x_:1006378538196279386>"); 202 | 203 | private final String text; 204 | 205 | Discord(final String text) { 206 | this.text = text; 207 | } 208 | 209 | @Override 210 | public String toString() { 211 | return text; 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/utils/MatchUtils.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.utils; 2 | 3 | import no.stelar7.api.r4j.impl.lol.builders.matchv5.match.MatchBuilder; 4 | import no.stelar7.api.r4j.pojo.lol.match.v5.LOLMatch; 5 | import no.stelar7.api.r4j.pojo.lol.match.v5.MatchParticipant; 6 | import no.stelar7.api.r4j.pojo.lol.summoner.Summoner; 7 | 8 | import javax.annotation.Nullable; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | 13 | public class MatchUtils { 14 | 15 | @Nullable 16 | public static MatchParticipant getSummonerLastMatchBySummoner(Summoner summoner) { 17 | 18 | MatchParticipant matchParticipant = null; 19 | String matchId = summoner.getLeagueGames().getLazy().get(0); 20 | 21 | if (matchId == null) { 22 | return null; 23 | } 24 | MatchBuilder matchBuilder = new MatchBuilder(summoner.getPlatform()); 25 | 26 | matchBuilder = matchBuilder.withId(matchId); 27 | for (final MatchParticipant participant : matchBuilder.getMatch().getParticipants()) { 28 | 29 | if (participant.getSummonerId().equals(summoner.getSummonerId())) { 30 | matchParticipant = participant; 31 | } 32 | } 33 | return matchParticipant; 34 | } 35 | 36 | @Nullable 37 | public static List getSummonerThreeRecentGames(Summoner summoner) { 38 | List recentGamesId = summoner.getLeagueGames().get(); 39 | if (recentGamesId.size() == 0) { 40 | return null; 41 | } 42 | MatchBuilder matchBuilder = new MatchBuilder(summoner.getPlatform()); 43 | List data = new ArrayList<>(); 44 | 45 | for (int i = 0; i < recentGamesId.size(); i++) { 46 | if (i >= 3) break; 47 | LOLMatch match = matchBuilder.withId(recentGamesId.get(i)).getMatch(); 48 | for (final MatchParticipant participant : match.getParticipants()) { 49 | if (participant.getSummonerId().equals(summoner.getSummonerId())) { 50 | data.add(participant); 51 | } 52 | } 53 | } 54 | return data; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/me/fabriziocoder/luxanna/utils/SummonerUtils.java: -------------------------------------------------------------------------------- 1 | package me.fabriziocoder.luxanna.utils; 2 | 3 | import com.merakianalytics.orianna.types.common.Region; 4 | import com.merakianalytics.orianna.types.core.staticdata.Versions; 5 | import no.stelar7.api.r4j.basic.constants.api.regions.LeagueShard; 6 | import no.stelar7.api.r4j.impl.lol.builders.championmastery.ChampionMasteryBuilder; 7 | import no.stelar7.api.r4j.impl.lol.builders.league.LeagueBuilder; 8 | import no.stelar7.api.r4j.impl.lol.builders.summoner.SummonerBuilder; 9 | import no.stelar7.api.r4j.pojo.lol.championmastery.ChampionMastery; 10 | import no.stelar7.api.r4j.pojo.lol.league.LeagueEntry; 11 | import no.stelar7.api.r4j.pojo.lol.summoner.Summoner; 12 | 13 | import javax.annotation.Nullable; 14 | import java.util.List; 15 | 16 | public class SummonerUtils { 17 | @Nullable 18 | public static Summoner getSummonerByName(String summonerName, LeagueShard platform) { 19 | return new SummonerBuilder().withName(summonerName).withPlatform(platform).get(); 20 | } 21 | 22 | @Nullable 23 | public static List getSummonerTopChampionsSummonerId(String summonerId, LeagueShard platform, int count) { 24 | return new ChampionMasteryBuilder().withSummonerId(summonerId).withPlatform(platform).getTopChampions(count); 25 | } 26 | 27 | @Nullable 28 | public static List getSummonerLeagueEntryBySummonerId(String summonerId, LeagueShard platform) { 29 | return new LeagueBuilder().withSummonerId(summonerId).withPlatform(platform).getLeagueEntries(); 30 | } 31 | 32 | public static String getLatestVersion() { 33 | return Versions.withRegion(Region.NORTH_AMERICA).get().get(0); 34 | } 35 | 36 | public static String makeProfileIconURL(String iconId) { 37 | return "http://ddragon.leagueoflegends.com/cdn/" + getLatestVersion() + "/img/profileicon/" + iconId + ".png"; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Created-By: Apache Maven 3 | Main-Class: me.fabriziocoder.luxanna.Luxanna 4 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{HH:mm:ss.SSS} %boldCyan(%-34.-34thread) %red(%10.10X{jda.shard}) %boldGreen(%-15.-15logger{0}) 6 | %highlight(%-6level) %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | --------------------------------------------------------------------------------