Hiscore feature expansion (#152)

* Add remaining Hiscore parameters to HiscoreSkill

* Add remaining Hiscore parameters to HiscoreResult

* Add remaining Hiscore parameters to HiscoreResultBuilder

* Add new Hiscore panel icons (from offical Hiscore website, so they don't match very well) and subpanel for Clue Scrolls, Bounty Hunter - Hunter, Bounty Hunter - Rogue, and Last Man Standing

* Add logic to catch unranked hiscores and display them properly. Not currently checking for combat level calculations, but other cases should be covered.

* Make HiscoreService and HiscoreClient aware of different hiscore endpoints

* Add Spring Editor to convert path variable String to enum, add pretty versions of HiscoreEndpoint names, add new icons for endpoint selection

* Fix HiscoreEndpoint.valueof failing silently and preventing lookup, update HiscoreService tests, add Hiscore endpoint selection buttons to HiscorePanel

* Replace HiscorePanel skill icons with smaller versions from the official hiscore website

* Fix details listing rank instead of experience

* Fix details listing rank instead of experience, fix skill panels not being cleared when selecting a different hiscore category, make HiscoreService respond 404  when a Hiscore entry is not found instead of 500.

* Fix skill panels not being cleared when selecting a different hiscore category, make HiscoreService respond 404  when a Hiscore entry is not found instead of 500.

* Revert changing RuneliteAPI base URL, those changes should not have been committed (local testing only)

* Add ClueScrollAll and ClueScrollMaster to HiscoreService tests.

* Style cleanup and relocate NotFoundException to http-service package

* Use relative path for small skill icons

* Move Jagex Hiscore urls from HiscoreService to HiscoreEndpoint

* Create new util package in http-service for common exceptions and Spring converters, clean up HiscoreService by streamlining error handling and removing methods for old unit test

* Change HiscoreService unit test to use new HiscoreTestService subclass which handles setting the test URL

* Change HiscoreEndpoint hiscoreUrls to HttpUrl instead of String

* Cleanup formatting, remove unused http-service exception

* http-api: cleanup HiscoreEndpoint
This commit is contained in:
Julian Nowaczek
2017-09-16 15:28:42 -05:00
committed by Adam
parent 10afba7017
commit b12bd04764
59 changed files with 692 additions and 207 deletions

View File

@@ -40,10 +40,11 @@ public class HiscoreClient
{
private static final Logger logger = LoggerFactory.getLogger(HiscoreClient.class);
public HiscoreResult lookup(String username) throws IOException
public HiscoreResult lookup(String username, HiscoreEndpoint endpoint) throws IOException
{
HttpUrl.Builder builder = RuneliteAPI.getApiBase().newBuilder()
.addPathSegment("hiscore")
.addPathSegment(endpoint.name().toLowerCase())
.addQueryParameter("username", username);
HttpUrl url = builder.build();
@@ -67,10 +68,16 @@ public class HiscoreClient
}
}
public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill) throws IOException
public HiscoreResult lookup(String username) throws IOException
{
return lookup(username, HiscoreEndpoint.NORMAL);
}
public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill, HiscoreEndpoint endpoint) throws IOException
{
HttpUrl.Builder builder = RuneliteAPI.getApiBase().newBuilder()
.addPathSegment("hiscore")
.addPathSegment(endpoint.name())
.addPathSegment(skill.toString().toLowerCase())
.addQueryParameter("username", username);
@@ -94,4 +101,9 @@ public class HiscoreClient
throw new IOException(ex);
}
}
public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill) throws IOException
{
return lookup(username, skill, HiscoreEndpoint.NORMAL);
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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 HOLDER 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 okhttp3.HttpUrl;
public enum HiscoreEndpoint
{
NORMAL("Normal", "http://services.runescape.com/m=hiscore_oldschool/index_lite.ws"),
IRONMAN("Ironman", "http://services.runescape.com/m=hiscore_oldschool_ironman/index_lite.ws"),
HARDCORE_IRONMAN("Hardcore Ironman", "http://services.runescape.com/m=hiscore_oldschool_hardcore_ironman/index_lite.ws"),
ULTIMATE_IRONMAN("Ultimate Ironman", "http://services.runescape.com/m=hiscore_oldschool_ultimate/index_lite.ws"),
DEADMAN("Deadman", "http://services.runescape.com/m=hiscore_oldschool_deadman/index_lite.ws"),
SEASONAL_DEADMAN("Seasonal Deadman", "http://services.runescape.com/m=hiscore_oldschool_seasonal/index_lite.ws");
private final String name;
private final HttpUrl hiscoreURL;
HiscoreEndpoint(String name, String hiscoreURL)
{
this.name = name;
this.hiscoreURL = HttpUrl.parse(hiscoreURL);
}
public String getName()
{
return name;
}
public HttpUrl getHiscoreURL()
{
return hiscoreURL;
}
}

View File

@@ -53,6 +53,15 @@ public class HiscoreResult
private Skill runecraft;
private Skill hunter;
private Skill construction;
private Skill clueScrollEasy;
private Skill clueScrollMedium;
private Skill clueScrollAll;
private Skill bountyHunterRogue;
private Skill bountyHunterHunter;
private Skill clueScrollHard;
private Skill lastManStanding;
private Skill clueScrollElite;
private Skill clueScrollMaster;
public String getPlayer()
{
@@ -304,6 +313,96 @@ public class HiscoreResult
this.construction = construction;
}
public Skill getClueScrollEasy()
{
return clueScrollEasy;
}
public void setClueScrollEasy(Skill clueScrollEasy)
{
this.clueScrollEasy = clueScrollEasy;
}
public Skill getClueScrollMedium()
{
return clueScrollMedium;
}
public void setClueScrollMedium(Skill clueScrollMedium)
{
this.clueScrollMedium = clueScrollMedium;
}
public Skill getClueScrollAll()
{
return clueScrollAll;
}
public void setClueScrollAll(Skill clueScrollAll)
{
this.clueScrollAll = clueScrollAll;
}
public Skill getBountyHunterRogue()
{
return bountyHunterRogue;
}
public void setBountyHunterRogue(Skill bountyHunterRogue)
{
this.bountyHunterRogue = bountyHunterRogue;
}
public Skill getBountyHunterHunter()
{
return bountyHunterHunter;
}
public void setBountyHunterHunter(Skill bountyHunterHunter)
{
this.bountyHunterHunter = bountyHunterHunter;
}
public Skill getClueScrollHard()
{
return clueScrollHard;
}
public void setClueScrollHard(Skill clueScrollHard)
{
this.clueScrollHard = clueScrollHard;
}
public Skill getLastManStanding()
{
return lastManStanding;
}
public void setLastManStanding(Skill lastManStanding)
{
this.lastManStanding = lastManStanding;
}
public Skill getClueScrollElite()
{
return clueScrollElite;
}
public void setClueScrollElite(Skill clueScrollElite)
{
this.clueScrollElite = clueScrollElite;
}
public Skill getClueScrollMaster()
{
return clueScrollMaster;
}
public void setClueScrollMaster(Skill clueScrollMaster)
{
this.clueScrollMaster = clueScrollMaster;
}
public Skill getSkill(HiscoreSkill skill)
{
switch (skill)
@@ -356,9 +455,27 @@ public class HiscoreResult
return getConstruction();
case OVERALL:
return getOverall();
case CLUE_SCROLL_EASY:
return getClueScrollEasy();
case CLUE_SCROLL_MEDIUM:
return getClueScrollMedium();
case CLUE_SCROLL_ALL:
return getClueScrollAll();
case BOUNTY_HUNTER_ROGUE:
return getBountyHunterRogue();
case BOUNTY_HUNTER_HUNTER:
return getBountyHunterHunter();
case CLUE_SCROLL_HARD:
return getClueScrollHard();
case LAST_MAN_STANDING:
return getLastManStanding();
case CLUE_SCROLL_ELITE:
return getClueScrollElite();
case CLUE_SCROLL_MASTER:
return getClueScrollMaster();
}
throw new IllegalArgumentException("Invalid skill");
throw new IllegalArgumentException("Invalid hiscore item");
}
@Override
@@ -390,6 +507,15 @@ public class HiscoreResult
hash = 29 * hash + Objects.hashCode(this.runecraft);
hash = 29 * hash + Objects.hashCode(this.hunter);
hash = 29 * hash + Objects.hashCode(this.construction);
hash = 29 * hash + Objects.hashCode(this.clueScrollEasy);
hash = 29 * hash + Objects.hashCode(this.clueScrollMedium);
hash = 29 * hash + Objects.hashCode(this.clueScrollAll);
hash = 29 * hash + Objects.hashCode(this.bountyHunterRogue);
hash = 29 * hash + Objects.hashCode(this.bountyHunterHunter);
hash = 29 * hash + Objects.hashCode(this.clueScrollHard);
hash = 29 * hash + Objects.hashCode(this.lastManStanding);
hash = 29 * hash + Objects.hashCode(this.clueScrollElite);
hash = 29 * hash + Objects.hashCode(this.clueScrollMaster);
return hash;
}
@@ -509,12 +635,48 @@ public class HiscoreResult
{
return false;
}
if (!Objects.equals(this.clueScrollEasy, other.clueScrollEasy))
{
return false;
}
if (!Objects.equals(this.clueScrollMedium, other.clueScrollMedium))
{
return false;
}
if (!Objects.equals(this.clueScrollAll, other.clueScrollAll))
{
return false;
}
if (!Objects.equals(this.bountyHunterRogue, other.bountyHunterRogue))
{
return false;
}
if (!Objects.equals(this.bountyHunterHunter, other.bountyHunterHunter))
{
return false;
}
if (!Objects.equals(this.clueScrollHard, other.clueScrollHard))
{
return false;
}
if (!Objects.equals(this.lastManStanding, other.lastManStanding))
{
return false;
}
if (!Objects.equals(this.clueScrollElite, other.clueScrollElite))
{
return false;
}
if (!Objects.equals(this.clueScrollMaster, other.clueScrollMaster))
{
return false;
}
return true;
}
@Override
public String toString()
{
return "HiscoreResult{" + "player=" + player + ", 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 + '}';
return "HiscoreResult{" + "player=" + player + ", 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 + ", clueScrollEasy=" + clueScrollEasy + ", clueScrollMedium=" + clueScrollMedium + ", clueScrollAll=" + clueScrollAll + ", bountyHunterRogue=" + bountyHunterRogue + ", bountyHunterHunter=" + bountyHunterHunter + ", clueScrollHard=" + clueScrollHard + ", lastManStanding=" + lastManStanding + ", clueScrollElite=" + clueScrollElite + ", clueScrollMaster=" + clueScrollMaster + '}';
}
}

View File

@@ -49,7 +49,16 @@ public enum HiscoreSkill
FARMING("Farming"),
RUNECRAFT("Runecraft"),
HUNTER("Hunter"),
CONSTRUCTION("Construction");
CONSTRUCTION("Construction"),
CLUE_SCROLL_EASY("Clue Scrolls (easy)"),
CLUE_SCROLL_MEDIUM("Clue Scrolls (medium)"),
CLUE_SCROLL_ALL("Clue Scrolls (all)"),
BOUNTY_HUNTER_ROGUE("Bounty Hunter - Rogue"),
BOUNTY_HUNTER_HUNTER("Bounty Hunter - Hunter"),
CLUE_SCROLL_HARD("Clue Scrolls (hard)"),
LAST_MAN_STANDING("Last Man Standing"),
CLUE_SCROLL_ELITE("Clue Scrolls (elite)"),
CLUE_SCROLL_MASTER("Clue Scrolls (master)");
private final String name;