Search in sources :

Example 1 with Wiimmfi

use of com.gamebuster19901.excite.Wiimmfi in project ExciteBot by TheGameCommunity.

the class Wiimmfi method updateOnlinePlayers.

@SuppressWarnings({ "rawtypes", "unchecked" })
public Player[] updateOnlinePlayers() throws SQLException, WiimmfiResponseException {
    HashSet<Player> onlinePlayers = new HashSet<Player>();
    if (JSON != null) {
        JsonArray objects = null;
        JsonElement object1;
        HashMap<String, JsonElement> object1Entries = new HashMap<String, JsonElement>();
        if (JSON.isJsonArray()) {
            objects = JSON.getAsJsonArray();
            object1 = objects.get(0);
        } else {
            object1 = JSON;
        }
        for (Entry<String, JsonElement> e : object1.getAsJsonObject().entrySet()) {
            if (object1Entries.put(e.getKey(), e.getValue()) != null) {
                throw new WiimmfiResponseException("Duplicate key in json response:" + e.getKey());
            }
        }
        JsonElement typeJson = object1Entries.get("type");
        JsonElement identifyJson = object1Entries.get("identify");
        JsonElement gameJson = object1Entries.get("game_list");
        String type = null;
        String identify = null;
        String game = null;
        if (typeJson != null) {
            type = typeJson.getAsString();
        }
        if (type == null) {
            throw new WiimmfiResponseException("Unexpected response from wiimmfi api");
        }
        if (type.equals("error")) {
            JsonElement errorJson = object1Entries.get("error");
            JsonElement msgJson = object1Entries.get("msg");
            String error = null;
            String msg = null;
            if (errorJson != null) {
                error = errorJson.getAsString();
            } else {
                error = "No error type received from wiimmfi";
            }
            if (msgJson != null) {
                msg = msgJson.getAsString();
            }
            throw new WiimmfiErrorResponse(error + ": " + msg);
        }
        if (identifyJson != null) {
            identify = identifyJson.getAsString();
        }
        if (gameJson != null) {
            if (gameJson.getAsJsonArray().size() > 0) {
                game = gameJson.getAsJsonArray().get(0).getAsString();
            } else {
                throw new WiimmfiResponseException("No game data response");
            }
        }
        if (!"games".equals(identify)) {
            throw new WiimmfiResponseException("Unexpected response of type: " + identify);
        }
        if (!"exciteracewii".equals(game)) {
            throw new WiimmfiResponseException("Wiimmfi sent player list from incorrect game: " + game);
        }
        elementFinder: for (int i = 1; i < objects.size(); i++) {
            // should be safe to access w/o null check as it should error before now
            JsonElement obj = objects.get(i);
            HashMap<String, JsonElement> entries = new HashMap<String, JsonElement>();
            for (Entry<String, JsonElement> e : obj.getAsJsonObject().entrySet()) {
                if (entries.put(e.getKey(), e.getValue()) != null) {
                    throw new WiimmfiResponseException("Duplicate key in json response:" + e.getKey());
                }
            }
            if ("game-stats".equals(entries.get("type").getAsString())) {
                JsonArray playerList = entries.get("list").getAsJsonArray();
                for (JsonElement e : playerList) {
                    HashMap<String, JsonElement> playerDataEntries = new HashMap<String, JsonElement>();
                    for (Entry<String, JsonElement> e2 : e.getAsJsonObject().entrySet()) {
                        playerDataEntries.put(e2.getKey(), e2.getValue());
                    }
                    int pid = playerDataEntries.get("pid").getAsInt();
                    String fc = playerDataEntries.get("fc").getAsString();
                    int status = playerDataEntries.get("online_status").getAsInt();
                    int host = playerDataEntries.get("hoststate").getAsInt();
                    String name = playerDataEntries.get("name").getAsJsonArray().get(0).getAsString();
                    Player player = Player.getPlayerByID(ConsoleContext.INSTANCE, pid);
                    if (player instanceof UnknownPlayer) {
                        player = Player.addPlayer(new MessageContext(player), true, pid, fc, name);
                    } else {
                        player.setName(name);
                        player.setOnlineStatus(status);
                        player.setHost(host);
                    }
                    onlinePlayers.add(player);
                }
                ;
                break elementFinder;
            }
        }
    }
    for (Player player : onlinePlayers) {
        if (PREV_ONLINE_PLAYERS.contains(player)) {
            if (!(player.isPrivate() || player.isSearching() || player.isFriendsList())) {
                player.updateSecondsPlayed();
            }
            player.updateLastOnline();
        } else {
            LogInAudit.addLoginAudit(new MessageContext(player), player);
            player.updateLastOnline();
        }
        PREV_ONLINE_PLAYERS.remove(player);
    }
    for (Player player : PREV_ONLINE_PLAYERS) {
        LogOutAudit.addLogOutAudit(new MessageContext(player), player);
    }
    ONLINE_PLAYERS = onlinePlayers;
    PREV_ONLINE_PLAYERS = ONLINE_PLAYERS;
    return onlinePlayers.toArray(new Player[] {});
}
Also used : HashMap(java.util.HashMap) JsonArray(com.google.gson.JsonArray) WiimmfiResponseException(com.gamebuster19901.excite.exception.WiimmfiResponseException) Entry(java.util.Map.Entry) JsonElement(com.google.gson.JsonElement) MessageContext(com.gamebuster19901.excite.bot.command.MessageContext) WiimmfiErrorResponse(com.gamebuster19901.excite.exception.WiimmfiErrorResponse) HashSet(java.util.HashSet)

