diff --git a/src/main/main.ts b/src/main/main.ts index 8f428ab2..1f471f9d 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -15,6 +15,7 @@ import log from 'electron-log'; import { resolveHtmlPath } from './util'; import './ipcs'; import { UtilsService } from './services/utils.service'; +import { BeatModsApiService } from './services/beat-mods-api.service'; export default class AppUpdater { constructor() { @@ -29,6 +30,8 @@ log.transports.file.resolvePath = (() => { return path.join(app.getPath("logs"), `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}.log`); }); +console.log(process.env.CSC_LINK); + log.catchErrors(); let mainWindow: BrowserWindow = null; @@ -38,6 +41,9 @@ export function getMainWindow(): BrowserWindow{ } +BeatModsApiService.getInstance().getVersionMods({BSVersion: "1.24.0"}).then(a => {}); + + if (process.env.NODE_ENV === 'production') { const sourceMapSupport = require('source-map-support'); sourceMapSupport.install(); diff --git a/src/main/services/beat-mods-api.service.ts b/src/main/services/beat-mods-api.service.ts new file mode 100644 index 00000000..b472cbe0 --- /dev/null +++ b/src/main/services/beat-mods-api.service.ts @@ -0,0 +1,73 @@ +import { BSVersion } from "shared/bs-version.interface"; +import { Mod } from "shared/models/mods/mod.interface"; +import { RequestService } from "./request.service"; + +export class BeatModsApiService { + + private static instance: BeatModsApiService; + + private readonly requestService: RequestService + + private readonly BEAT_MODS_VERSIONS = "https://versions.beatmods.com/versions.json"; + private readonly BEAT_MODS_ALIAS = "https://alias.beatmods.com/aliases.json"; + + private readonly BEAT_MODS_API_URL = "https://beatmods.com/api/v1/"; + + private readonly versionsCache: BSVersion[] = []; + private readonly aliasesCache = new Map(); + private readonly versionModsCache = new Map(); + + private readonly allModsCache: Mod[] = []; + + public static getInstance(): BeatModsApiService{ + if(!BeatModsApiService.instance){ BeatModsApiService.instance = new BeatModsApiService(); } + return BeatModsApiService.instance; + } + + private constructor(){ + this.requestService = RequestService.getInstance(); + } + + private getVersionModsUrl(version: BSVersion): string{ + return `${this.BEAT_MODS_API_URL}mod?status=approved&gameVersion=${version.BSVersion}&sort=&sortDirection=1`; + } + + private async getVersionAlias(): Promise>{ + if(this.aliasesCache.size){ return this.aliasesCache; } + return this.requestService.get>(this.BEAT_MODS_ALIAS).then(rawAliases => { + Object.entries(rawAliases).forEach(([key, value]) => { + this.aliasesCache.set(key, value.map(s => ({BSVersion: s} as BSVersion))); + }); + return this.aliasesCache; + }) + } + + private async getAliasOfVersion(version: BSVersion): Promise{ + return this.getVersionAlias().then(aliases => { + if(Array.from(aliases.keys()).some(k => k === version.BSVersion)){ return version; } + const alias = Array.from(aliases.entries()).find(([key, value]) => value.find(v => v.BSVersion === version.BSVersion))[0]; + return {BSVersion: alias} as BSVersion + }); + } + + private asignDependencies(mod: Mod, mods: Mod[]): Mod{ + mod.dependencies.map(dep => mods.find(mod => mod.name === dep.name)); + return mod; + } + + public async getVersionMods(version: BSVersion): Promise{ + if(this.versionModsCache.has(version.BSVersion)){ return this.versionModsCache.get(version.BSVersion); } + + const alias = await this.getAliasOfVersion(version); + + return this.requestService.get(this.getVersionModsUrl(alias)).then(mods => { + mods.map(mod => this.asignDependencies(mod, mods)); + this.versionModsCache.set(version.BSVersion, mods); + return mods; + }); + + } + + + +} \ No newline at end of file diff --git a/src/main/services/bs-mods.service.ts b/src/main/services/bs-mods.service.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/main/services/bs-version-lib.service.ts b/src/main/services/bs-version-lib.service.ts index 2a0599e4..ed06e7ed 100644 --- a/src/main/services/bs-version-lib.service.ts +++ b/src/main/services/bs-version-lib.service.ts @@ -3,6 +3,7 @@ import { UtilsService } from './utils.service'; import path from 'path'; import { writeFileSync } from 'fs'; import { BSVersion } from 'shared/bs-version.interface'; +import { RequestService } from "./request.service" import isOnline from 'is-online'; export class BSVersionLibService{ @@ -13,11 +14,13 @@ export class BSVersionLibService{ private static instance: BSVersionLibService; private utilsService: UtilsService; + private requestService: RequestService private bsVersions: BSVersion[] = []; private constructor(){ this.utilsService = UtilsService.getInstance(); + this.requestService = RequestService.getInstance(); } @@ -26,19 +29,9 @@ export class BSVersionLibService{ return BSVersionLibService.instance; } - private getRemoteVersions(): Promise{ - return new Promise((resolve, reject) => { - let body = '' - get(this.REMOTE_BS_VERSIONS_URL, (res) => { - res.on('data', chunk => body += chunk); - res.on('end', () => { - this.bsVersions = JSON.parse(body); - resolve(this.bsVersions); - }); - res.on('error', () => reject(null)) - }) - }) - } + private getRemoteVersions(): Promise{ + return this.requestService.get(this.REMOTE_BS_VERSIONS_URL); + } private async getLocalVersions(): Promise{ const localVersionsPath = path.join(this.utilsService.getAssestsJsonsPath(), this.VERSIONS_FILE); diff --git a/src/main/services/request.service.ts b/src/main/services/request.service.ts new file mode 100644 index 00000000..89df50cd --- /dev/null +++ b/src/main/services/request.service.ts @@ -0,0 +1,27 @@ +import { get } from "https"; + +export class RequestService { + + private static instance: RequestService; + + public static getInstance(): RequestService{ + if(!RequestService.instance){ RequestService.instance = new RequestService(); } + return RequestService.instance; + } + + private constructor(){} + + public get(url: string): Promise{ + return new Promise((resolve, reject) => { + let body = '' + get(url, (res) => { + res.on('data', chunk => body += chunk); + res.on('end', () => { + resolve(JSON.parse(body)); + }); + res.on('error', (err) => reject(err)) + }); + }); + } + +} \ No newline at end of file diff --git a/src/shared/models/mods/mod.interface.ts b/src/shared/models/mods/mod.interface.ts new file mode 100644 index 00000000..ffb72137 --- /dev/null +++ b/src/shared/models/mods/mod.interface.ts @@ -0,0 +1,34 @@ +export interface Mod { + _id: string, + name: string, + version: string, + gameVersion: string, + authorId: string, + uploadedDate: string, + updatedDate: string, + author: ModAuthor, + description: string, + link: string, + category: string, + downloads: DownloadLink[], + required: boolean, + dependencies: Mod[], + +} + +export interface ModAuthor { + _id: string, + username: string, + lastLogin: string, +} + +export interface DownloadLink { + type: string, + url: string, + hashMd5: FileHashes[] +} + +export interface FileHashes { + hash: string, + file: string +} \ No newline at end of file