diff --git a/package-lock.json b/package-lock.json index f99ef262..cb97ef8a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -946,6 +946,11 @@ "tslib": "^1.9.0" } }, + "class-transformer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", + "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -2472,6 +2477,11 @@ "resolve": "^1.9.0" } }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", diff --git a/package.json b/package.json index 3aabec53..9311dc00 100644 --- a/package.json +++ b/package.json @@ -52,10 +52,12 @@ }, "dependencies": { "adm-zip": "^0.5.4", + "class-transformer": "^0.4.0", "cli-progress": "^3.9.0", "colors": "^1.4.0", "p-map": "^4.0.0", "progress-stream": "^2.0.0", + "reflect-metadata": "^0.1.13", "semver": "^7.3.5", "source-map-support": "^0.5.19", "uuid": "^8.3.2", diff --git a/src/main/LauncherServer.ts b/src/main/LauncherServer.ts index 4370436a..50c55299 100644 --- a/src/main/LauncherServer.ts +++ b/src/main/LauncherServer.ts @@ -16,9 +16,8 @@ * along with this program. If not, see . */ -import 'source-map-support/register'; - -const version = require("../../package").version +import "source-map-support/register" +import "reflect-metadata" import { EventEmitter } from "events" @@ -35,6 +34,8 @@ import { ModulesManager } from "./modules/ModulesManager" import { ProfilesManager } from "./profiles/ProfilesManager" import { UpdatesManager } from "./updates/UpdatesManager" +const version = require("../../package").version + export class LauncherServer extends EventEmitter { private _ConfigManager: ConfigManager private _LangManager: LangManager diff --git a/src/main/api/WebSocketManager.ts b/src/main/api/WebSocketManager.ts index 60464479..6cbe9489 100644 --- a/src/main/api/WebSocketManager.ts +++ b/src/main/api/WebSocketManager.ts @@ -52,7 +52,7 @@ export class WebSocketManager { // } try { - parsedMessage = JsonHelper.toJSON(message) + parsedMessage = JsonHelper.fromJSON(message) } catch (error) { return this.wsSend(ws, { uuid: NIL_UUID, @@ -88,6 +88,6 @@ export class WebSocketManager { } private wsSend(ws: ws, data: wsResponse | wsErrorResponse): void { - ws.send(JsonHelper.toString(data)) + ws.send(JsonHelper.toJSON(data)) } } diff --git a/src/main/api/types/ErrorResponse.ts b/src/main/api/types/ErrorResponse.ts index 511fcdb5..37d5ae69 100644 --- a/src/main/api/types/ErrorResponse.ts +++ b/src/main/api/types/ErrorResponse.ts @@ -1,3 +1,21 @@ +/** + * AuroraLauncher LauncherServer - Server for AuroraLauncher + * Copyright (C) 2020 - 2021 AuroraTeam + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + export interface ErrorResponse { code: number message: string diff --git a/src/main/api/types/Request.ts b/src/main/api/types/Request.ts index 6006dcec..c5fb187c 100644 --- a/src/main/api/types/Request.ts +++ b/src/main/api/types/Request.ts @@ -1,3 +1,21 @@ +/** + * AuroraLauncher LauncherServer - Server for AuroraLauncher + * Copyright (C) 2020 - 2021 AuroraTeam + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + export type RequestData = object export interface Request { diff --git a/src/main/api/types/Response.ts b/src/main/api/types/Response.ts index db1a2cc9..baa65a5e 100644 --- a/src/main/api/types/Response.ts +++ b/src/main/api/types/Response.ts @@ -1,3 +1,21 @@ +/** + * AuroraLauncher LauncherServer - Server for AuroraLauncher + * Copyright (C) 2020 - 2021 AuroraTeam + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + export type ResponseData = object export interface Response { diff --git a/src/main/config/ConfigManager.ts b/src/main/config/ConfigManager.ts index 4983c2ac..98ebb9bf 100644 --- a/src/main/config/ConfigManager.ts +++ b/src/main/config/ConfigManager.ts @@ -16,11 +16,11 @@ * along with this program. If not, see . */ -import { JsonHelper } from "../helpers/JsonHelper" +import * as fs from "fs" + import { LogHelper } from "../helpers/LogHelper" import { StorageHelper } from "../helpers/StorageHelper" -import { LauncherServerConfig } from "./LauncherServerConfig" -import fs = require("fs") +import { LauncherServerConfig } from "./types/LauncherServerConfig" export class ConfigManager { private config: LauncherServerConfig @@ -41,18 +41,19 @@ export class ConfigManager { } private load(): void { - const config = fs.readFileSync(StorageHelper.configFile) + const config = fs.readFileSync(StorageHelper.configFile).toString() try { - this.config = JsonHelper.toJSON(config.toString()) + this.config = LauncherServerConfig.fromJSON(config) } catch (e) { if (e instanceof SyntaxError) { LogHelper.error(e) LogHelper.fatal("Json syntax broken. Try fix or delete LauncherServerConfig.json") } + LogHelper.fatal(e) } } private save(): void { - fs.writeFileSync(StorageHelper.configFile, JsonHelper.toString(this.config, true)) + fs.writeFileSync(StorageHelper.configFile, this.config.toJSON()) } } diff --git a/src/main/config/types/AuthConfig.ts b/src/main/config/types/AuthConfig.ts new file mode 100644 index 00000000..bfe8730e --- /dev/null +++ b/src/main/config/types/AuthConfig.ts @@ -0,0 +1,35 @@ +/** + * AuroraLauncher LauncherServer - Server for AuroraLauncher + * Copyright (C) 2020 - 2021 AuroraTeam + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { AbstractAuthProvider, AbstractAuthProviderConfig } from "../../auth/authProviders/AbstractAuthProvider" +import { + AbstractTextureProvider, + AbstractTextureProviderConfig, +} from "../../auth/textureProviders/AbstractTextureProvider" + +export class AuthConfig { + authProvider: AbstractAuthProviderConfig + textureProvider: AbstractTextureProviderConfig + + static getDefaults(): AuthConfig { + const defaults = new AuthConfig() + defaults.authProvider = AbstractAuthProvider.getDefaultConfig() + defaults.textureProvider = AbstractTextureProvider.getDefaultConfig() + return defaults + } +} diff --git a/src/main/config/types/LauncherServerConfig.ts b/src/main/config/types/LauncherServerConfig.ts new file mode 100644 index 00000000..c5fb539d --- /dev/null +++ b/src/main/config/types/LauncherServerConfig.ts @@ -0,0 +1,59 @@ +/** + * AuroraLauncher LauncherServer - Server for AuroraLauncher + * Copyright (C) 2020 - 2021 AuroraTeam + + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import { classToPlain, deserialize } from "class-transformer" + +import { JsonHelper } from "../../helpers/JsonHelper" +import { AuthConfig } from "./AuthConfig" +import { WebSocketConfig } from "./WebSocketConfig" + +// TODO Инфа на будущее, пригодится при версионировании конфигов +// https://github.com/typestack/class-transformer/tree/v0.4.0#using-versioning-to-control-exposed-and-excluded-properties +export class LauncherServerConfig { + configVersion: number + lang: "ru" | "en" + env: Envirovement + mirrors: string[] + auth: AuthConfig + ws: WebSocketConfig + + static getDefaults(): LauncherServerConfig { + const config = new LauncherServerConfig() + config.configVersion = 0 + config.lang = "ru" + config.env = Envirovement.DEV + config.mirrors = ["https://mirror.aurora-launcher.ru/"] + config.auth = AuthConfig.getDefaults() + config.ws = WebSocketConfig.getDefaults() + return config + } + + public toJSON(): string { + return JsonHelper.toJSON(classToPlain(this), true) + } + + public static fromJSON(json: string): LauncherServerConfig { + return deserialize(LauncherServerConfig, json) + } +} + +export enum Envirovement { + PRODUCTION = "prod", + DEBUG = "debug", + DEV = "dev", +} diff --git a/src/main/config/LauncherServerConfig.ts b/src/main/config/types/WebSocketConfig.ts similarity index 52% rename from src/main/config/LauncherServerConfig.ts rename to src/main/config/types/WebSocketConfig.ts index 8df84650..43d34432 100644 --- a/src/main/config/LauncherServerConfig.ts +++ b/src/main/config/types/WebSocketConfig.ts @@ -16,12 +16,6 @@ * along with this program. If not, see . */ -import { AbstractAuthProvider, AbstractAuthProviderConfig } from "../auth/authProviders/AbstractAuthProvider" -import { - AbstractTextureProvider, - AbstractTextureProviderConfig, -} from "../auth/textureProviders/AbstractTextureProvider" - export class WebSocketConfig { address: string ip: string @@ -49,45 +43,3 @@ export class WebSocketConfig { return defaults } } - -export class AuthConfig { - authProvider: AbstractAuthProviderConfig - textureProvider: AbstractTextureProviderConfig - - static getDefaults(): AuthConfig { - const defaults = new AuthConfig() - defaults.authProvider = AbstractAuthProvider.getDefaultConfig() - defaults.textureProvider = AbstractTextureProvider.getDefaultConfig() - return defaults - } -} - -export enum Envirovement { - PRODUCTION = "prod", - DEBUG = "debug", - DEV = "dev", -} - -export class LauncherServerConfig { - configVersion: string - lang: string - - env: Envirovement - - updatesUrl: Array - - auth: AuthConfig - - ws: WebSocketConfig - - static getDefaults(): LauncherServerConfig { - const config = new LauncherServerConfig() - config.configVersion = "0" - config.lang = "ru" - config.env = Envirovement.DEV - config.updatesUrl = ["https://mirror.aurora-launcher.ru/"] - config.auth = AuthConfig.getDefaults() - config.ws = WebSocketConfig.getDefaults() - return config - } -} diff --git a/src/main/download/FabricManager.ts b/src/main/download/FabricManager.ts index d7e81ae4..119d9520 100644 --- a/src/main/download/FabricManager.ts +++ b/src/main/download/FabricManager.ts @@ -74,7 +74,7 @@ export class FabricManager extends MojangManager { let loaders: any[] try { - loaders = JsonHelper.toJSON(loadersData) + loaders = JsonHelper.fromJSON(loadersData) } catch (error) { LogHelper.debug(error) LogHelper.error("Error parsing JSON data") @@ -99,7 +99,7 @@ export class FabricManager extends MojangManager { } try { - return JsonHelper.toJSON(versionData) + return JsonHelper.fromJSON(versionData) } catch (error) { LogHelper.debug(error) return diff --git a/src/main/download/MirrorManager.ts b/src/main/download/MirrorManager.ts index 652734ba..803eb191 100644 --- a/src/main/download/MirrorManager.ts +++ b/src/main/download/MirrorManager.ts @@ -37,7 +37,7 @@ export class MirrorManager { * @param dirName - Название конечной папки */ async downloadClient(clientName: string, dirName: string): Promise { - const mirrors: string[] = App.ConfigManager.getConfig().updatesUrl + const mirrors: string[] = App.ConfigManager.getConfig().mirrors const clientDir = path.resolve(StorageHelper.updatesDir, dirName) if (fs.existsSync(clientDir)) return LogHelper.error(App.LangManager.getTranslate("MirrorManager.dirExist")) @@ -82,7 +82,7 @@ export class MirrorManager { //Profiles App.ProfilesManager.createProfile({ - ...JsonHelper.toJSON(profile), + ...JsonHelper.fromJSON(profile), clientDir: dirName, } as ClientProfileConfig) LogHelper.info(App.LangManager.getTranslate("MirrorManager.client.success")) @@ -94,7 +94,7 @@ export class MirrorManager { * @param dirName - Название конечной папки */ async downloadAssets(assetsName: string, dirName: string): Promise { - const mirrors: string[] = App.ConfigManager.getConfig().updatesUrl + const mirrors: string[] = App.ConfigManager.getConfig().mirrors const assetsDir = path.resolve(StorageHelper.updatesDir, dirName) if (fs.existsSync(assetsDir)) return LogHelper.error(App.LangManager.getTranslate("MirrorManager.dirExist")) diff --git a/src/main/download/MojangManager.ts b/src/main/download/MojangManager.ts index 9e9b6c06..18c1cd1d 100644 --- a/src/main/download/MojangManager.ts +++ b/src/main/download/MojangManager.ts @@ -105,7 +105,7 @@ export class MojangManager { fs.mkdirSync(path.resolve(assetsDir, "indexes")) fs.writeFileSync(path.resolve(assetsDir, `indexes/${version.assets}.json`), assetsFile) - const assetsData = JsonHelper.toJSON(assetsFile).objects + const assetsData = JsonHelper.fromJSON(assetsFile).objects const assetsHashes: Set = new Set() for (const key in assetsData) { const hash = assetsData[key].hash @@ -186,7 +186,7 @@ export class MojangManager { let versions try { - versions = JsonHelper.toJSON(versionsData).versions + versions = JsonHelper.fromJSON(versionsData).versions } catch (error) { LogHelper.debug(error) LogHelper.error("Error parsing versions data") @@ -209,7 +209,7 @@ export class MojangManager { } try { - return JsonHelper.toJSON(clientData) + return JsonHelper.fromJSON(clientData) } catch (error) { LogHelper.debug(error) LogHelper.error("Error parsing client data") diff --git a/src/main/helpers/JsonHelper.ts b/src/main/helpers/JsonHelper.ts index a2ecfb09..4ac59abe 100644 --- a/src/main/helpers/JsonHelper.ts +++ b/src/main/helpers/JsonHelper.ts @@ -17,11 +17,22 @@ */ export class JsonHelper { - static toJSON(string: string): any { + /** + * Преобразовать JSON строку в объект + * @param string JSON строка + * @returns `Object | Array` + */ + static fromJSON(string: string): any { return JSON.parse(string) } - static toString(data: object, pretty = false): string { - return pretty ? JSON.stringify(data, null, 4) : JSON.stringify(data) + /** + * Преобразовать объект в JSON строку + * @param obj Пробразуемый объект + * @param pretty Форматировать вывод отступами или вывести в одну строку (по умолчанию `false`) + * @returns JSON сторка + */ + static toJSON(obj: Record, pretty = false): string { + return pretty ? JSON.stringify(obj, null, 4) : JSON.stringify(obj) } } diff --git a/src/main/profiles/ProfileConfig.ts b/src/main/profiles/ProfileConfig.ts index 776e39fc..b482249d 100644 --- a/src/main/profiles/ProfileConfig.ts +++ b/src/main/profiles/ProfileConfig.ts @@ -86,7 +86,7 @@ export class ClientProfile implements ClientProfileConfig { } public toString(): string { - return JsonHelper.toString(this, true) + return JsonHelper.toJSON(this, true) } } diff --git a/src/main/profiles/ProfilesManager.ts b/src/main/profiles/ProfilesManager.ts index 0ba4ab71..1a82d554 100644 --- a/src/main/profiles/ProfilesManager.ts +++ b/src/main/profiles/ProfilesManager.ts @@ -45,7 +45,7 @@ export class ProfilesManager { if (!file.endsWith(".json")) return try { - const data = JsonHelper.toJSON( + const data = JsonHelper.fromJSON( fs.readFileSync(path.resolve(StorageHelper.profilesDir, file)).toString() ) this.profiles.push(new ClientProfile(data)) diff --git a/tsconfig.json b/tsconfig.json index 754c85f7..51660ce7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,9 @@ "sourceMap": true, "noImplicitAny": true, "module": "commonjs", - "target": "es5", - "jsx": "react", - "allowJs": true + "target": "ES2017", + "allowJs": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true } -} \ No newline at end of file +}