Example 2 with Wiimmfi

use of com.gamebuster19901.excite.Wiimmfi in project ExciteBot by TheGameCommunity.

the class WhoIsCommand method sendResponse.

@SuppressWarnings("serial")
public static int sendResponse(MessageContext context, String lookingFor) {
    if (context.isConsoleMessage() || context.isIngameEvent()) {
        context.sendMessage("You cannot execute this command as " + context.getEvent().getClass().getSimpleName());
        return 1;
    }
    Wiimmfi wiimmfi = Main.discordBot.getWiimmfi();
    EmbedBuilder embed = new EmbedBuilder();
    boolean hasMembers = context.isGuildMessage();
    if (wiimmfi.getError() == null) {
        if (!lookingFor.isEmpty()) {
            HashSet<DiscordUser> users = new HashSet<DiscordUser>() {

                {
                    this.addAll(Arrays.asList(DiscordUser.getDiscordUsersWithUsernameOrID(context, lookingFor)));
                }
            };
            HashSet<Player> players = new HashSet<Player>() {

                {
                    this.addAll(Arrays.asList(Player.getPlayersByAnyIdentifier(context, lookingFor)));
                }
            };
            HashSet<Named> matches = new HashSet<Named>();
            matches.addAll(users);
            matches.addAll(players);
            SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd HH:mm z", Locale.ENGLISH);
            if (matches.size() == 1) {
                Named match = matches.iterator().next();
                embed.setTitle("Information about " + match.getIdentifierName());
                if (match instanceof DiscordUser) {
                    DiscordUser user = (DiscordUser) match;
                    Member member;
                    embed.setColor(Color.WHITE);
                    Wii[] wiis = user.getRegisteredWiis();
                    Set<Player> profiles = user.getProfiles(context);
                    Duration timeOnline = Duration.ZERO;
                    Instant lastOnline = TimeUtils.PLAYER_EPOCH;
                    String profileList = "";
                    String wiiList = "";
                    for (Player profile : profiles) {
                        profileList = profileList + profile.toEmbedstring() + "\n";
                        timeOnline = timeOnline.plus(profile.getOnlineDuration());
                        Instant profileLastOnline = profile.getLastOnline();
                        if (profileLastOnline.isAfter(lastOnline)) {
                            lastOnline = profileLastOnline;
                        }
                    }
                    for (Wii wii : wiis) {
                        wiiList = wiiList + wii.getName() + "\n";
                    }
                    if (hasMembers && (member = user.getMember(context.getServer())) != null) {
                        embed.setColor(member.getColor());
                        embed.setThumbnail(user.getJDAUser().getEffectiveAvatarUrl());
                        embed.addField("Username:", user.getJDAUser().getName(), false);
                        embed.addField("Discriminator", user.getJDAUser().getDiscriminator(), false);
                        // embed.addField("Badges:", "", false);
                        embed.addField("ID:", "" + user.getID(), false);
                        embed.addField("Nickname:", member.getNickname() != null ? member.getNickname() : "##Not Nicknamed##", false);
                        embed.addField("Joined Discord:", date.format(member.getTimeCreated().toInstant().toEpochMilli()), false);
                        embed.addField("Joined " + context.getServer().getName() + ":", date.format(member.getTimeJoined().toInstant().toEpochMilli()), false);
                        embed.addField("Member for:", readableDuration(TimeUtils.since(member.getTimeJoined().toInstant()), false), false);
                        embed.addField("Time Online:", readableDuration(timeOnline, true), false);
                        embed.addField(profiles.size() + " registered Profiles:", profileList, false);
                        embed.addField(wiis.length + " registered Wiis:", wiiList, false);
                    } else {
                        embed.setThumbnail(user.getJDAUser().getEffectiveAvatarUrl());
                        embed.addField("Username:", user.getJDAUser().getName(), false);
                        embed.addField("Discriminator", user.getJDAUser().getDiscriminator(), false);
                        embed.addField("ID:", "" + user.getID(), false);
                        embed.addField("Time Online:", readableDuration(timeOnline, true), false);
                        embed.addField(profiles.size() + " registered Profiles:", profileList, false);
                        embed.addField(wiis.length + " registered Wiis:", wiiList, false);
                        embed.appendDescription("For more information, execute this command in a server the user is in.");
                    }
                } else if (match instanceof Player) {
                    Player profile = (Player) match;
                    DiscordUser user = DiscordUser.getDiscordUserTreatingUnknownsAsNobody(context, profile.getDiscord());
                    embed.addField("Name:", profile.getName(), false);
                    embed.addField("ID:", profile.getID() + "", false);
                    embed.addField("FC:", profile.getFriendCode(), false);
                    embed.addField("Owner:", user.toDetailedString(), false);
                    embed.addField("Time Online:", readableDuration(profile.getOnlineDuration(), true), false);
                    embed.addField("First Seen:", date.format(profile.getFirstSeen().toEpochMilli()), false);
                    embed.addField("Last Seen:", date.format(profile.getLastOnline().toEpochMilli()), false);
                }
            } else if (matches.size() == 0) {
                embed.setColor(Color.RED);
                embed.setTitle("Target not found");
                embed.addField("Target:", lookingFor, true);
            } else {
                embed.setTitle("Ambigious target string, supply an ID");
                embed.setColor(Color.RED);
                embed.addField("Target", lookingFor, true);
                embed.addField("Ambiguities", "" + matches.size(), true);
                if (users.size() > 0) {
                    embed.appendDescription("Discord users:\n");
                    String userList = "";
                    for (DiscordUser user : users) {
                        Member member;
                        if (hasMembers && (member = user.getMember(context.getServer())) != null && member.getNickname() != null) {
                            userList = userList + user.toDetailedString() + " AKA " + member.getEffectiveName() + "#" + member.getIdLong() + "\n";
                        } else {
                            userList = userList + user.toDetailedString() + "\n";
                        }
                    }
                    embed.addField("Ambiguous Users:", userList, false);
                }
                if (players.size() > 0) {
                    String playerList = "";
                    for (Player player : players) {
                        playerList = playerList + player.toFullString() + "\n";
                    }
                    embed.addField("Ambiguous Profiles:", playerList, false);
                }
            }
            embed.setTimestamp(Instant.now());
            context.sendMessage(embed.build());
        }
    }
    return 1;
}
Also used : DiscordUser(com.gamebuster19901.excite.bot.user.DiscordUser) Named(com.gamebuster19901.excite.util.Named) Player(com.gamebuster19901.excite.Player) Instant(java.time.Instant) Duration(java.time.Duration) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Wii(com.gamebuster19901.excite.bot.user.Wii) SimpleDateFormat(java.text.SimpleDateFormat) Member(net.dv8tion.jda.api.entities.Member) Wiimmfi(com.gamebuster19901.excite.Wiimmfi) HashSet(java.util.HashSet)

