Graph database Analysis of the Steam Network
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
8.7 KiB

  1. package net.jrtechs.www.SteamAPI;
  2. import net.jrtechs.www.model.Game;
  3. import net.jrtechs.www.model.Player;
  4. import net.jrtechs.www.utils.ConfigLoader;
  5. import net.jrtechs.www.utils.WebScraper;
  6. import net.jrtechs.www.webCrawler.APIThrottler;
  7. import org.json.JSONArray;
  8. import org.json.JSONObject;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.stream.IntStream;
  13. /**
  14. * Class which is used to pull information from the Steam api
  15. *
  16. * Documentation at https://developer.valvesoftware.com/wiki/Steam_Web_API
  17. *
  18. * @author Jeffery Russell 5-26-18
  19. */
  20. public class APIConnection
  21. {
  22. /** Base url to use for all queries to steam's api **/
  23. private final String baseURL = "https://community.steam-api.com";
  24. /** Path to use when getting info on a player from api **/
  25. private final String playerInfoURL = "/ISteamUser/GetPlayerSummaries/v0002/";
  26. private final String friendListURL = "/ISteamUser/GetFriendList/v0001/";
  27. private final String gamesListURL = "/IPlayerService/GetOwnedGames/v0001/";
  28. /** Path to conf file(from within the conf folder) **/
  29. private final String confPath = "SteamAPIKey.json";
  30. /** API key for steam's api - loaded from json conf file **/
  31. private String apiKey;
  32. /**
  33. * Constructor for APIConnection which loads a config file
  34. * and sets the api key to your Steam api key.
  35. */
  36. public APIConnection()
  37. {
  38. ConfigLoader conf = new ConfigLoader(confPath);
  39. apiKey = "?key=" + conf.getValue("api");
  40. }
  41. /**
  42. * Makes a call to the steam api using the requested url and does
  43. * some error handling where it will re-request data from the steam
  44. * api if it simply throws an internal error.
  45. *
  46. * @param url address to download data with
  47. * @return string of the data returned
  48. */
  49. public String querySteamAPI(String url)
  50. {
  51. System.out.println(url);
  52. boolean downloaded = false;
  53. String apiData = "";
  54. while(!downloaded)
  55. {
  56. try
  57. {
  58. apiData = WebScraper.getWebsite(url);
  59. downloaded = true;
  60. }
  61. catch (SteamConnectionException e)
  62. {
  63. switch (e.getError())
  64. {
  65. case RESTRICTED:
  66. {
  67. //This is fine
  68. System.out.println("Private profile: ");
  69. System.out.println(url);
  70. return "";
  71. }
  72. case CONNECTION:
  73. {
  74. //spooky 500 error :(
  75. //I don't know why but, steam throws 1-3 of these per day
  76. System.out.println("Spooky steam API error");
  77. new APIThrottler().wait(30);
  78. break;
  79. }
  80. case RATE_LIMITED:
  81. {
  82. //hasn't happened yet
  83. System.out.println("Oof, we are being throttled");
  84. new APIThrottler().wait(300);
  85. break;
  86. }
  87. case FORBIDDEN:
  88. {
  89. System.out.println("Check your API key.");
  90. System.exit(-1);
  91. }
  92. case BAD_REQUEST:
  93. {
  94. System.out.println("BAD REQUEST:");
  95. System.out.println(url);
  96. System.out.println("Please modify your query.");
  97. return "";
  98. }
  99. }
  100. }
  101. }
  102. return apiData;
  103. }
  104. public List<Game> getGames(String steamID)
  105. {
  106. List<Game> games = new ArrayList<>();
  107. String apiData = this.querySteamAPI(this.baseURL + this.gamesListURL +
  108. this.apiKey + "&steamid=" + steamID +
  109. "&include_appinfo=true&include_played_free_games=true");
  110. if(apiData.isEmpty())
  111. return games;
  112. JSONObject object = new JSONObject(apiData);
  113. System.out.println(object);
  114. if(object.has("response"))
  115. {
  116. JSONArray gamesJ = object.getJSONObject("response").getJSONArray("games");
  117. IntStream.range(0, gamesJ.length()).forEach(i ->
  118. games.add(new Game(gamesJ.getJSONObject(i))));
  119. }
  120. return games;
  121. }
  122. /**
  123. * Returns a list of the UIDs of all the players friends
  124. *
  125. * @param steamid
  126. * @return
  127. */
  128. public List<String> getFriends(String steamid)
  129. {
  130. List<String> friendsId = new ArrayList<>();
  131. String apiData = this.querySteamAPI(this.baseURL + this.friendListURL +
  132. this.apiKey + "&steamid=" + steamid);
  133. if(apiData.equals(""))
  134. return friendsId; //private url
  135. JSONObject object = new JSONObject(apiData);
  136. System.out.println(object);
  137. if(object.has("friendslist"))
  138. {
  139. object.getJSONObject("friendslist")
  140. .getJSONArray("friends").toList()
  141. .forEach(f->
  142. friendsId.add(((HashMap<String, String>)(f)).get("steamid"))
  143. );
  144. }
  145. else
  146. {
  147. return friendsId;
  148. }
  149. return friendsId;
  150. }
  151. /**
  152. * returns a map from the steam id to the players name
  153. *
  154. * * tricky because we can only request up to 100 ids
  155. * in one request
  156. *
  157. * @param ids
  158. * @return
  159. */
  160. public List<Player> getPlayers(List<String> ids)
  161. {
  162. System.out.println(ids);
  163. List<Player> players = new ArrayList<>();
  164. while(!ids.isEmpty())
  165. {
  166. StringBuilder queryUrl = new StringBuilder(baseURL + playerInfoURL + apiKey + "&steamids=");
  167. int remove = Math.min(ids.size(), 100);
  168. for(int i = 0; i < remove; i++)
  169. {
  170. queryUrl.append(",").append(ids.remove(0));
  171. }
  172. System.out.println(queryUrl);
  173. JSONArray names;
  174. String apiResult = this.querySteamAPI(queryUrl.toString());
  175. if(apiResult.equals(""))
  176. return players;
  177. JSONObject object = new JSONObject(apiResult);
  178. if(object.has("response"))
  179. {
  180. names = object.getJSONObject("response").getJSONArray("players");
  181. }
  182. else
  183. {
  184. //eh
  185. return players;
  186. }
  187. for(int i = 0; i < names.length(); i++)
  188. {
  189. JSONObject player = names.getJSONObject(i);
  190. if(player.has(Player.KEY_STEAM_ID) && player.has(Player.KEY_USERNAME))
  191. {
  192. players.add(transformToPlayer(player));
  193. }
  194. }
  195. }
  196. return players;
  197. }
  198. private Player transformToPlayer(JSONObject player)
  199. {
  200. String avatar = player.has(Player.KEY_AVATAR) ?
  201. player.getString(Player.KEY_AVATAR) :
  202. "";
  203. String realName = player.has(Player.KEY_REAL_NAME) ?
  204. player.getString(Player.KEY_REAL_NAME) :
  205. "";
  206. String id = player.getString(Player.KEY_STEAM_ID);
  207. Integer timeCreated = player.has(Player.KEY_TIME_CREATED) ?
  208. player.getInt(Player.KEY_TIME_CREATED) :
  209. 0;
  210. String username = player.getString(Player.KEY_USERNAME);
  211. return new Player(username, id, realName, timeCreated, avatar);
  212. }
  213. /**
  214. * Returns the name of the player with a specific steam id
  215. *
  216. * @param steamid the steam id of player
  217. * @return
  218. */
  219. public Player getSingle(String steamid) throws SteamConnectionException
  220. {
  221. JSONObject response = new JSONObject(WebScraper
  222. .getWebsite(this.baseURL + this.playerInfoURL +
  223. this.apiKey + "&steamids=" + steamid));
  224. if(response.has("response"))
  225. {
  226. response = response.getJSONObject("response");
  227. if(response.has("players"))
  228. {
  229. JSONArray arr = response.getJSONArray("players");
  230. if(arr.length() > 0)
  231. {
  232. return transformToPlayer(arr.getJSONObject(0));
  233. }
  234. }
  235. }
  236. return null;
  237. }
  238. public static void main(String[] args) throws SteamConnectionException
  239. {
  240. APIConnection con = new APIConnection();
  241. //steam id of jrtechs
  242. con.getFriends("76561198188400721").forEach(System.out::println);
  243. //System.out.println(con.getSingle("76561198188400721"));
  244. System.out.println(con.getGames("76561198188400721"));
  245. }
  246. }