diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java index 4662dd9942..f8257b88d3 100644 --- a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreClient.java @@ -66,4 +66,32 @@ public class HiscoreClient throw new IOException(ex); } } + + public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill) throws IOException + { + HttpUrl.Builder builder = RuneliteAPI.getApiBase().newBuilder() + .addPathSegment("hiscore") + .addPathSegment(skill.toString().toLowerCase()) + .addQueryParameter("username", username); + + HttpUrl url = builder.build(); + + logger.debug("Built URI: {}", url); + + Request request = new Request.Builder() + .url(url) + .build(); + + Response response = RuneliteAPI.CLIENT.newCall(request).execute(); + + try (ResponseBody body = response.body()) + { + InputStream in = body.byteStream(); + return RuneliteAPI.GSON.fromJson(new InputStreamReader(in), SingleHiscoreSkillResult.class); + } + catch (JsonParseException ex) + { + throw new IOException(ex); + } + } } diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java new file mode 100644 index 0000000000..6eee6ca75d --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/HiscoreSkill.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.api.hiscore; + +public enum HiscoreSkill +{ + OVERALL("Overall"), + ATTACK("Attack"), + DEFENCE("Defence"), + STRENGTH("Strength"), + HITPOINTS("Hitpoints"), + RANGED("Ranged"), + PRAYER("Prayer"), + MAGIC("Magic"), + COOKING("Cooking"), + WOODCUTTING("Woodcutting"), + FLETCHING("Fletching"), + FISHING("Fishing"), + FIREMAKING("Firemaking"), + CRAFTING("Crafting"), + SMITHING("Smithing"), + MINING("Mining"), + HERBLORE("Herblore"), + AGILITY("Agility"), + THIEVING("Thieving"), + SLAYER("Slayer"), + FARMING("Farming"), + RUNECRAFT("Runecraft"), + HUNTER("Hunter"), + CONSTRUCTION("Construction"); + + private final String name; + + HiscoreSkill(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java b/http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java new file mode 100644 index 0000000000..c2ab3407a1 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/hiscore/SingleHiscoreSkillResult.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2017. l2- + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.http.api.hiscore; + +import java.util.Objects; + +public class SingleHiscoreSkillResult +{ + private String player; + private String skillName; + private Skill skill; + + public String getPlayer() + { + return player; + } + + public void setPlayer(String player) + { + this.player = player; + } + + public String getSkillName() + { + return skillName; + } + + public void setSkillName(String skillName) + { + this.skillName = skillName; + } + + public Skill getSkill() + { + return skill; + } + + public void setSkill(Skill skill) + { + this.skill = skill; + } + + @Override + public int hashCode() + { + int hash = 7; + hash = 37 * hash + Objects.hashCode(this.player); + hash = 37 * hash + Objects.hashCode(this.skillName); + hash = 37 * hash + Objects.hashCode(this.skill); + return hash; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final SingleHiscoreSkillResult other = (SingleHiscoreSkillResult) obj; + if (!Objects.equals(this.player, other.player)) + { + return false; + } + if (!Objects.equals(this.skillName, other.skillName)) + { + return false; + } + if (!Objects.equals(this.skill, other.skill)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return "SingleHiscoreSkillResult{" + "player=" + player + ", skillName=" + skillName + ", skill=" + skill + '}'; + } +} diff --git a/http-service/src/main/java/net/runelite/http/service/Service.java b/http-service/src/main/java/net/runelite/http/service/Service.java index 6d30f5b64d..2a024b0a8f 100644 --- a/http-service/src/main/java/net/runelite/http/service/Service.java +++ b/http-service/src/main/java/net/runelite/http/service/Service.java @@ -93,7 +93,11 @@ public class Service implements SparkApplication get("/version", (request, response) -> RuneliteAPI.getVersion()); get("/update-check", updateCheck::check, transformer); - get("/hiscore", hiscores::lookup, transformer); + path("/hiscore", () -> + { + get("", hiscores::lookup, transformer); + get("/:skill", hiscores::singleSkillLookup, transformer); + }); get("/worlds", worlds::listWorlds, transformer); post("/xtea", xtea::submit); get("/xtea/:rev", xtea::get, transformer); diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreResultBuilder.java b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreResultBuilder.java index c082e4816e..1d8034ab38 100644 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreResultBuilder.java +++ b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreResultBuilder.java @@ -24,58 +24,59 @@ */ package net.runelite.http.service.hiscore; -import java.util.function.Consumer; +import java.util.ArrayList; +import java.util.List; import net.runelite.http.api.hiscore.HiscoreResult; import net.runelite.http.api.hiscore.Skill; public class HiscoreResultBuilder { - public static final int NUM_SKILLS = 24; - - private final HiscoreResult result = new HiscoreResult(); - - private final Consumer[] consumers = new Consumer[] - { - (s) -> result.setOverall((Skill) s), - (s) -> result.setAttack((Skill) s), - (s) -> result.setDefence((Skill) s), - (s) -> result.setStrength((Skill) s), - (s) -> result.setHitpoints((Skill) s), - (s) -> result.setRanged((Skill) s), - (s) -> result.setPrayer((Skill) s), - (s) -> result.setMagic((Skill) s), - (s) -> result.setCooking((Skill) s), - (s) -> result.setWoodcutting((Skill) s), - (s) -> result.setFletching((Skill) s), - (s) -> result.setFishing((Skill) s), - (s) -> result.setFiremaking((Skill) s), - (s) -> result.setCrafting((Skill) s), - (s) -> result.setSmithing((Skill) s), - (s) -> result.setMining((Skill) s), - (s) -> result.setHerblore((Skill) s), - (s) -> result.setAgility((Skill) s), - (s) -> result.setThieving((Skill) s), - (s) -> result.setSlayer((Skill) s), - (s) -> result.setFarming((Skill) s), - (s) -> result.setRunecraft((Skill) s), - (s) -> result.setHunter((Skill) s), - (s) -> result.setConstruction((Skill) s), - }; - - private int position; + private String player; + private final List skills = new ArrayList<>(); public void setPlayer(String player) { - result.setPlayer(player); + this.player = player; } public void setNextSkill(Skill skill) { - consumers[position++].accept(skill); + skills.add(skill); + } + + public Skill getSkill(int index) + { + return skills.get(index); } public HiscoreResult build() { - return result; + HiscoreResult hiscoreResult = new HiscoreResult(); + hiscoreResult.setPlayer(player); + hiscoreResult.setOverall(skills.get(0)); + hiscoreResult.setAttack(skills.get(1)); + hiscoreResult.setDefence(skills.get(2)); + hiscoreResult.setStrength(skills.get(3)); + hiscoreResult.setHitpoints(skills.get(4)); + hiscoreResult.setRanged(skills.get(5)); + hiscoreResult.setPrayer(skills.get(6)); + hiscoreResult.setMagic(skills.get(7)); + hiscoreResult.setCooking(skills.get(8)); + hiscoreResult.setWoodcutting(skills.get(9)); + hiscoreResult.setFletching(skills.get(10)); + hiscoreResult.setFishing(skills.get(11)); + hiscoreResult.setFiremaking(skills.get(12)); + hiscoreResult.setCrafting(skills.get(13)); + hiscoreResult.setSmithing(skills.get(14)); + hiscoreResult.setMining(skills.get(15)); + hiscoreResult.setHerblore(skills.get(16)); + hiscoreResult.setAgility(skills.get(17)); + hiscoreResult.setThieving(skills.get(18)); + hiscoreResult.setSlayer(skills.get(19)); + hiscoreResult.setFarming(skills.get(20)); + hiscoreResult.setRunecraft(skills.get(21)); + hiscoreResult.setHunter(skills.get(22)); + hiscoreResult.setConstruction(skills.get(23)); + return hiscoreResult; } } diff --git a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java index 72146ca478..e6f0ff7234 100644 --- a/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java +++ b/http-service/src/main/java/net/runelite/http/service/hiscore/HiscoreService.java @@ -27,7 +27,9 @@ package net.runelite.http.service.hiscore; import java.io.IOException; import net.runelite.http.api.RuneliteAPI; import net.runelite.http.api.hiscore.HiscoreResult; +import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; import net.runelite.http.api.hiscore.Skill; +import net.runelite.http.api.hiscore.HiscoreSkill; import okhttp3.HttpUrl; import okhttp3.ResponseBody; import org.apache.commons.csv.CSVFormat; @@ -42,10 +44,8 @@ public class HiscoreService private HttpUrl url = RUNESCAPE_HISCORE_SERVICE; - public HiscoreResult lookup(Request request, Response response) throws IOException + private HiscoreResultBuilder lookup(String username) throws IOException { - String username = request.queryParams("username"); - HttpUrl hiscoreUrl = url.newBuilder() .addQueryParameter("player", username) .build(); @@ -71,7 +71,7 @@ public class HiscoreService for (CSVRecord record : parser.getRecords()) { - if (count++ >= HiscoreResultBuilder.NUM_SKILLS) + if (count++ >= HiscoreSkill.values().length) { break; // rest is other things? } @@ -85,8 +85,38 @@ public class HiscoreService hiscoreBuilder.setNextSkill(skill); } + return hiscoreBuilder; + } + + public HiscoreResult lookup(Request request, Response response) throws IOException + { + String username = request.queryParams("username"); + HiscoreResultBuilder result = lookup(username); + response.type("application/json"); - return hiscoreBuilder.build(); + return result.build(); + } + + public SingleHiscoreSkillResult singleSkillLookup(Request request, Response response) throws IOException + { + String username = request.queryParams("username"); + String skillName = request.params("skill"); + + HiscoreSkill skill = HiscoreSkill.valueOf(skillName.toUpperCase()); + + // RS api only supports looking up all stats + HiscoreResultBuilder result = lookup(username); + + // Find the skill to return + Skill requested = result.getSkill(skill.ordinal()); + + SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult(); + skillResult.setPlayer(username); + skillResult.setSkillName(skillName); + skillResult.setSkill(requested); + + response.type("application/json"); + return skillResult; } public HttpUrl getUrl()