aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cleaners/skyblock/auctions.ts36
-rw-r--r--src/database.ts11
-rw-r--r--src/hypixel.ts49
-rw-r--r--src/index.ts14
4 files changed, 108 insertions, 2 deletions
diff --git a/src/cleaners/skyblock/auctions.ts b/src/cleaners/skyblock/auctions.ts
new file mode 100644
index 0000000..28e1958
--- /dev/null
+++ b/src/cleaners/skyblock/auctions.ts
@@ -0,0 +1,36 @@
+import typedHypixelApi from 'typed-hypixel-api'
+import { cleanInventory, headIdFromBase64, Item } from './inventory.js'
+
+
+export interface Auction {
+ id: string
+ sellerUuid: string
+ sellerProfileUuid: string
+ buyerUuid: string | null
+ creationTimestamp: number
+ boughtTimestamp: number
+ coins: number
+ bin: boolean
+ item: Item
+}
+
+export async function cleanAuctions(data: typedHypixelApi.SkyBlockRequestAuctionResponse): Promise<Auction[]> {
+ console.log(data)
+ const auctions: Auction[] = []
+ for (const auction of data.auctions) {
+ auctions.push({
+ id: auction.uuid,
+ sellerUuid: auction.auctioneer,
+ sellerProfileUuid: auction.profile_id,
+ creationTimestamp: auction.start,
+ buyerUuid: auction.end ? auction.bids[auction.bids.length - 1].bidder : null,
+ boughtTimestamp: auction.end,
+ coins: auction.highest_bid_amount,
+ bin: auction.bin ?? false,
+ item: (await cleanInventory(typeof auction.item_bytes === 'string' ? auction.item_bytes : auction.item_bytes.data))[0]
+ })
+ }
+
+ return auctions
+
+} \ No newline at end of file
diff --git a/src/database.ts b/src/database.ts
index 3aafd05..a8dd1a4 100644
--- a/src/database.ts
+++ b/src/database.ts
@@ -1110,6 +1110,17 @@ export async function updateItemAuction(auction: ItemAuctionsSchema) {
}, { $set: auction }, { upsert: true })
}
+/**
+ * Fetches the SkyBlock ids of all the items in the auctions database. This method is slow and should be cached!
+ */
+export async function fetchItemsAuctionsIds(): Promise<string[]> {
+ const docs = await itemAuctionsCollection?.aggregate([
+ // this removes everything except the _id
+ { $project: { _id: true } }
+ ]).toArray()
+ return docs.map(r => r._id)
+}
+
export async function fetchServerStatus() {
return await database.admin().serverStatus()
diff --git a/src/hypixel.ts b/src/hypixel.ts
index 88f3768..5865878 100644
--- a/src/hypixel.ts
+++ b/src/hypixel.ts
@@ -14,6 +14,7 @@ import {
AccountSchema,
fetchAccount,
fetchItemsAuctions,
+ fetchItemsAuctionsIds,
ItemAuctionsSchema,
queueUpdateDatabaseMember,
queueUpdateDatabaseProfile,
@@ -33,6 +34,7 @@ import { debug } from './index.js'
import { WithId } from 'mongodb'
import { cleanEndedAuctions } from './cleaners/skyblock/endedAuctions.js'
import { cleanAuctions } from './cleaners/skyblock/auctions.js'
+import { string } from 'prismarine-nbt'
export type Included = 'profiles' | 'player' | 'stats' | 'inventories' | undefined
@@ -452,4 +454,51 @@ export async function periodicallyFetchRecentlyEndedAuctions() {
}
}
+let isFetchingAuctionItemList = false
+let cachedAuctionItemListData: Map<string, string> | null = null
+let nextAuctionItemListUpdate: Date = new Date(0)
+
+export async function fetchAuctionItems() {
+ if (cachedAuctionItemListData && nextAuctionItemListUpdate > new Date())
+ return cachedAuctionItemListData
+
+ // if it's currently fetching the election data and it doesn't have it,
+ // wait until we do have the election data
+ if (isFetchingAuctionItemList && !cachedAuctionItemListData) {
+ await new Promise(resolve => {
+ const interval = setInterval(() => {
+ if (cachedAuctionItemListData) {
+ clearInterval(interval)
+ resolve(cachedAuctionItemListData)
+ }
+ }, 100)
+ })
+ }
+
+ isFetchingAuctionItemList = true
+ const itemList = await fetchAuctionItemsUncached()
+ isFetchingAuctionItemList = false
+
+ cachedAuctionItemListData = itemList
+ // updates every 60 minutes
+ nextAuctionItemListUpdate = new Date(Date.now() + 10 * 60 * 1000);
+ return Object.fromEntries(itemList)
+}
+
+async function fetchAuctionItemsUncached() {
+ const auctionItemIds = await fetchItemsAuctionsIds()
+ const itemList = await fetchItemList()
+ const idsToNames: Map<string, string> = new Map()
+ for (const item of itemList.list)
+ // we only return items in auctionItemIds so the response isn't too big,
+ // since usually it would contain stuff that we don't care about like
+ // minions
+ if (auctionItemIds.includes(item.id))
+ idsToNames.set(item.id, item.display.name)
+ // if the item in the database isn't in the items api, just set the name to the id
+ for (const item of auctionItemIds)
+ if (!idsToNames.has(item))
+ idsToNames.set(item, item)
+ return idsToNames
+}
diff --git a/src/index.ts b/src/index.ts
index 1dcb523..9311fe6 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,5 @@
import { createSession, fetchAccountFromDiscord, fetchAllLeaderboardsCategorized, fetchLeaderboard, fetchMemberLeaderboardSpots, fetchSession, finishedCachingRawLeaderboards, leaderboardUpdateMemberQueue, leaderboardUpdateProfileQueue, updateAccount, deleteSession, fetchPaginatedItemsAuctions, fetchItemsAuctions } from './database.js'
-import { fetchAuctionUncached, fetchElection, fetchItemList, fetchMemberProfile, fetchUser } from './hypixel.js'
+import { fetchAuctionItems, fetchAuctionUncached, fetchElection, fetchItemList, fetchMemberProfile, fetchUser } from './hypixel.js'
import rateLimit from 'express-rate-limit'
import * as constants from './constants.js'
import * as discord from './discord.js'
@@ -166,7 +166,6 @@ app.get('/items', async (req, res) => {
}
})
-
app.get('/auctionprices', async (req, res) => {
const itemIds = typeof req.query.items === 'string' ? req.query.items.split(',') : null
if (itemIds && itemIds.length > 100)
@@ -186,6 +185,17 @@ app.get('/auctionprices', async (req, res) => {
}
})
+app.get('/auctionitems', async (req, res) => {
+ try {
+ res
+ .setHeader('Cache-Control', 'public, max-age=600')
+ .json(await fetchAuctionItems())
+ } catch (err) {
+ console.error(err)
+ res.json({ ok: false })
+ }
+})
+
app.get('/auction/:uuid', async (req, res) => {
console.log('fetching auction', req.params.uuid)
const auction = await fetchAuctionUncached(req.params.uuid)