zikeji / node-hypixel

With thorough IntelliSense support & 100% test coverage, this is an unopinionated async/await API wrapper for Hypixel's Public API. It is developed in TypeScript complete with documentation, typed interfaces for all API responses (and an OpenAPI 3.0 schema!), built-in rate-limit handling, flexible cache support, helper functions, and support for undocumented endpoints.
https://node-hypixel.zikeji.com
MIT License
20 stars 6 forks source link

Skywars stats arent availiable #119

Closed Mythbusters123 closed 3 years ago

Mythbusters123 commented 3 years ago

Describe the bug So i was looking through the code, and it doesnt seem to document Skywars Stats well. I could be wrong on this, but it seems to only have the type of the base game, not with a different class where you can grab the data.

To Reproduce Its in the api.ts file

Expected behavior There should be stats just for skywars, so you can access them

Environment:

zikeji commented 3 years ago

This is an enhancement request, not a bug. As I mention in the README, my API aims to be unopinionated and not change output from the API. It documents it and adds type completion for added ease of use. Some Helpers exist to fill in roles where calculations and other overhead is necessary, but in form where explicitly run the helper.

None of the objects returned by the API calls are classes - they're all the JSON results from Hypixel.

Skywars stats themselves come from two places in Hypixel's API, but all under the /player call.

Some of the SkyWars stats are available in the achievements property of the player object.

https://node-hypixel.zikeji.com/ts-api/interfaces/components.schemas.player/#achievements https://node-hypixel.zikeji.com/ts-api/interfaces/components.schemas.playerachievements/#skywars-heads

Code_qYGWlTmtL9

The majority of the stats are in the stats property however.

https://node-hypixel.zikeji.com/ts-api/interfaces/components.schemas.player/#stats https://node-hypixel.zikeji.com/ts-api/interfaces/components.schemas.playerstats/#skywars

Code_TlDRKbxJkH

You might be referring to the typings for that property (the schema). You are correct as I haven't explored it thoroughly. However the data is there, and the possible data types will be suggested based on my exploration of Hypixel's API. Just because there aren't any suggestions doesn't mean the data isn't available - you can use console.log to view the properties. In this instance based on the screenshots you'd do console.log(player.stats.SkyWars) to view the available data for that player.

In terms of the SkyWars data it is very much like the BedWars data. In my exploration of the APIs I downloaded the player data for 6913 Hypixel players and used it to explore difference datasets.

The player.stats.SkyWars property has over 10 thousand unique properties - mapping that in the schema would cause alot of trouble.

You can view the mapping here: https://codebeautify.org/online-json-editor/cbffdf3a

To explain the JSON format: the "count" property shows how many existed, and properties obviously shows the properties of that object. So delving into it you can see how many instances showed up (how rare/common that data is).

chrome_rlvTd4RU5V

So in the above example you can see the base object (stats.SkyWars) had 6853 instances out of the 6913. So SkyWars_openedChests in that screenshot shows up 4815 times. Which means a good amount of players will have the stats.SkyWars.SkyWars_openedChests property. As the data shows, that property is a "number" type.

chrome_Esa8XxILI2

In that example you can see the activeKit_MEGA property is a string and shows up in slightly more than half of the results. That would be stats.SkyWars.activeKit_MEGA.

zikeji commented 3 years ago

@Mythbusters123 I went ahead and converted the data to a typescript definition here: https://gist.github.com/zikeji/5d63dec21fade695293355f190e0cc9e

Not sure if you're using TypeScript or just normal JS. You should be able to manually assign the stats.SkyBlock object that type in either platform.

e.g.

In typescript:

/** interface definition here */
const player = await client.player.uuid('20934ef9488c465180a78f861586b4cf');
const skywarsStats = player.stats.SkyWars as SkyWarsStats;

In vanilla JS you'd need to use jsdoc - not terribly familiar but I can look into it later.

Mythbusters123 commented 3 years ago

Wow, you didnt have to. That must have taken a ton of time. Thank you though!

zikeji commented 3 years ago

Wow, you didnt have to. That must have taken a ton of time. Thank you though!

I have parsing scripts setup to pull out definitions from API data. That's how I typed out most of the interfaces - I pulled API data on a bunch of players and fed it into the script. Took a while to setup, but since it's already there I just ran it against SkyWars stats again.