net.meltdowntech.steamstats.SteamUser.java Source code

Java tutorial

Introduction

Here is the source code for net.meltdowntech.steamstats.SteamUser.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package net.meltdowntech.steamstats;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

/**
 *
 * @author Miguel Obregon <miguel_lego@yahoo.com>
 */
public class SteamUser {
    private final Map<String, Object> values;
    private final List<SteamGame> games;

    public static void main(String[] args) {
        Util.startTimer();
        List<Long> ids = new ArrayList<>();
        ids.add(76561198038145439L);
        List<SteamUser> users = fetchUsers(ids);
        users.get(0).fetchPlaytime();
        users.get(0).fetchLevel();
        Util.printInfo("Playtime " + users.get(0).getPlaytime());
        Util.printInfo("Level " + users.get(0).getLevel());
    }

    private SteamUser() {
        values = new TreeMap<>();
        games = new ArrayList<>();
    }

    public int getLevel() {
        if (values.containsKey("level"))
            return (Integer) values.get("level");
        return 0;
    }

    public double getPlaytime() {
        if (values.containsKey("playtime"))
            return (Double) values.get("playtime");
        return 0;
    }

    public String getPersonaName() {
        if (values.containsKey("personaname"))
            return (String) values.get("personaname");
        return "";
    }

    public int getCommunityVisibilityState() {
        if (values.containsKey("communityvisibilitystate"))
            return (Integer) values.get("communityvisibilitystate");
        return 1;
    }

    public long getCommunityId() {
        if (values.containsKey("steamid"))
            return Long.parseLong((String) values.get("steamid"));
        return 0;
    }

    public int getLastLogOff() {
        if (values.containsKey("lastlogoff"))
            return (Integer) values.get("lastlogoff");
        return 0;
    }

    @Override
    public String toString() {
        return String.format("%d,\"%s\",%.1f,%d", this.getCommunityId(), this.getPersonaName(), this.getPlaytime(),
                this.getLevel());
    }

    public static List<SteamUser> fetchUsers(List<Long> ids) {
        List<SteamUser> users = new ArrayList<>();
        int queries = (int) Math.ceil(ids.size() / 100.0);

        //Query every hundred users
        Util.printDebug("Fetching users");
        Util.printInfo(String.format("%d user%s allotted", ids.size(), ids.size() == 1 ? "" : "s"));
        Util.printDebug(String.format("%d quer%s allotted", queries, queries == 1 ? "y" : "ies"));
        for (int x = 0; x < queries; x++) {
            //Create steam ids query string
            String steamIds = "&steamids=";
            for (int y = x * 100; y < (x + 1) * 100 && y < ids.size(); y++) {
                steamIds += ids.get(y) + ",";
            }

            //Create query url
            String url = Steam.URL + Steam.PLAYER_DATA + "?key=" + Steam.KEY + steamIds;
            try {
                //Attempt connection and parse
                URL steam = new URL(url);
                URLConnection steamConn = steam.openConnection();
                Reader steamReader = new InputStreamReader(steamConn.getInputStream());
                JSONTokener steamTokener = new JSONTokener(steamReader);
                JSONObject data = (JSONObject) steamTokener.nextValue();
                JSONObject response = data.getJSONObject("response");
                JSONArray players = response.getJSONArray("players");

                //Parse each player
                for (int y = 0; y < players.length(); y++) {
                    JSONObject player = players.getJSONObject(y);
                    SteamUser user = new SteamUser();

                    //Parse each field
                    Iterator keys = player.keys();
                    while (keys.hasNext()) {
                        String key = (String) keys.next();
                        user.values.put(key, player.get(key));
                    }
                    users.add(user);
                }
            } catch (MalformedURLException ex) {
                Util.printError("Invalid URL");
            } catch (IOException | JSONException ex) {
                Util.printError("Invalid data");
            } catch (Exception ex) {
                Util.printError("Generic error");
            }

        }
        Util.printDebug("Done fetching users");
        return users;
    }

    public void fetchPlaytime() {
        if (this.getCommunityVisibilityState() == 1)
            return;
        games.addAll(SteamGame.fetchGames(this, false));
        double sum = 0;
        for (SteamGame game : games)
            sum += game.getPlaytime();
        values.put("playtime", sum / 60.0);
    }

    public void fetchGames() {
        if (this.getCommunityVisibilityState() == 1)
            return;
        games.addAll(SteamGame.fetchGames(this, true));
        double sum = 0;
        for (SteamGame game : games)
            sum += game.getPlaytime();
        values.put("playtime", sum / 60.0);
    }

    public void fetchLevel() {
        try {
            String url = String.format("http://steamcommunity.com/profiles/%s/badges", getCommunityId() + "");
            URL steam = new URL(url);
            URLConnection yc = steam.openConnection();
            Reader reader = new InputStreamReader(yc.getInputStream());
            HTMLEditorKit.Parser parser = new ParserDelegator();
            parser.parse(reader, new HTMLEditorKit.ParserCallback() {
                private boolean foundIt;

                @Override
                public void handleText(char[] data, int pos) {
                    if (foundIt)
                        values.put("level", Integer.parseInt(new String(data)));
                }

                @Override
                public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
                    if (t == HTML.Tag.SPAN) {
                        Object o = a.getAttribute(HTML.Attribute.CLASS);
                        if (o != null && o.equals("friendPlayerLevelNum"))
                            foundIt = true;
                    }
                }

                @Override
                public void handleEndTag(HTML.Tag t, int pos) {
                    if (t == HTML.Tag.SPAN)
                        foundIt = false;
                }
            }, true);

        } catch (IOException ex) {
            Util.printError("Invalid data");
        }
    }

    public static SteamUser fetchUser(Long id) {
        //TODO Write optimized version of this
        List<SteamUser> user = fetchUsers(Arrays.asList(new Long[] { id }));
        if (!user.isEmpty())
            return user.get(0);
        return new SteamUser();
    }
}