goldwatch_checker.PlayerData.java Source code

Java tutorial

Introduction

Here is the source code for goldwatch_checker.PlayerData.java

Source

/*
 * Copyright 2017 Thomas Hamill
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to 
 * deal in the Software without restriction, including without limitation the 
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
 * sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
*/
package goldwatch_checker;

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import org.apache.commons.io.IOUtils;

/**
 *
 * @author tom
 */
public class PlayerData {

    private String m_battletag;
    private String m_discordName;
    private String json;
    private String m_region;
    private GregorianCalendar m_first_chk;
    private GregorianCalendar m_last_chk;
    private Integer m_firstRank;
    private Integer m_lastRank;
    private PlayerTier m_highestTier;
    private float m_qphoursplayed;
    private int m_level;
    private int m_compMatchesPlayed;

    /**
     *
     * @return
     */
    public Float getQuickPlayHours() {
        return m_qphoursplayed;
    }

    /**
     *
     * @param name
     * @param discord
     * @param region
     * @param firstDate
     * @param lastDate
     * @param firstSr
     * @param lastSr
     * @param maxtier
     * @param hours
     * @throws MalformedURLException
     * @throws IOException
     */
    public PlayerData(String name, String discord, String region, String firstDate, String lastDate,
            Integer firstSr, Integer lastSr, String maxtier, float hours)
            throws MalformedURLException, IOException {
        m_battletag = name.replaceAll(" ", "");
        m_discordName = discord;
        json = "";
        DetermineRegion(region);
        if (firstDate != null) {
            String date[] = firstDate.split("/");
            for (int i = 0; i < date.length; ++i) {
                date[i] = date[i].replaceFirst("\"", "").trim();
            }
            m_first_chk = new GregorianCalendar(Integer.parseInt(date[2]), Integer.parseInt(date[0]) - 1,
                    Integer.parseInt(date[1]));
        } else {
            Date today = new Date();
            m_first_chk = new GregorianCalendar();
            m_first_chk.setTime(today);
        }

        if (lastDate != null) {
            String date[] = lastDate.split("/");
            for (int i = 0; i < 3; ++i) {
                date[i] = date[i].trim().replaceAll("\"", "").replaceFirst("^0+(?!$)", "");
            }
            m_last_chk = new GregorianCalendar(Integer.parseInt(date[2]), Integer.parseInt(date[0]) - 1,
                    Integer.parseInt(date[1]));
        } else {
            m_last_chk = (GregorianCalendar) m_first_chk.clone();
        }
        m_firstRank = firstSr;
        m_lastRank = lastSr;
        m_highestTier = PlayerTier.Factory(maxtier);
        m_qphoursplayed = hours;
        m_level = 0;
        m_compMatchesPlayed = 0;
    }

    /**
     *
     * @param name
     * @throws MalformedURLException
     * @throws IOException
     */
    public PlayerData(String name) throws MalformedURLException, IOException {
        this(name, null, "us", null, null, null, null, null, 0.0f);
    }

    /**
     *
     * @param name
     * @param discord
     * @throws MalformedURLException
     * @throws IOException
     */
    public PlayerData(String name, String discord) throws MalformedURLException, IOException {
        this(name, discord, "us", null, null, null, null, null, 0.0f);
    }

    /**
     *
     * @param name
     * @param discord
     * @param region
     * @throws MalformedURLException
     * @throws IOException
     */
    public PlayerData(String name, String discord, String region) throws MalformedURLException, IOException {
        this(name, discord, region, null, null, null, null, null, 0.0f);
    }

    /**
     *
     * @return
     */
    public PlayerData CreateServerConn() {
        StringBuilder connstring = new StringBuilder();
        connstring.append("http://localhost:4444");
        connstring.append("/api/v3");
        connstring.append("/u/").append(m_battletag.replace("#", "-"));
        connstring.append("/blob");
        URL url;

        /* JSON method of retreival */
        try {
            url = new URL(connstring.toString());
            json = IOUtils.toString(url, "UTF-8");
        } catch (IOException e) {
            System.err.printf("Server connection error: could not find data for player %s\n", m_battletag);
        }
        return this;
    }

