diff --git a/server/api/update.ts b/server/api/update.ts index d8430c4..1147650 100644 --- a/server/api/update.ts +++ b/server/api/update.ts @@ -1,4 +1,3 @@ -import {Downloads} from "~/server/utils/types/downloads"; import {updateStatistics} from "~/server/utils/statistics"; export default defineEventHandler(async (event) => { diff --git a/server/utils/fetchData.ts b/server/utils/fetchData.ts index d8ff188..7e7763d 100644 --- a/server/utils/fetchData.ts +++ b/server/utils/fetchData.ts @@ -6,7 +6,7 @@ export async function getProjectIds(offset: number): Promise { limit: 100, offset: offset, //todo - remove newest - // index: "newest", + index: "newest", facets: "[[\"project_types:mod\"]]" } }) @@ -53,4 +53,23 @@ export type Version = { loaders: string[] game_versions: string[] downloads: number +} + +export async function getGameVersions(): Promise { + const data = await $modrinthFetch<{ + version: string, + version_type: string + }[]>("/tag/game_version") + + return data.map(value => { + return { + name: value.version, + fullVersion: value.version_type == "release" + } + }).toReversed() +} + +export type GameVersion = { + name: string, + fullVersion: boolean, } \ No newline at end of file diff --git a/server/utils/statistics.ts b/server/utils/statistics.ts index d35f900..8fe58bb 100644 --- a/server/utils/statistics.ts +++ b/server/utils/statistics.ts @@ -1,7 +1,3 @@ -import {Downloads} from "~/server/utils/types/downloads"; -import {Version} from "~/server/utils/fetchData"; -import {isAllowedModLoader} from "~/server/utils/allowed"; - export async function updateStatistics() { const projectIds = await getProjectIds(0); console.log("project ids", projectIds.length); @@ -10,13 +6,13 @@ export async function updateStatistics() { console.log("version ids", versionIds.length); let data = new Map>() - let versionsSet = new Set() + let versions = await getGameVersions() - await insertVersionsFromIds(versionIds, data, versionsSet); + await insertVersionsFromIds(versionIds, data); - let allDownloads = downloadsFromData(versionsSet, data); - let minorVersionDownloads = onlyMinorVersions(allDownloads); - let majorVersionDownloads = onlyMajorVersions(allDownloads); + let allDownloads = downloadsFromData(versions, data); + let {gameVersions: minorGameVersions, downloads: minorVersionDownloads} = onlyMinorVersions(versions, allDownloads); + let majorVersionDownloads = onlyMajorVersions(minorGameVersions, minorVersionDownloads); const storage = useStorage("statistics"); await storage.setItem("allVersionDownloads", allDownloads) @@ -24,7 +20,7 @@ export async function updateStatistics() { await storage.setItem("majorVersionDownloads", majorVersionDownloads) } -async function insertVersionsFromIds(versionIds: string[], data: Map>, versionsSet: Set) { +async function insertVersionsFromIds(versionIds: string[], data: Map>) { const BATCH_SIZE = 1000; let currentIndex = 0; @@ -36,14 +32,18 @@ async function insertVersionsFromIds(versionIds: string[], data: Map>, versionsSet: Set) { +function insertVersions(versions: Version[], data: Map>) { for (let version of versions) { + + // compensate for a version contributing to multiple loaders and versions + let versionDownloads = version.downloads / (version.loaders.length * version.game_versions.length) + for (let loader of version.loaders) { if (!isAllowedModLoader(loader)) { continue @@ -58,12 +58,10 @@ function insertVersions(versions: Version[], data: Map>() - let versionsSet = new Set() - - for (let loader of all.data) { - let downloads = new Map(); + let index = 0 - for (let i = 0; i < all.versions.length; i++) { - let versionText = all.versions[i]; + while (true) { + if (index == versions.length) + break - //todo - dont somehow handle snapshot versions - if (versionText.includes("w")) { - continue - } + let gameVersion = versions[index]; - let version = versionText.split("-")[0]; + if (gameVersion.fullVersion) { + index++ + continue + } - versionsSet.add(version); + for (let loader of downloads.data) { + let downloads = loader.downloads.splice(index, 1); - if (downloads.has(version)) { - downloads.set(version, downloads.get(version)! + loader.downloads[i]) - } else { - downloads.set(version, loader.downloads[i]) + if (index + 1 >= loader.downloads.length) { + continue } + + loader.downloads[index + 1] += downloads[0] } - data.set(loader.name, downloads) + versions.splice(index, 1) + downloads.versions.splice(index, 1) } - return downloadsFromData(versionsSet, data); + return {gameVersions: versions, downloads: downloads} } -function onlyMajorVersions(all: Downloads): Downloads { - - let data = new Map>() - let versionsSet = new Set() +function onlyMajorVersions(gameVersions: GameVersion[], all: Downloads): Downloads { + const versions = Array.from(gameVersions) + const downloads: Downloads = JSON.parse(JSON.stringify(all)) - for (let loader of all.data) { - let downloads = new Map(); + let index = versions.length - 1 - for (let i = 0; i < all.versions.length; i++) { - let versionText = all.versions[i]; + while (true) { + if (index == -1) + break - //todo - dont somehow handle snapshot versions - if (versionText.includes("w")) { - continue - } + let gameVersion = versions[index]; - let version = versionText.split("-")[0]; - version = version.split(".").slice(0, 2).join(".") + if (gameVersion.name.split(".").length == 2) { + index-- + continue + } - versionsSet.add(version); + for (let loader of downloads.data) { + let downloads = loader.downloads.splice(index, 1); - if (downloads.has(version)) { - downloads.set(version, downloads.get(version)! + loader.downloads[i]) - } else { - downloads.set(version, loader.downloads[i]) + if (index - 1 < 0) { + continue } + + loader.downloads[index - 1] += downloads[0] } - data.set(loader.name, downloads) + versions.splice(index, 1) + downloads.versions.splice(index, 1) } - return downloadsFromData(versionsSet, data); + return downloads } -function downloadsFromData(versionsSet: Set, data: Map>): Downloads { - const versionArray = Array.from(versionsSet) - versionArray.sort((a, b) => a.localeCompare(b, undefined, {numeric: true})) +function downloadsFromData(versions: GameVersion[], data: Map>): Downloads { + const versionArray = versions.map(value => { + return value.name + }) const loaderData = [] @@ -156,6 +159,10 @@ function downloadsFromData(versionsSet: Set, data: Map { + return Math.round(value) + }) + loaderData.push({ name: loader[0], downloads: downloads