Make HiscoreClient call the OSRS hiscore API directly
This commit is contained in:
@@ -53,6 +53,11 @@
|
|||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-csv</artifactId>
|
||||||
|
<version>1.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
|
|||||||
@@ -24,51 +24,28 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.http.api.hiscore;
|
package net.runelite.http.api.hiscore;
|
||||||
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
import org.slf4j.Logger;
|
import org.apache.commons.csv.CSVFormat;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.apache.commons.csv.CSVParser;
|
||||||
|
import org.apache.commons.csv.CSVRecord;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class HiscoreClient
|
public class HiscoreClient
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(HiscoreClient.class);
|
|
||||||
|
|
||||||
public HiscoreResult lookup(String username, HiscoreEndpoint endpoint) throws IOException
|
public HiscoreResult lookup(String username, HiscoreEndpoint endpoint) throws IOException
|
||||||
{
|
{
|
||||||
HttpUrl.Builder builder = RuneLiteAPI.getApiBase().newBuilder()
|
return lookup(username, endpoint.getHiscoreURL());
|
||||||
.addPathSegment("hiscore")
|
}
|
||||||
.addPathSegment(endpoint.name().toLowerCase())
|
|
||||||
.addQueryParameter("username", username);
|
|
||||||
|
|
||||||
HttpUrl url = builder.build();
|
public HiscoreResult lookup(String username, HttpUrl endpoint) throws IOException
|
||||||
|
{
|
||||||
logger.debug("Built URI: {}", url);
|
HiscoreResultBuilder resultBuilder = lookupUsername(username, endpoint);
|
||||||
|
return resultBuilder.build();
|
||||||
Request request = new Request.Builder()
|
|
||||||
.url(url)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
|
||||||
{
|
|
||||||
if (!response.isSuccessful())
|
|
||||||
{
|
|
||||||
logger.debug("unsuccessful lookup for {}", username);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputStream in = response.body().byteStream();
|
|
||||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), HiscoreResult.class);
|
|
||||||
}
|
|
||||||
catch (JsonParseException ex)
|
|
||||||
{
|
|
||||||
throw new IOException(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HiscoreResult lookup(String username) throws IOException
|
public HiscoreResult lookup(String username) throws IOException
|
||||||
@@ -78,39 +55,82 @@ public class HiscoreClient
|
|||||||
|
|
||||||
public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill, HiscoreEndpoint endpoint) throws IOException
|
public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill, HiscoreEndpoint endpoint) throws IOException
|
||||||
{
|
{
|
||||||
HttpUrl.Builder builder = RuneLiteAPI.getApiBase().newBuilder()
|
HiscoreResultBuilder resultBuilder = lookupUsername(username, endpoint.getHiscoreURL());
|
||||||
.addPathSegment("hiscore")
|
HiscoreResult result = resultBuilder.build();
|
||||||
.addPathSegment(endpoint.name())
|
|
||||||
.addPathSegment(skill.toString().toLowerCase())
|
|
||||||
.addQueryParameter("username", username);
|
|
||||||
|
|
||||||
HttpUrl url = builder.build();
|
Skill requested = result.getSkill(skill);
|
||||||
|
SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult();
|
||||||
logger.debug("Built URI: {}", url);
|
skillResult.setPlayer(username);
|
||||||
|
skillResult.setSkillName(skill.getName());
|
||||||
Request request = new Request.Builder()
|
skillResult.setSkill(requested);
|
||||||
.url(url)
|
return skillResult;
|
||||||
.build();
|
|
||||||
|
|
||||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
|
||||||
{
|
|
||||||
if (!response.isSuccessful())
|
|
||||||
{
|
|
||||||
logger.debug("unsuccessful lookup for {}", username);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputStream in = response.body().byteStream();
|
|
||||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), SingleHiscoreSkillResult.class);
|
|
||||||
}
|
|
||||||
catch (JsonParseException ex)
|
|
||||||
{
|
|
||||||
throw new IOException(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill) throws IOException
|
public SingleHiscoreSkillResult lookup(String username, HiscoreSkill skill) throws IOException
|
||||||
{
|
{
|
||||||
return lookup(username, skill, HiscoreEndpoint.NORMAL);
|
return lookup(username, skill, HiscoreEndpoint.NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HiscoreResultBuilder lookupUsername(String username, HttpUrl hiscoreUrl) throws IOException
|
||||||
|
{
|
||||||
|
HttpUrl url = hiscoreUrl.newBuilder()
|
||||||
|
.addQueryParameter("player", username)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
log.debug("Built URL {}", url);
|
||||||
|
|
||||||
|
Request okrequest = new Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String responseStr;
|
||||||
|
|
||||||
|
try (Response okresponse = RuneLiteAPI.CLIENT.newCall(okrequest).execute())
|
||||||
|
{
|
||||||
|
if (!okresponse.isSuccessful())
|
||||||
|
{
|
||||||
|
switch (okresponse.code())
|
||||||
|
{
|
||||||
|
case 404:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
default:
|
||||||
|
throw new IOException("Error retrieving data from Jagex Hiscores: " + okresponse.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
responseStr = okresponse.body().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVParser parser = CSVParser.parse(responseStr, CSVFormat.DEFAULT);
|
||||||
|
|
||||||
|
HiscoreResultBuilder hiscoreBuilder = new HiscoreResultBuilder();
|
||||||
|
hiscoreBuilder.setPlayer(username);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (CSVRecord record : parser.getRecords())
|
||||||
|
{
|
||||||
|
if (count++ >= HiscoreSkill.values().length)
|
||||||
|
{
|
||||||
|
log.warn("Jagex Hiscore API returned unexpected data");
|
||||||
|
break; // rest is other things?
|
||||||
|
}
|
||||||
|
|
||||||
|
// rank, level, experience
|
||||||
|
int rank = Integer.parseInt(record.get(0));
|
||||||
|
int level = Integer.parseInt(record.get(1));
|
||||||
|
|
||||||
|
// items that are not skills do not have an experience parameter
|
||||||
|
long experience = -1;
|
||||||
|
if (record.size() == 3)
|
||||||
|
{
|
||||||
|
experience = Long.parseLong(record.get(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
Skill skill = new Skill(rank, level, experience);
|
||||||
|
hiscoreBuilder.setNextSkill(skill);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hiscoreBuilder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.http.service.hiscore;
|
package net.runelite.http.api.hiscore;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -83,11 +83,6 @@
|
|||||||
<artifactId>sql2o</artifactId>
|
<artifactId>sql2o</artifactId>
|
||||||
<version>1.5.4</version>
|
<version>1.5.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-csv</artifactId>
|
|
||||||
<version>1.4</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ public class HiscoreController
|
|||||||
@RequestMapping("/{endpoint}")
|
@RequestMapping("/{endpoint}")
|
||||||
public HiscoreResult lookup(@PathVariable HiscoreEndpoint endpoint, @RequestParam String username) throws ExecutionException
|
public HiscoreResult lookup(@PathVariable HiscoreEndpoint endpoint, @RequestParam String username) throws ExecutionException
|
||||||
{
|
{
|
||||||
HiscoreResultBuilder resultBuilder = hiscoreService.lookupUsername(username, endpoint);
|
HiscoreResult result = hiscoreService.lookupUsername(username, endpoint);
|
||||||
HiscoreResult result = resultBuilder.build();
|
|
||||||
|
|
||||||
// Submit to xp tracker?
|
// Submit to xp tracker?
|
||||||
switch (endpoint)
|
switch (endpoint)
|
||||||
@@ -75,10 +74,10 @@ public class HiscoreController
|
|||||||
HiscoreSkill skill = HiscoreSkill.valueOf(skillName.toUpperCase());
|
HiscoreSkill skill = HiscoreSkill.valueOf(skillName.toUpperCase());
|
||||||
|
|
||||||
// RS api only supports looking up all stats
|
// RS api only supports looking up all stats
|
||||||
HiscoreResultBuilder result = hiscoreService.lookupUsername(username, endpoint);
|
HiscoreResult result = hiscoreService.lookupUsername(username, endpoint);
|
||||||
|
|
||||||
// Find the skill to return
|
// Find the skill to return
|
||||||
Skill requested = result.getSkill(skill.ordinal());
|
Skill requested = result.getSkill(skill);
|
||||||
|
|
||||||
SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult();
|
SingleHiscoreSkillResult skillResult = new SingleHiscoreSkillResult();
|
||||||
skillResult.setPlayer(username);
|
skillResult.setPlayer(username);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.http.service.hiscore;
|
package net.runelite.http.service.hiscore;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
@@ -31,104 +32,38 @@ import java.io.IOException;
|
|||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
import net.runelite.http.api.hiscore.HiscoreClient;
|
||||||
import net.runelite.http.api.hiscore.HiscoreEndpoint;
|
import net.runelite.http.api.hiscore.HiscoreEndpoint;
|
||||||
import net.runelite.http.api.hiscore.HiscoreSkill;
|
import net.runelite.http.api.hiscore.HiscoreResult;
|
||||||
import net.runelite.http.api.hiscore.Skill;
|
|
||||||
import net.runelite.http.service.util.exception.InternalServerErrorException;
|
|
||||||
import net.runelite.http.service.util.exception.NotFoundException;
|
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.Response;
|
|
||||||
import org.apache.commons.csv.CSVFormat;
|
|
||||||
import org.apache.commons.csv.CSVParser;
|
|
||||||
import org.apache.commons.csv.CSVRecord;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class HiscoreService
|
public class HiscoreService
|
||||||
{
|
{
|
||||||
private final LoadingCache<HiscoreKey, HiscoreResultBuilder> hiscoreCache = CacheBuilder.newBuilder()
|
private final HiscoreClient hiscoreClient = new HiscoreClient();
|
||||||
|
private final LoadingCache<HiscoreKey, HiscoreResult> hiscoreCache = CacheBuilder.newBuilder()
|
||||||
.maximumSize(128)
|
.maximumSize(128)
|
||||||
.expireAfterWrite(1, TimeUnit.MINUTES)
|
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||||
.build(
|
.build(
|
||||||
new CacheLoader<HiscoreKey, HiscoreResultBuilder>()
|
new CacheLoader<HiscoreKey, HiscoreResult>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public HiscoreResultBuilder load(HiscoreKey key) throws IOException
|
public HiscoreResult load(HiscoreKey key) throws IOException
|
||||||
{
|
{
|
||||||
return lookupUsername(key.getUsername(), key.getEndpoint().getHiscoreURL());
|
return hiscoreClient.lookup(key.getUsername(), key.getEndpoint());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
public HiscoreResultBuilder lookupUsername(String username, HiscoreEndpoint endpoint) throws ExecutionException
|
@VisibleForTesting
|
||||||
|
HiscoreResult lookupUsername(String username, HttpUrl httpUrl) throws IOException
|
||||||
|
{
|
||||||
|
return hiscoreClient.lookup(username, httpUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HiscoreResult lookupUsername(String username, HiscoreEndpoint endpoint) throws ExecutionException
|
||||||
{
|
{
|
||||||
return hiscoreCache.get(new HiscoreKey(username, endpoint));
|
return hiscoreCache.get(new HiscoreKey(username, endpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
HiscoreResultBuilder lookupUsername(String username, HttpUrl hiscoreUrl) throws IOException
|
|
||||||
{
|
|
||||||
HttpUrl url = hiscoreUrl.newBuilder()
|
|
||||||
.addQueryParameter("player", username)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
log.debug("Built URL {}", url);
|
|
||||||
|
|
||||||
Request okrequest = new Request.Builder()
|
|
||||||
.url(url)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
String responseStr;
|
|
||||||
|
|
||||||
try (Response okresponse = RuneLiteAPI.CLIENT.newCall(okrequest).execute())
|
|
||||||
{
|
|
||||||
if (!okresponse.isSuccessful())
|
|
||||||
{
|
|
||||||
switch (HttpStatus.valueOf(okresponse.code()))
|
|
||||||
{
|
|
||||||
case NOT_FOUND:
|
|
||||||
throw new NotFoundException();
|
|
||||||
default:
|
|
||||||
throw new InternalServerErrorException("Error retrieving data from Jagex Hiscores: " + okresponse.message());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
responseStr = okresponse.body().string();
|
|
||||||
}
|
|
||||||
|
|
||||||
CSVParser parser = CSVParser.parse(responseStr, CSVFormat.DEFAULT);
|
|
||||||
|
|
||||||
HiscoreResultBuilder hiscoreBuilder = new HiscoreResultBuilder();
|
|
||||||
hiscoreBuilder.setPlayer(username);
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
for (CSVRecord record : parser.getRecords())
|
|
||||||
{
|
|
||||||
if (count++ >= HiscoreSkill.values().length)
|
|
||||||
{
|
|
||||||
log.warn("Jagex Hiscore API returned unexpected data");
|
|
||||||
break; // rest is other things?
|
|
||||||
}
|
|
||||||
|
|
||||||
// rank, level, experience
|
|
||||||
int rank = Integer.parseInt(record.get(0));
|
|
||||||
int level = Integer.parseInt(record.get(1));
|
|
||||||
|
|
||||||
// items that are not skills do not have an experience parameter
|
|
||||||
long experience = -1;
|
|
||||||
if (record.size() == 3)
|
|
||||||
{
|
|
||||||
experience = Long.parseLong(record.get(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
Skill skill = new Skill(rank, level, experience);
|
|
||||||
hiscoreBuilder.setNextSkill(skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hiscoreBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import net.runelite.http.api.hiscore.HiscoreEndpoint;
|
import net.runelite.http.api.hiscore.HiscoreEndpoint;
|
||||||
import net.runelite.http.api.hiscore.HiscoreResult;
|
import net.runelite.http.api.hiscore.HiscoreResult;
|
||||||
import net.runelite.http.api.xp.XpData;
|
import net.runelite.http.api.xp.XpData;
|
||||||
import net.runelite.http.service.hiscore.HiscoreResultBuilder;
|
|
||||||
import net.runelite.http.service.hiscore.HiscoreService;
|
import net.runelite.http.service.hiscore.HiscoreService;
|
||||||
import net.runelite.http.service.xp.beans.PlayerEntity;
|
import net.runelite.http.service.xp.beans.PlayerEntity;
|
||||||
import net.runelite.http.service.xp.beans.XpEntity;
|
import net.runelite.http.service.xp.beans.XpEntity;
|
||||||
@@ -53,8 +52,7 @@ public class XpTrackerService
|
|||||||
|
|
||||||
public void update(String username) throws ExecutionException
|
public void update(String username) throws ExecutionException
|
||||||
{
|
{
|
||||||
HiscoreResultBuilder hiscoreResultBuilder = hiscoreService.lookupUsername(username, HiscoreEndpoint.NORMAL);
|
HiscoreResult hiscoreResult = hiscoreService.lookupUsername(username, HiscoreEndpoint.NORMAL);
|
||||||
HiscoreResult hiscoreResult = hiscoreResultBuilder.build();
|
|
||||||
update(username, hiscoreResult);
|
update(username, hiscoreResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class HiscoreServiceTest
|
|||||||
{
|
{
|
||||||
HiscoreTestService hiscores = new HiscoreTestService(server.url("/"));
|
HiscoreTestService hiscores = new HiscoreTestService(server.url("/"));
|
||||||
|
|
||||||
HiscoreResult result = hiscores.lookupUsername("zezima", HiscoreEndpoint.NORMAL).build();
|
HiscoreResult result = hiscores.lookupUsername("zezima", HiscoreEndpoint.NORMAL.getHiscoreURL());
|
||||||
|
|
||||||
Assert.assertEquals(50, result.getAttack().getLevel());
|
Assert.assertEquals(50, result.getAttack().getLevel());
|
||||||
Assert.assertEquals(159727L, result.getFishing().getExperience());
|
Assert.assertEquals(159727L, result.getFishing().getExperience());
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ package net.runelite.http.service.hiscore;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import net.runelite.http.api.hiscore.HiscoreEndpoint;
|
import net.runelite.http.api.hiscore.HiscoreResult;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
|
|
||||||
class HiscoreTestService extends HiscoreService
|
class HiscoreTestService extends HiscoreService
|
||||||
@@ -40,15 +40,8 @@ class HiscoreTestService extends HiscoreService
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HiscoreResultBuilder lookupUsername(String username, HiscoreEndpoint endpoint) throws ExecutionException
|
public HiscoreResult lookupUsername(String username, HttpUrl endpoint) throws IOException
|
||||||
{
|
{
|
||||||
try
|
return super.lookupUsername(username, testUrl);
|
||||||
{
|
|
||||||
return super.lookupUsername(username, testUrl);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new ExecutionException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user