-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
298 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,4 +45,5 @@ testing/ | |
.circleci/ | ||
changelog.md | ||
master.json | ||
.env | ||
.env | ||
.vscode/settings.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module.exports = async function () { | ||
const BingoData = require('../../structures/Skyblock/Static/BingoData.js'); | ||
|
||
const res = await this._makeRequest('/resources/skyblock/election'); | ||
if (res.raw) return res; | ||
|
||
return new BingoData(res); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
const getSkyblockBingo = require('./getSkyblockBingo'); | ||
const toUuid = require('../../utils/toUuid'); | ||
const Errors = require('../../Errors'); | ||
module.exports = async function (query, { fetchBingoData = false }) { | ||
if (!query) throw new Error(Errors.NO_NICKNAME_UUID); | ||
const PlayerBingo = require('../../structures/SkyBlock/PlayerBingo'); | ||
query = await toUuid(query); | ||
const res = await this._makeRequest(`/skyblock/uuid?player=${query}`); | ||
if (res.raw) return res; | ||
let bingoData = null; | ||
if (fetchBingoData) bingoData = await getSkyblockBingo.call(this); | ||
|
||
return new PlayerBingo(data, bingoData); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/** | ||
* @typedef {import('./Static/BingoData.js')} BingoData | ||
* @typedef {import('./Static/Bingo.js')} Bingo | ||
*/ | ||
|
||
/** | ||
* Player Bingo Class | ||
*/ | ||
class PlayerBingo { | ||
/** | ||
* Constructor | ||
* @param {Object} data data | ||
* @param {BingoData|null} bingoData bingo data | ||
*/ | ||
constructor(data, bingoData) { | ||
const events = data.success && Array.isArray(data.events) ? data.events : []; | ||
/** | ||
* Data per event | ||
* @type {PlayerBingoDataPerEvent} | ||
*/ | ||
this.dataPerEvent = events.map((eventData) => { | ||
let doneGoals = eventData.completed_goals; | ||
if (!Array.isArray(doneGoals)) doneGoals = []; | ||
const enrichable = parseInt(eventData.key, 10) === bingoData?.id; | ||
if (enrichable) doneGoals = populateGoals(doneGoals, bingoData.goals); | ||
return { | ||
eventId: parseInt(eventData.key, 10) || null, | ||
points: parseInt(eventData.points, 10) || 0, | ||
goalsCompleted: doneGoals, | ||
enrichedGoals: enrichable | ||
}; | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* Populate goals | ||
* For compatibility and lazy handling, uncompleted goals will be hidden in a property | ||
* @param {string[]} achieved achieved goals | ||
* @param {Bingo[]} all All goals | ||
* @returns {SpecialBingoArray} | ||
*/ | ||
function populateGoals(achieved, all) { | ||
const populatedAchieved = []; | ||
const unachieved = []; | ||
for (const goal of all) { | ||
if (achieved.find((str) => str === goal.name)) populatedAchieved.push(goal); | ||
else unachieved.push(goal); | ||
} | ||
populatedAchieved.unachievedGoals = unachieved; | ||
return populatedAchieved; | ||
} | ||
|
||
/** | ||
* @typedef {Bingo[] & {'unachievedGoals': Bingo[]}} SpecialBingoArray | ||
*/ | ||
/** | ||
* @typedef {Object} PlayerBingoDataPerEvent | ||
* @property {number} eventId ID of event | ||
* @property {number} points Points acquired | ||
* @property {boolean} enrichedGoals Whether the goals are enriched (populated with data from static skyblock bingp data) | ||
* @property {SpecialBingoArray|string[]} goalsCompleted Special Bingo Array if enrichedGoals is true. You can however always treat SpecialBingoArray as string[] | ||
*/ | ||
|
||
module.exports = PlayerBingo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/** | ||
* Bingo class | ||
*/ | ||
class Bingo { | ||
/** | ||
* Constructor | ||
* @param {Object} data data | ||
* @param {number} position Position | ||
*/ | ||
constructor(data, position = 0) { | ||
/** | ||
* Name of this bingo goal | ||
* @type {string} | ||
*/ | ||
this.name = data.name; | ||
/** | ||
* string ID (code name) | ||
* @type {string} | ||
*/ | ||
this.id = data.id; | ||
const [row, column] = parsePosition(position); | ||
/** | ||
* 1-indexed row | ||
* @type {number|null} | ||
*/ | ||
this.row = row; | ||
/** | ||
* 1-indexed colmun | ||
* @type {number|null} | ||
*/ | ||
this.column = column; | ||
/** | ||
* Bingo lore, with color codes | ||
* @type {string} | ||
*/ | ||
this.rawLore = data.lore; | ||
/** | ||
* Bingo lore in plain text | ||
* @type {string} | ||
*/ | ||
this.lore = data.lore?.replace?.(/§([1-9]|[a-l])|§/gm, '') || null; | ||
/** | ||
* Only available for TIERED bingos | ||
* Shows you the requirement for each tier of this achievement | ||
* @type {number[]} | ||
*/ | ||
this.tiers = Array.isArray(data.tiers) ? data.tiers.map((x) => parseInt(x, 10) || 0) : null; | ||
/** | ||
* Only available for TIERED bingos | ||
* Difference between each tier requirement, if it is constant | ||
* @type {number|null} | ||
*/ | ||
this.tierStep = this.#getTierStep(); | ||
/** | ||
* Only available for ONE_TIERED bingos | ||
* @type {number|null} | ||
*/ | ||
this.requiredAmount = parseInt(data.requiredAmount, 10) ?? null; | ||
/** | ||
* Type of Bingo | ||
* ONE_TIME means the goal doesn't have a specific amount | ||
* ONE_TIER means the goal specifies 1 amount to achieve | ||
* TIERED means the goal specifies more than 1 amount to achieve | ||
* @type {'ONE_TIME'|'ONE_TIER'|'TIERED'} | ||
*/ | ||
this.type = this.tiers ? 'TIERED' : this.requiredAmount ? 'ONE_TIER' : 'ONE_TIME'; | ||
} | ||
/** | ||
* As string | ||
* BEWARE this returns ID to assure compatibility with PlayerBingo | ||
* @return {string} | ||
*/ | ||
toString() { | ||
return this.id; | ||
} | ||
/** | ||
* Gets tier step, if constant | ||
* @private | ||
* @returns {number|null} | ||
*/ | ||
#getTierStep() { | ||
if (this.type !== 'TIERED') return null; | ||
// No step possible | ||
if (this.tiers.length < 2) return null; | ||
const hypotheticStep = this.tiers[1] - this.tiers[0]; | ||
// Check if every 2 elements have the same step | ||
const isConstant = this.tiers.slice(1).every((el, index) => { | ||
return hypotheticStep === this.tiers[index - 1] - el; | ||
}); | ||
if (!isConstant) return null; | ||
return hypotheticStep; | ||
} | ||
} | ||
|
||
/** | ||
* Parses row and col from position, assuming bingo table is 5x5 | ||
* @param {number} position Position | ||
* @returns {number[]} | ||
*/ | ||
function parsePosition(position) { | ||
const x = (position % 5) + 1; | ||
const y = Math.floor(position / 5) + 1; | ||
return [x, y]; | ||
} | ||
|
||
module.exports = Bingo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
const Bingo = require('./Bingo.js'); | ||
|
||
/** | ||
* SB Bingo Class | ||
*/ | ||
class BingoData { | ||
/** | ||
* constructor | ||
* @param {Object} data | ||
*/ | ||
constructor(data) { | ||
/** | ||
* Last time this resource was updated | ||
* @type {number} | ||
*/ | ||
this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10); | ||
/** | ||
* Last time this resource was updated, as Date | ||
* @type {Date|null} | ||
*/ | ||
this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); | ||
/** | ||
* Bingo ID | ||
* @type {number|null} | ||
*/ | ||
this.id = parseInt(data.id, 10) || null; | ||
/** | ||
* Goals | ||
* @type {Bingo[]|null} | ||
*/ | ||
this.goals = Array.isArray(data.goals) ? data.goals.map((goal, index) => new Bingo(goal, index)) : null; | ||
} | ||
/** | ||
* Gets a goal on the bingo table by row and column | ||
* @param {number} column Column number (starts at 1) | ||
* @param {number} row Row number (starts at 1) | ||
* @returns {Bingo|undefined} | ||
*/ | ||
getGoal(column, row) { | ||
if (!this.goals || this.goals.length < 1) return; | ||
return this.goals.find((goal) => goal.row === row && goal.column === column); | ||
} | ||
} | ||
|
||
module.exports = BingoData; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* eslint-disable no-undef */ | ||
const { SkyblockBingoData } = require('../src'); | ||
const { client } = require('./Client.js'); | ||
const { expect } = require('chai'); | ||
|
||
describe('Client#getSkyblockBingo', async () => { | ||
let bingo; | ||
it('expect not to throw', async () => { | ||
bingo = await client.getSkyblockBingo(); | ||
}); | ||
it('should be an objecct', () => { | ||
expect(bingo).to.be.an('object'); | ||
}); | ||
it('required keys should exist', () => { | ||
expect(bingo).instanceOf(SkyblockBingoData); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,17 @@ | ||
/* eslint-disable no-undef */ | ||
const { SkyblockGovernment } = require('../src/'); | ||
const { SkyblockGovernment } = require('../src'); | ||
const { client } = require('./Client.js'); | ||
const { expect } = require('chai'); | ||
|
||
describe('Client#getSkyblockMember', async () => { | ||
describe('Client#getSkyblockGoverment', async () => { | ||
let goverment; | ||
describe('Random (1)', async () => { | ||
it('expect not to throw', async () => { | ||
goverment = await client.getSkyblockGoverment(); | ||
}); | ||
it('should be an objecct', () => { | ||
expect(goverment).to.be.an('object'); | ||
}); | ||
it('required keys should exist', () => { | ||
expect(goverment).instanceOf(SkyblockGovernment); | ||
}); | ||
it('expect not to throw', async () => { | ||
goverment = await client.getSkyblockGoverment(); | ||
}); | ||
it('should be an objecct', () => { | ||
expect(goverment).to.be.an('object'); | ||
}); | ||
it('required keys should exist', () => { | ||
expect(goverment).instanceOf(SkyblockGovernment); | ||
}); | ||
}); |