From 50db0809994e607a83bd4d717f41b283622c2e51 Mon Sep 17 00:00:00 2001 From: Pingex Date: Fri, 27 May 2016 00:27:21 +0200 Subject: [PATCH] New command! /lol:currentgame let you see all details about a currently ongoing game. --- .../pingex/dbotm/LeagueOfDiscordModule.java | 159 +++++++++++++++++- 1 file changed, 157 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/pingex/dbotm/LeagueOfDiscordModule.java b/src/main/java/net/pingex/dbotm/LeagueOfDiscordModule.java index e40525a..37f1fbf 100644 --- a/src/main/java/net/pingex/dbotm/LeagueOfDiscordModule.java +++ b/src/main/java/net/pingex/dbotm/LeagueOfDiscordModule.java @@ -2,14 +2,24 @@ package net.pingex.dbotm; import com.robrua.orianna.api.core.RiotAPI; import com.robrua.orianna.type.core.champion.ChampionStatus; +import com.robrua.orianna.type.core.common.QueueType; import com.robrua.orianna.type.core.common.Region; +import com.robrua.orianna.type.core.common.Side; +import com.robrua.orianna.type.core.currentgame.CurrentGame; +import com.robrua.orianna.type.core.currentgame.MasteryRank; +import com.robrua.orianna.type.core.currentgame.Participant; +import com.robrua.orianna.type.core.league.League; import com.robrua.orianna.type.core.staticdata.Champion; +import com.robrua.orianna.type.core.staticdata.Mastery; +import com.robrua.orianna.type.core.summoner.Summoner; +import com.robrua.orianna.type.exception.APIException; import net.pingex.discordbot.AbstractModule; import net.pingex.discordbot.Command; import net.pingex.discordbot.Configuration; import net.pingex.discordbot.Controllable; import sx.blah.discord.api.IDiscordClient; import sx.blah.discord.handle.impl.events.MessageReceivedEvent; +import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.HTTP429Exception; import sx.blah.discord.util.MissingPermissionsException; @@ -19,8 +29,9 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.URL; -import java.util.ArrayList; -import java.util.Map; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.LongStream; /** * League of Discord, all the stuff related to League of Legends ! @@ -40,6 +51,21 @@ public class LeagueOfDiscordModule extends AbstractModule */ private static final int LSI_UNIT_HEIGHT = 560; + /** + * Time shift when spectating games (3 minutes) + */ + private static final int SPECTATE_TIMESHIFT = 180; + + /** + * All keystones ID. + */ + private static final long[] KEYSTONES_ID = {6161, 6162, 6164, 6361, 6362, 6363, 6261, 6262, 6263}; + + /** + * Time to wait when the Rate Limit has been reached. + */ + private static final int RATELIMIT_SLEEP = 5; + /** * Constructor doing all the basic stuff, like registering as a Listener to Discord, getting a logger, etc. * @param client Discord Client instance used to register self. @@ -73,6 +99,10 @@ public class LeagueOfDiscordModule extends AbstractModule } } + /** + * Returns this week F2P champs + * @return A list of the F2P champions, plus a picture with all the splash. + */ @Command(description = "Returns this week F2P champions.") public String fwr(MessageReceivedEvent event) { @@ -119,4 +149,129 @@ public class LeagueOfDiscordModule extends AbstractModule } return toReturn.toString(); } + + /** + * Tell cur game info for given player. + * @param summonerName Summoner username + * @return Text-based game info + */ + @Command(description = "Tell the current game info of given summoner", shorthand = "lolcur") + public String currentGame(MessageReceivedEvent event, String summonerName) throws HTTP429Exception, DiscordException, MissingPermissionsException, InterruptedException + { + IMessage loadingMessage = event.getMessage().getChannel().sendMessage("Fetching data from Riot API..."); + CurrentGame ginfo = null; + Summoner targetPlayer = null; + + // Data-fetching marathon + for(int i=1;; i++) + try + { + ginfo = RiotAPI.getCurrentGame(summonerName); + targetPlayer = RiotAPI.getSummonerByName(summonerName); + if(ginfo == null) return "Summoner is not in a game."; + else break; + } + catch (APIException e) + { + switch(e.getStatus()) + { + case NOT_FOUND: + return "Summoner not found."; + case RATE_LIMIT_EXCEEDED: + Thread.sleep(TimeUnit.SECONDS.toMillis(RATELIMIT_SLEEP)); + break; + case INTERNAL_SERVER_ERROR: + case SERVICE_UNAVAILABLE: + if(i>=5) return "Command failed. Please try again later."; + break; + default: + throw e; + } + } + + // General game info + StringBuffer sb = new StringBuffer("Current game info for " + targetPlayer.getName() + ": "); + String timeStarted = String.format("%d:%d", TimeUnit.SECONDS.toMinutes(ginfo.getLength()+SPECTATE_TIMESHIFT), ginfo.getLength()+SPECTATE_TIMESHIFT - TimeUnit.MINUTES.toSeconds(TimeUnit.SECONDS.toMinutes(ginfo.getLength()+SPECTATE_TIMESHIFT))); + sb.append(ginfo.getQueueType()).append(" started ").append(timeStarted).append(" ago.\n\n"); + + loadingMessage.edit("Game found. Fetching summoners data..."); + sb.append("Team Blue\n"); + boolean swapped = false; + for(Participant i : ginfo.getParticipants()) + { + if(i.getTeam().equals(Side.PURPLE) && !swapped) + { + sb.append("\nTeam Purple\n"); + swapped = true; + } + + // Summoner Name + Champ + sb.append("* ").append(i.getSummonerName()).append(" (").append(i.getChampion().getName()).append(") - "); + + // SoloQ Ranked stats + for(int count=1; count>0; count++) + try + { + for(League j : i.getSummoner().getLeagueEntries()) + if(j.getQueueType().equals(QueueType.RANKED_SOLO_5x5)) + { + sb.append(j.getTier().toString()).append(" ").append(j.getParticipantEntry().getDivision()); + count = -1; + break; + } + } + catch (APIException e) + { + switch(e.getStatus()) + { + case NOT_FOUND: // Silently ignore HTTP404 which is OK and means "Unranked" + sb.append("Unranked"); + count = -1; + break; + case RATE_LIMIT_EXCEEDED: + Thread.sleep(TimeUnit.SECONDS.toMillis(RATELIMIT_SLEEP)); + break; + case INTERNAL_SERVER_ERROR: + case SERVICE_UNAVAILABLE: + if(count>=5) sb.append("(Unavailable)"); + break; + default: + throw e; + } + } + sb.append(" - "); + + // Summoner Spells + sb.append(i.getSummonerSpell1().getName()).append("/").append(i.getSummonerSpell2()).append(" - "); + + // Masteries + Mastery keystone = null; + int ferocity = 0, cunning = 0, resolve = 0; + for(MasteryRank j : i.getMasteries()) // TODO: May crash ? Wait and see + { + if(LongStream.of(KEYSTONES_ID).anyMatch(x -> x == j.getMasteryID())) + keystone = j.getMastery(); + + switch(j.getMastery().getType()) + { + case Ferocity: + ferocity+=j.getRank(); + break; + case Cunning: + cunning+=j.getRank(); + break; + case Resolve: + resolve+=j.getRank(); + break; + } + } + sb.append("[").append(ferocity).append("/").append(cunning).append("/").append(resolve).append("] ") + .append(keystone != null ? keystone.getName() : "No keystone"); + + // Next guy + sb.append("\n"); + } + + return sb.toString(); + } } \ No newline at end of file