    /**
     * Opens connection to local OWAPI server, queries new data for this Player
     * @return true if player exists on server, false otherwise
     * @throws IOException 
     */
    public PlayerData GetDataFromServer() throws IOException {
        if (json.isEmpty()) {
            CreateServerConn();
        }
        JsonParser p = new JsonParser();
        JsonElement e = p.parse(json);
        if (!e.isJsonNull()) {
            Date today = new Date();
            m_last_chk = new GregorianCalendar();
            m_last_chk.setTime(today);
            try {
                int sr = e.getAsJsonObject().get(m_region).getAsJsonObject().get("stats").getAsJsonObject()
                        .get("competitive").getAsJsonObject().get("overall_stats").getAsJsonObject().get("comprank")
                        .getAsInt();
                m_lastRank = Integer.valueOf(sr);
            } catch (IllegalStateException ex) {
                m_lastRank = null;
            } catch (UnsupportedOperationException ex) {
                m_lastRank = null;
            }

            if (m_firstRank == null)
                m_firstRank = m_lastRank;
            try {
                m_highestTier = PlayerTier.Factory(e.getAsJsonObject().get(m_region).getAsJsonObject().get("stats")
                        .getAsJsonObject().get("competitive").getAsJsonObject().get("overall_stats")
                        .getAsJsonObject().get("tier").getAsString());
            } catch (UnsupportedOperationException ex) {
                m_highestTier = PlayerTier.INVALID;
            }
            m_qphoursplayed = ComputeQuickplayTimePlayed();
            m_level = GetLevel();
            m_compMatchesPlayed = e.getAsJsonObject().get(m_region).getAsJsonObject().get("stats").getAsJsonObject()
                    .get("competitive").getAsJsonObject().get("overall_stats").getAsJsonObject().get("games")
                    .getAsInt();
            return this;
        }
        return null;
    }

    /**
     * 
     * @return
     * @throws IOException 
     */
    public PlayerTier GetPlayerTier() throws IOException {
        return (m_highestTier != null) ? m_highestTier : PlayerTier.INVALID;
    }

    /**
     *
     * @param region
     * @return
     * @throws IOException
     */
    public PlayerTier GetPlayerTier(String region) throws IOException {
        JsonParser parser = new JsonParser();
        JsonElement e = parser.parse(json);
        if (e.isJsonObject()) {
            JsonElement tier = e.getAsJsonObject().get(region).getAsJsonObject().get("stats").getAsJsonObject()
                    .get("competitive").getAsJsonObject().get("overall_stats").getAsJsonObject().get("tier");
            if (tier != null) {
                String val = tier.getAsString();
                return PlayerTier.Factory(val);
            }
        }
        return null;
    }

    /**
     * 
     * @return 
     */
    public PlayerTier GetCurrentTier() {
        if (GetPlayerSR() == null) {
            return PlayerTier.INVALID;
        }
        if (GetPlayerSR() < 1500)
            return PlayerTier.BRONZE;
        if (GetPlayerSR() < 2000)
            return PlayerTier.SILVER;
        if (GetPlayerSR() < 2500)
            return PlayerTier.GOLD;
        if (GetPlayerSR() < 3000)
            return PlayerTier.PLATINUM;
        if (GetPlayerSR() < 3500)
            return PlayerTier.DIAMOND;
        if (GetPlayerSR() < 4000)
            return PlayerTier.MASTER;
        else
            return PlayerTier.GRANDMASTER;
    }

    /**
     * 
     * @return 
     */
    public Integer GetPlayerSR() {
        return m_lastRank;
    }

    /**
     * 
     * @return 
     */
    public Integer GetStartingSR() {
        return m_firstRank;
    }

    /**
     * 
     * @param region
     * @return
     * @throws Exception 
     */
    public Integer GetPlayerSR(String region) throws Exception {
        if (region.equals(m_region))
            return m_lastRank;

        JsonParser p = new JsonParser();
        JsonElement e = p.parse(json);
        if (e.isJsonObject()) {
            if (e.getAsJsonObject().get(region).isJsonNull()) {
                String route = e.getAsJsonObject().get("_request").getAsJsonObject().get("route").getAsString();
                String list[] = route.split("/");
                System.err.printf("%s not found in %s\n", list[4], region);
                return 0;
            }
            Integer sr;
            try {
                sr = e.getAsJsonObject().get(region).getAsJsonObject().get("stats").getAsJsonObject()
                        .get("competitive").getAsJsonObject().get("overall_stats").getAsJsonObject().get("comprank")
                        .getAsInt();
            } catch (IllegalStateException ex) {
                sr = null;
            }
            return sr;
        }
        return 0;

    }

    /**
     *
     * @return
     */
    public final String GetBattletag() {
        return m_battletag;
    }

    /**
     *
     * @return
     */
    public final String GetDiscord() {
        return m_discordName;
    }

    /**
     *
     * @return
     */
    public final String GetRegion() {
        return m_region;
    }