Example 3 with Wiimmfi

use of com.gamebuster19901.excite.Wiimmfi in project ExciteBot by TheGameCommunity.

the class Main method startDiscordBot.

private static DiscordBot startDiscordBot(String[] args, Wiimmfi wiimmfi) throws LoginException, IOException {
    String botOwner = null;
    File keyFile = new File("./discord.secret");
    for (int i = 0; i < args.length; i++) {
        if (args[i].equalsIgnoreCase("-owner")) {
            botOwner = args[++i];
        }
        if (args[i].equalsIgnoreCase("-keyFile")) {
            keyFile = new File(args[++i]);
        }
    }
    return new DiscordBot(wiimmfi, botOwner, keyFile);
}
Also used : DiscordBot(com.gamebuster19901.excite.bot.DiscordBot) File(java.io.File)

Example 4 with Wiimmfi

use of com.gamebuster19901.excite.Wiimmfi in project ExciteBot by TheGameCommunity.

the class Main method main.

@SuppressWarnings("rawtypes")
public static void main(String[] args) throws InterruptedException, ClassNotFoundException, IOException, SQLException {
    if (args.length % 2 != 0) {
        throw new IllegalArgumentException("Must be started with an even number of arguments!");
    }
    for (int i = 0; i < args.length; i++) {
        if (args[i].equals("-owner")) {
            botOwner = Long.parseLong(args[++i]);
        }
    }
    wiimmfi = startWiimmfi(args);
    discordBot = null;
    int bootAttempts = 0;
    while (discordBot == null) {
        try {
            bootAttempts++;
            discordBot = startDiscordBot(args, wiimmfi);
            discordBot.setLoading();
            discordBot.setWiimmfi(wiimmfi);
        } catch (LoginException | IOException | ErrorResponseException e) {
            LOGGER.log(Level.SEVERE, e, () -> e.getMessage());
            if (bootAttempts >= 3) {
                System.exit(-2);
            }
            Thread.sleep(5000);
        }
    }
    while (CONSOLE == null) {
        try {
            CONSOLE = new ConsoleUser();
        } catch (IOError e) {
            System.out.println(e);
            discordBot.setNoDB();
            Thread.sleep(5000);
        }
    }
    do {
        try {
            DatabaseConnection.INSTANCE = new DatabaseConnection();
        } catch (Throwable t) {
            System.out.println(t);
            discordBot.setNoDB();
            Thread.sleep(5000);
        }
    } while (DatabaseConnection.INSTANCE == null);
    Throwable prevError = null;
    Instant nextDiscordPing = Instant.now().minusMillis(1);
    Instant sendDiscordNotifications = Instant.now().minusMillis(1);
    startConsole();
    Thread mailThread = startMailThread();
    try {
        while (true) {
            try {
                System.gc();
                Throwable error = wiimmfi.getError();
                wiimmfi.update();
                if (error == null) {
                    if (prevError != null) {
                    // LOGGER.log(Level.SEVERE, "Error resolved.");
                    }
                } else {
                    if (prevError == null || !prevError.getClass().equals(error.getClass())) {
                        System.out.println("Error!");
                        LOGGER.log(Level.SEVERE, error, () -> error.getMessage());
                    }
                    prevError = error;
                }
                if (discordBot != null) {
                    if (nextDiscordPing.isBefore(Instant.now())) {
                        nextDiscordPing = Instant.now().plus(Duration.ofSeconds(5));
                        updateLists(true, true);
                    }
                    if (sendDiscordNotifications.isBefore(Instant.now())) {
                        sendDiscordNotifications = Instant.now().plus(Duration.ofSeconds(4));
                        DiscordUser.notifyDiscordUsers();
                    }
                }
                while (!consoleCommandsAwaitingProcessing.isEmpty()) {
                    Commands.DISPATCHER.handleCommand(consoleCommandsAwaitingProcessing.pollFirst());
                }
            } catch (ErrorResponseException e) {
                CONSOLE.sendMessage(StacktraceUtil.getStackTrace(e));
                CONSOLE.sendMessage("An ErrorResponseException occurred... waiting 10 seconds");
            } catch (Throwable t) {
                if (t != null && (t instanceof ConnectionIsClosedException || t instanceof CommunicationsException || t instanceof CJCommunicationsException || t instanceof SQLNonTransientConnectionException || (t.getCause() != null && (t.getCause() instanceof IOException || t.getCause() instanceof SQLException || t.getCause() instanceof IOError)))) {
                    System.err.println("Attempting to recover from database connection failure...");
                    DatabaseConnection.INSTANCE.close();
                    DatabaseConnection.INSTANCE = null;
                    while (DatabaseConnection.INSTANCE == null) {
                        discordBot.setNoDB();
                        try {
                            DatabaseConnection.INSTANCE = new DatabaseConnection();
                        } catch (Throwable t2) {
                            System.err.println("Attempting to recover from database connection failure...");
                            t2.printStackTrace(System.err);
                            DatabaseConnection.INSTANCE = null;
                        }
                        Thread.sleep(5000);
                    }
                    continue;
                }
                throw t;
            }
            if (!mailThread.isAlive() && !stopping) {
                throw new Error("Mail thread has died");
            }
            Thread.sleep(1000);
        }
    } catch (Throwable t) {
        t.printStackTrace();
        if (discordBot != null) {
            discordBot.jda.getPresence().setPresence(OnlineStatus.DO_NOT_DISTURB, Activity.of(ActivityType.DEFAULT, "Bot Crashed"));
            if (botOwner != -1) {
                try {
                    DiscordUser user = DiscordUser.getDiscordUserIncludingUnknown(ConsoleContext.INSTANCE, botOwner);
                    if (!(user instanceof UnknownDiscordUser)) {
                        user.sendMessage(StacktraceUtil.getStackTrace(t));
                    } else {
                        CONSOLE.sendMessage(StacktraceUtil.getStackTrace(t));
                    }
                } catch (Throwable t2) {
                    CONSOLE.sendMessage(StacktraceUtil.getStackTrace(t));
                }
            }
            while (true) {
                Thread.sleep(1000);
            }
        } else {
            CONSOLE.sendMessage(StacktraceUtil.getStackTrace(t));
        }
    }
    System.exit(-1);
}
Also used : DiscordUser(com.gamebuster19901.excite.bot.user.DiscordUser) UnknownDiscordUser(com.gamebuster19901.excite.bot.user.UnknownDiscordUser) SQLException(java.sql.SQLException) UnknownDiscordUser(com.gamebuster19901.excite.bot.user.UnknownDiscordUser) Instant(java.time.Instant) IOError(java.io.IOError) IOException(java.io.IOException) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) SQLNonTransientConnectionException(java.sql.SQLNonTransientConnectionException) IOError(java.io.IOError) LoginException(javax.security.auth.login.LoginException) ErrorResponseException(net.dv8tion.jda.api.exceptions.ErrorResponseException) ConsoleUser(com.gamebuster19901.excite.bot.user.ConsoleUser) DatabaseConnection(com.gamebuster19901.excite.bot.database.sql.DatabaseConnection) CommunicationsException(com.mysql.cj.jdbc.exceptions.CommunicationsException) CJCommunicationsException(com.mysql.cj.exceptions.CJCommunicationsException) ConnectionIsClosedException(com.mysql.cj.exceptions.ConnectionIsClosedException)

