Added support for player lookup on official hiscores.
This commit is contained in:
9
osrs-toolbox/APIs/Runescape/DataModels/Activity.cs
Normal file
9
osrs-toolbox/APIs/Runescape/DataModels/Activity.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace osrs_toolbox
|
||||||
|
{
|
||||||
|
public class Activity : IPlayerInfoProperty
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int Rank { get; set; }
|
||||||
|
public int Score { get; set; }
|
||||||
|
}
|
||||||
|
}
|
9
osrs-toolbox/APIs/Runescape/DataModels/Boss.cs
Normal file
9
osrs-toolbox/APIs/Runescape/DataModels/Boss.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace osrs_toolbox
|
||||||
|
{
|
||||||
|
public class Boss : IPlayerInfoProperty
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int Rank { get; set; }
|
||||||
|
public int Kills { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
namespace osrs_toolbox
|
||||||
|
{
|
||||||
|
public interface IPlayerInfoProperty
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
190
osrs-toolbox/APIs/Runescape/DataModels/PlayerInfo.cs
Normal file
190
osrs-toolbox/APIs/Runescape/DataModels/PlayerInfo.cs
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace osrs_toolbox
|
||||||
|
{
|
||||||
|
public class PlayerInfo
|
||||||
|
{
|
||||||
|
private static readonly Skill InitialSkillState = new Skill { Rank = -1, Level = 1, Experience = 1 };
|
||||||
|
private static readonly Activity InitialActivityState = new Activity { Rank = -1, Score = -1 };
|
||||||
|
private static readonly Boss InitialBossState = new Boss { Rank = -1, Kills = -1 };
|
||||||
|
|
||||||
|
public string Name { get; set; } = "";
|
||||||
|
public PlayerInfoStatus Status { get; internal set; } = PlayerInfoStatus.Unknown;
|
||||||
|
public PlayerType AccountType { get; internal set; } = PlayerType.Unknown;
|
||||||
|
|
||||||
|
//skills
|
||||||
|
public Skill Overall { get; set; } = InitialSkillState;
|
||||||
|
public Skill Attack { get; set; } = InitialSkillState;
|
||||||
|
public Skill Defence { get; set; } = InitialSkillState;
|
||||||
|
public Skill Strength { get; set; } = InitialSkillState;
|
||||||
|
public Skill Hitpoints { get; set; } = InitialSkillState;
|
||||||
|
public Skill Ranged { get; set; } = InitialSkillState;
|
||||||
|
public Skill Prayer { get; set; } = InitialSkillState;
|
||||||
|
public Skill Magic { get; set; } = InitialSkillState;
|
||||||
|
public Skill Cooking { get; set; } = InitialSkillState;
|
||||||
|
public Skill Woodcutting { get; set; } = InitialSkillState;
|
||||||
|
public Skill Fletching { get; set; } = InitialSkillState;
|
||||||
|
public Skill Fishing { get; set; } = InitialSkillState;
|
||||||
|
public Skill Firemaking { get; set; } = InitialSkillState;
|
||||||
|
public Skill Crafting { get; set; } = InitialSkillState;
|
||||||
|
public Skill Smithing { get; set; } = InitialSkillState;
|
||||||
|
public Skill Mining { get; set; } = InitialSkillState;
|
||||||
|
public Skill Herblore { get; set; } = InitialSkillState;
|
||||||
|
public Skill Agility { get; set; } = InitialSkillState;
|
||||||
|
public Skill Thieving { get; set; } = InitialSkillState;
|
||||||
|
public Skill Slayer { get; set; } = InitialSkillState;
|
||||||
|
public Skill Farming { get; set; } = InitialSkillState;
|
||||||
|
public Skill Runecrafting { get; set; } = InitialSkillState;
|
||||||
|
public Skill Hunter { get; set; } = InitialSkillState;
|
||||||
|
public Skill Construction { get; set; } = InitialSkillState;
|
||||||
|
|
||||||
|
//minigames
|
||||||
|
public Activity LeaguePoints { get; set; } = InitialActivityState;
|
||||||
|
public Activity BountyHunterRogues { get; set; } = InitialActivityState;
|
||||||
|
public Activity BountyHunter { get; set; } = InitialActivityState;
|
||||||
|
public Activity BountyHunterRoguesLegacy { get; set; } = InitialActivityState;
|
||||||
|
public Activity BountyHunterLegacy { get; set; } = InitialActivityState;
|
||||||
|
public Activity DeadManMode { get; set; } = InitialActivityState;
|
||||||
|
public Activity TotalCluesScrolls { get; set; } = InitialActivityState;
|
||||||
|
public Activity BeginnerClueScrolls { get; set; } = InitialActivityState;
|
||||||
|
public Activity EasyClueScrolls { get; set; } = InitialActivityState;
|
||||||
|
public Activity MediumClueScrolls { get; set; } = InitialActivityState;
|
||||||
|
public Activity HardClueScrolls { get; set; } = InitialActivityState;
|
||||||
|
public Activity EliteClueScrolls { get; set; } = InitialActivityState;
|
||||||
|
public Activity MasterClueScrolls { get; set; } = InitialActivityState;
|
||||||
|
public Activity LastManStanding { get; set; } = InitialActivityState;
|
||||||
|
public Activity PvPArena { get; set; } = InitialActivityState;
|
||||||
|
public Activity SoulWarsZeal { get; set; } = InitialActivityState;
|
||||||
|
public Activity RiftsClosed { get; set; } = InitialActivityState;
|
||||||
|
|
||||||
|
//bosses
|
||||||
|
public Boss AbyssalSire { get; set; } = InitialBossState;
|
||||||
|
public Boss AlchemicalHydra { get; set; } = InitialBossState;
|
||||||
|
public Boss Artio { get; set; } = InitialBossState;
|
||||||
|
public Boss BarrowsChests { get; set; } = InitialBossState;
|
||||||
|
public Boss Bryophyta { get; set; } = InitialBossState;
|
||||||
|
public Boss Callisto { get; set; } = InitialBossState;
|
||||||
|
public Boss Calvarion { get; set; } = InitialBossState;
|
||||||
|
public Boss Cerberus { get; set; } = InitialBossState;
|
||||||
|
public Boss ChambersofXeric { get; set; } = InitialBossState;
|
||||||
|
public Boss ChambersofXericChallengeMode { get; set; } = InitialBossState;
|
||||||
|
public Boss ChaosElemental { get; set; } = InitialBossState;
|
||||||
|
public Boss ChaosFanatic { get; set; } = InitialBossState;
|
||||||
|
public Boss CommanderZilyana { get; set; } = InitialBossState;
|
||||||
|
public Boss CorporealBeast { get; set; } = InitialBossState;
|
||||||
|
public Boss CrazyArchaeologist { get; set; } = InitialBossState;
|
||||||
|
public Boss DagannothPrime { get; set; } = InitialBossState;
|
||||||
|
public Boss DagannothRex { get; set; } = InitialBossState;
|
||||||
|
public Boss DagannothSupreme { get; set; } = InitialBossState;
|
||||||
|
public Boss DerangedArchaeologist { get; set; } = InitialBossState;
|
||||||
|
public Boss DukeSucellus { get; set; } = InitialBossState;
|
||||||
|
public Boss GeneralGraardor { get; set; } = InitialBossState;
|
||||||
|
public Boss GiantMole { get; set; } = InitialBossState;
|
||||||
|
public Boss GrotesqueGuardians { get; set; } = InitialBossState;
|
||||||
|
public Boss Hespori { get; set; } = InitialBossState;
|
||||||
|
public Boss KalphiteQueen { get; set; } = InitialBossState;
|
||||||
|
public Boss KingBlackDragon { get; set; } = InitialBossState;
|
||||||
|
public Boss Kraken { get; set; } = InitialBossState;
|
||||||
|
public Boss Kree { get; set; } = InitialBossState;
|
||||||
|
public Boss Kril { get; set; } = InitialBossState;
|
||||||
|
public Boss Mimic { get; set; } = InitialBossState;
|
||||||
|
public Boss Nex { get; set; } = InitialBossState;
|
||||||
|
public Boss Nightmare { get; set; } = InitialBossState;
|
||||||
|
public Boss PhosanisNightmare { get; set; } = InitialBossState;
|
||||||
|
public Boss Obor { get; set; } = InitialBossState;
|
||||||
|
public Boss PhantomMuspah { get; set; } = InitialBossState;
|
||||||
|
public Boss Sarachnis { get; set; } = InitialBossState;
|
||||||
|
public Boss Scorpia { get; set; } = InitialBossState;
|
||||||
|
public Boss Skotizo { get; set; } = InitialBossState;
|
||||||
|
public Boss Spindel { get; set; } = InitialBossState;
|
||||||
|
public Boss Tempoross { get; set; } = InitialBossState;
|
||||||
|
public Boss Gauntlet { get; set; } = InitialBossState;
|
||||||
|
public Boss CorruptedGauntlet { get; set; } = InitialBossState;
|
||||||
|
public Boss Leviathan { get; set; } = InitialBossState;
|
||||||
|
public Boss Whisperer { get; set; } = InitialBossState;
|
||||||
|
public Boss TheatreofBlood { get; set; } = InitialBossState;
|
||||||
|
public Boss TheatreofBloodHardMode { get; set; } = InitialBossState;
|
||||||
|
public Boss ThermonuclearSmokeDevil { get; set; } = InitialBossState;
|
||||||
|
public Boss TombsOfAmascut { get; set; } = InitialBossState;
|
||||||
|
public Boss TombsOfAmascutExpertMode { get; set; } = InitialBossState;
|
||||||
|
public Boss Zuk { get; set; } = InitialBossState;
|
||||||
|
public Boss Jad { get; set; } = InitialBossState;
|
||||||
|
public Boss Vardorvis { get; set; } = InitialBossState;
|
||||||
|
public Boss Venenatis { get; set; } = InitialBossState;
|
||||||
|
public Boss Vetion { get; set; } = InitialBossState;
|
||||||
|
public Boss Vorkath { get; set; } = InitialBossState;
|
||||||
|
public Boss Wintertodt { get; set; } = InitialBossState;
|
||||||
|
public Boss Yama { get; set; } = InitialBossState;
|
||||||
|
public Boss Zalcano { get; set; } = InitialBossState;
|
||||||
|
public Boss Zulrah { get; set; } = InitialBossState;
|
||||||
|
|
||||||
|
public PlayerInfo() { }
|
||||||
|
|
||||||
|
//returns all info in a big string.
|
||||||
|
public string GetAllValuesToString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append($"Player Name : {Name} \n");
|
||||||
|
// retrieve the property information of the Player Info Class
|
||||||
|
PropertyInfo[] properties = typeof(PlayerInfo).GetProperties();
|
||||||
|
foreach (PropertyInfo info in properties)
|
||||||
|
{
|
||||||
|
if (info.PropertyType == typeof(Skill) || info.PropertyType == typeof(Activity))
|
||||||
|
{
|
||||||
|
// gets the value of the PropertyInfo (Skill/Minigame) and returns its Properties
|
||||||
|
PropertyInfo[] SkillProperties = info.GetValue(this).GetType().GetProperties();
|
||||||
|
//Skill Name
|
||||||
|
sb.Append($"{info.Name} : ");
|
||||||
|
// Add the Minigame/Skill Properties into the sb
|
||||||
|
foreach (PropertyInfo SkillInfo in SkillProperties)
|
||||||
|
{
|
||||||
|
sb.Append($"{SkillInfo.Name} : {SkillInfo.GetValue(info.GetValue(this))}, ");
|
||||||
|
}
|
||||||
|
sb.Append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
//IEnumerable for looping over all Skills
|
||||||
|
public IEnumerable<Skill> Skills()
|
||||||
|
{
|
||||||
|
PropertyInfo[] properties = typeof(PlayerInfo).GetProperties();
|
||||||
|
|
||||||
|
foreach (PropertyInfo info in properties.Where(info => info.PropertyType == typeof(Skill)))
|
||||||
|
{
|
||||||
|
Skill skill = (Skill)info.GetValue(this, null);
|
||||||
|
yield return skill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//IEnumberable for looping over all Minigames
|
||||||
|
public IEnumerable<Activity> Minigames()
|
||||||
|
{
|
||||||
|
PropertyInfo[] properties = typeof(PlayerInfo).GetProperties();
|
||||||
|
|
||||||
|
foreach (PropertyInfo info in properties.Where(info => info.PropertyType == typeof(Activity)))
|
||||||
|
{
|
||||||
|
Activity skill = (Activity)info.GetValue(this, null);
|
||||||
|
yield return skill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//IEnumberable for looping over all Bosses
|
||||||
|
public IEnumerable<Boss> Bosses()
|
||||||
|
{
|
||||||
|
PropertyInfo[] properties = typeof(PlayerInfo).GetProperties();
|
||||||
|
|
||||||
|
foreach (PropertyInfo info in properties.Where(info => info.PropertyType == typeof(Boss)))
|
||||||
|
{
|
||||||
|
Boss skill = (Boss)info.GetValue(this, null);
|
||||||
|
yield return skill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
namespace osrs_toolbox
|
||||||
|
{
|
||||||
|
public enum PlayerInfoStatus
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
NotFound,
|
||||||
|
Success
|
||||||
|
}
|
||||||
|
}
|
11
osrs-toolbox/APIs/Runescape/DataModels/PlayerType.cs
Normal file
11
osrs-toolbox/APIs/Runescape/DataModels/PlayerType.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace osrs_toolbox
|
||||||
|
{
|
||||||
|
public enum PlayerType
|
||||||
|
{
|
||||||
|
Main,
|
||||||
|
Ironman,
|
||||||
|
HardcoreIronman,
|
||||||
|
UltimateIronman,
|
||||||
|
Unknown
|
||||||
|
}
|
||||||
|
}
|
10
osrs-toolbox/APIs/Runescape/DataModels/Skill.cs
Normal file
10
osrs-toolbox/APIs/Runescape/DataModels/Skill.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace osrs_toolbox
|
||||||
|
{
|
||||||
|
public class Skill : IPlayerInfoProperty
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int Rank { get; set; }
|
||||||
|
public int Level { get; set; }
|
||||||
|
public int Experience { get; set; }
|
||||||
|
}
|
||||||
|
}
|
167
osrs-toolbox/APIs/Runescape/PlayerInfoService.cs
Normal file
167
osrs-toolbox/APIs/Runescape/PlayerInfoService.cs
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace osrs_toolbox
|
||||||
|
{
|
||||||
|
public class PlayerInfoService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
private bool _throwMismatchException;
|
||||||
|
|
||||||
|
internal bool ThrowMismatchException
|
||||||
|
{
|
||||||
|
get => _throwMismatchException;
|
||||||
|
set => _throwMismatchException = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerInfoService(HttpClient httpClient, bool throwMismatchException = true)
|
||||||
|
{
|
||||||
|
_httpClient = httpClient;
|
||||||
|
_throwMismatchException = throwMismatchException;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PlayerInfo> GetPlayerInfoAsync(string userName)
|
||||||
|
{
|
||||||
|
bool playerFound = false;
|
||||||
|
var playerInfo = new PlayerInfo { Name = userName };
|
||||||
|
|
||||||
|
//HttpResponseMessage response = null;
|
||||||
|
HttpResponseMessage response = await _httpClient.GetAsync("https://secure.runescape.com/m=hiscore_oldschool/index_lite.ws?player=" + userName).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (response.StatusCode == HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
playerInfo.Status = PlayerInfoStatus.NotFound;
|
||||||
|
return playerInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerInfo mainPlayerInfo = new PlayerInfo { Name = userName };
|
||||||
|
PlayerInfo ironPlayerInfo = new PlayerInfo { Name = userName };
|
||||||
|
PlayerInfo hcimPlayerInfo = new PlayerInfo { Name = userName };
|
||||||
|
PlayerInfo uimPlayerInfo = new PlayerInfo { Name = userName };
|
||||||
|
|
||||||
|
return await ParseHttpResponse(playerInfo, response).ConfigureAwait(false);
|
||||||
|
|
||||||
|
HttpResponseMessage mainResponse = await _httpClient.GetAsync("https://secure.runescape.com/m=hiscore_oldschool/index_lite.ws?player=" + userName).ConfigureAwait(false);
|
||||||
|
HttpResponseMessage ironResponse = await _httpClient.GetAsync("https://secure.runescape.com/m=hiscore_oldschool_ironman/index_lite.ws?player=" + userName).ConfigureAwait(false);
|
||||||
|
HttpResponseMessage hcimResponse = await _httpClient.GetAsync("https://secure.runescape.com/m=hiscore_oldschool_hardcore_ironman/index_lite.ws?player=" + userName).ConfigureAwait(false);
|
||||||
|
HttpResponseMessage uimResponse = await _httpClient.GetAsync("https://secure.runescape.com/m=hiscore_oldschool_ultimate/index_lite.ws?player=" + userName).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (mainResponse.StatusCode != HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
playerFound = true;
|
||||||
|
mainPlayerInfo = await ParseHttpResponse(mainPlayerInfo, mainResponse).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
if (ironResponse.StatusCode != HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
playerFound = true;
|
||||||
|
ironPlayerInfo = await ParseHttpResponse(ironPlayerInfo, ironResponse).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
if (hcimResponse.StatusCode != HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
playerFound = true;
|
||||||
|
hcimPlayerInfo = await ParseHttpResponse(hcimPlayerInfo, hcimResponse).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
if (uimResponse.StatusCode != HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
|
playerFound = true;
|
||||||
|
uimPlayerInfo = await ParseHttpResponse(uimPlayerInfo, uimResponse).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!playerFound)
|
||||||
|
{
|
||||||
|
playerInfo.Status = PlayerInfoStatus.NotFound;
|
||||||
|
return playerInfo;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<PlayerInfo>> GetPlayerInfoAsync(string[] userNames)
|
||||||
|
{
|
||||||
|
var tasks = userNames.Select(x => GetPlayerInfoAsync(x));
|
||||||
|
return await Task.WhenAll(tasks)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<PlayerInfo> ParseHttpResponse(PlayerInfo playerInfo, HttpResponseMessage response)
|
||||||
|
{
|
||||||
|
var stream = await response.Content.ReadAsStreamAsync()
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
using var reader = new StreamReader(stream);
|
||||||
|
|
||||||
|
var properties = typeof(PlayerInfo).GetProperties()
|
||||||
|
.Where(x => typeof(IPlayerInfoProperty).IsAssignableFrom(x.PropertyType)).ToArray();
|
||||||
|
|
||||||
|
if (properties.Count() != TotalLines(reader) && _throwMismatchException)
|
||||||
|
throw new FormatException("Property mismatch; OSRS API Contains more properties than PlayerInfo class. Please contact Repository creator");
|
||||||
|
|
||||||
|
foreach (PropertyInfo info in properties)
|
||||||
|
{
|
||||||
|
string[] values = reader.ReadLine().Split(',');
|
||||||
|
var property = ParseLine(values, info);
|
||||||
|
|
||||||
|
info.SetValue(playerInfo, property);
|
||||||
|
}
|
||||||
|
|
||||||
|
playerInfo.Status = PlayerInfoStatus.Success;
|
||||||
|
|
||||||
|
return playerInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int TotalLines(StreamReader reader)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
while (reader.ReadLine() != null) i++;
|
||||||
|
|
||||||
|
reader.BaseStream.Position = 0;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IPlayerInfoProperty ParseLine(string[] data, PropertyInfo info)
|
||||||
|
{
|
||||||
|
if (info.PropertyType == typeof(Skill))
|
||||||
|
{
|
||||||
|
return new Skill
|
||||||
|
{
|
||||||
|
Name = info.Name,
|
||||||
|
Rank = int.Parse(data[0]),
|
||||||
|
Level = int.Parse(data[1]),
|
||||||
|
Experience = int.Parse(data[2])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.PropertyType == typeof(Activity))
|
||||||
|
{
|
||||||
|
return new Activity
|
||||||
|
{
|
||||||
|
Name = info.Name,
|
||||||
|
Rank = int.Parse(data[0]),
|
||||||
|
Score = int.Parse(data[1])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.PropertyType == typeof(Boss))
|
||||||
|
{
|
||||||
|
return new Boss
|
||||||
|
{
|
||||||
|
Name = info.Name,
|
||||||
|
Rank = int.Parse(data[0]),
|
||||||
|
Kills = int.Parse(data[1])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotImplementedException($"Unimplemented type {info.PropertyType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user