    /**
     * 
     * @return 
     */
    public final String GetFirstDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("M/d/yyyy");
        return sdf.format(m_first_chk.getTime());
    }

    /**
     * 
     * @return 
     */
    public final String GetLastDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("M/d/yyyy");
        return sdf.format(m_last_chk.getTime());
    }

    /**
     *
     * @param that
     * @return
     */
    public int compareSR(PlayerData that) {
        return m_lastRank.compareTo(that.m_lastRank);
    }

    /**
     *
     * @param that
     * @return
     */
    public int compareName(PlayerData that) {
        return m_battletag.compareTo(that.m_battletag);
    }

    private static final String s_regions[] = { "us", "eu", "kr" };

    private void DetermineRegion(String region) {
        switch (region.toLowerCase()) {
        case "eu":
            m_region = s_regions[1];
            break;
        case "us":
            m_region = s_regions[0];
            break;
        case "kr":
            m_region = s_regions[2];
            break;
        default:
            m_region = s_regions[0];//assume unknown region is NA
            break;
        }
    }

    /**
     *
     * @return
     */
    public Float ComputeQuickplayTimePlayed() {
        JsonParser p = new JsonParser();
        JsonElement e = p.parse(json);
        float time = 0.0f;
        if (e.isJsonObject()) {
            JsonElement list = e.getAsJsonObject().get(m_region);
            if (!list.isJsonNull()) {
                for (HeroEnum h : HeroEnum.values()) {
                    time += list.getAsJsonObject().get("heroes").getAsJsonObject().get("playtime").getAsJsonObject()
                            .get("quickplay").getAsJsonObject().get(h.GetName()).getAsFloat();
                }
            }

        }
        return time;
    }

    /**
     *
     * @return
     */
    public Float GetCompTimePlayed() {
        JsonParser p = new JsonParser();
        JsonElement e = p.parse(json);
        float time = 0.0f;
        if (e.isJsonObject()) {
            JsonElement list = e.getAsJsonObject().get(m_region);
            if (!list.isJsonNull()) {
                for (HeroEnum h : HeroEnum.values()) {
                    try {
                        time += list.getAsJsonObject().get("heroes").getAsJsonObject().get("playtime")
                                .getAsJsonObject().get("competitive").getAsJsonObject().get(h.GetName())
                                .getAsFloat();
                    } catch (IllegalStateException ex) {
                        //TODO: not a json object handler?
                    }
                }
            }

        }
        return time;
    }

    /**
     *
     * @return
     */
    public Float GetTotalTimePlayed() {
        return GetCompTimePlayed() + ComputeQuickplayTimePlayed();
    }

    private Integer GetLevel() throws IllegalStateException {
        JsonParser p = new JsonParser();
        JsonElement e = p.parse(json);
        int maxLevel = Integer.MIN_VALUE;
        if (!e.isJsonNull()) {
            for (String r : s_regions) {
                if (!e.getAsJsonObject().get(r).isJsonNull()) {
                    int level = 100 * e.getAsJsonObject().get(r).getAsJsonObject().get("stats").getAsJsonObject()
                            .get("competitive").getAsJsonObject().get("overall_stats").getAsJsonObject()
                            .get("prestige").getAsInt();
                    level += e.getAsJsonObject().get(r).getAsJsonObject().get("stats").getAsJsonObject()
                            .get("competitive").getAsJsonObject().get("overall_stats").getAsJsonObject()
                            .get("level").getAsInt();
                    if (maxLevel < level)
                        maxLevel = level;
                }
            }
        }
        return (maxLevel > 25) ? maxLevel : Integer.MAX_VALUE;
    }

    /**
     * 
     * @param maxTier
     * @param minQpHours
     * @param minLevel
     * @return 
     */
    public Boolean CanParticipate(PlayerTier maxTier, float minQpHours, int minLevel)
            throws NullPointerException, IllegalStateException {
        return PlayerTier.tierComparator.compare(m_highestTier, maxTier) <= 0 && getQuickPlayHours() >= minQpHours
                && GetLevel() >= minLevel;
    }

    /**
     * 
     * @param minLevel
     * @param minCompMatches
     * @return 
     */
    public Boolean CanParticipate(int minLevel, int minCompMatches) {
        return m_compMatchesPlayed >= minCompMatches && m_level >= minLevel;
    }

    /**
     * 
     * @return 
     */
    public int getLevel() {
        return m_level;
    }

    /**
     * 
     * @param level 
     */
    public void setLevel(int level) {
        this.m_level = level;
    }

    /**
     * 
     * @return 
     */
    public int getCompMatchesPlayed() {
        return m_compMatchesPlayed;
    }

    /**
     * 
     * @param compMatchesPlayed 
     */
    public void setCompMatchesPlayed(int compMatchesPlayed) {
        this.m_compMatchesPlayed = compMatchesPlayed;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(m_battletag);
        sb.append(", ").append(m_discordName);

        return sb.toString();
    }
}