Example 5 with Wiimmfi

use of com.gamebuster19901.excite.Wiimmfi in project ExciteBot by TheGameCommunity.

the class Wiimmfi method update.

public void update() {
    if (Instant.now().isAfter(nextPing)) {
        if (url != null) {
            try {
                String key = IOUtils.toString(new FileInputStream(new File("./wiimmfi.secret")), Charsets.UTF_8);
                HttpClient client = HttpClients.custom().build();
                HttpUriRequest request = RequestBuilder.get(EXCITEBOTS.toURI()).setHeader(new BasicHeader("X-Wiimmfi-Key", key)).setHeader(new BasicHeader(HttpHeaders.USER_AGENT, "Excitebot (+https://gamebuster19901.com/ExciteBot)")).build();
                HttpResponse response = client.execute(request);
                JSON = JsonParser.parseString(new BasicResponseHandler().handleResponse(response));
                updateOnlinePlayers();
                error = null;
            } catch (Exception e) {
                error = e;
                System.out.println(e);
            }
        } else {
            if (error == null) {
                error = new NullPointerException("No url or file provided!");
            }
        }
        nextPing = Instant.now().plus(WAIT_TIME);
    }
}
Also used : HttpUriRequest(org.apache.http.client.methods.HttpUriRequest) HttpClient(org.apache.http.client.HttpClient) BasicResponseHandler(org.apache.http.impl.client.BasicResponseHandler) HttpResponse(org.apache.http.HttpResponse) File(java.io.File) FileInputStream(java.io.FileInputStream) BasicHeader(org.apache.http.message.BasicHeader) SQLException(java.sql.SQLException) WiimmfiResponseException(com.gamebuster19901.excite.exception.WiimmfiResponseException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Aggregations

Wiimmfi (com.gamebuster19901.excite.Wiimmfi)2 DiscordUser (com.gamebuster19901.excite.bot.user.DiscordUser)2 WiimmfiResponseException (com.gamebuster19901.excite.exception.WiimmfiResponseException)2 File (java.io.File)2 IOException (java.io.IOException)2 SQLException (java.sql.SQLException)2 Instant (java.time.Instant)2 HashSet (java.util.HashSet)2 Player (com.gamebuster19901.excite.Player)1 DiscordBot (com.gamebuster19901.excite.bot.DiscordBot)1 MessageContext (com.gamebuster19901.excite.bot.command.MessageContext)1 DatabaseConnection (com.gamebuster19901.excite.bot.database.sql.DatabaseConnection)1 ConsoleUser (com.gamebuster19901.excite.bot.user.ConsoleUser)1 UnknownDiscordUser (com.gamebuster19901.excite.bot.user.UnknownDiscordUser)1 Wii (com.gamebuster19901.excite.bot.user.Wii)1 WiimmfiErrorResponse (com.gamebuster19901.excite.exception.WiimmfiErrorResponse)1 Named (com.gamebuster19901.excite.util.Named)1 JsonArray (com.google.gson.JsonArray)1 JsonElement (com.google.gson.JsonElement)1 CJCommunicationsException (com.mysql.cj.exceptions.CJCommunicationsException)1