From c39adf21eab6cf30d920efb8d491ebcf1527b560 Mon Sep 17 00:00:00 2001 From: abstrakt Date: Tue, 14 Sep 2021 19:32:10 +0200 Subject: [PATCH 01/13] Using `encodeUriComponent` to make special characters like `#` be encoded in the URL --- apps/desktop-frontend/src/app/backend/watchBackendStatus.ts | 1 - apps/desktop-frontend/src/app/electron/electron-api.ts | 3 --- libs/api/common/src/blueprints/LocalBlueprintController.ts | 2 +- libs/api/common/src/replays/LocalReplayController.ts | 2 +- .../feature-replay-viewer/src/app/theater/BlueprintService.ts | 4 ++-- libs/feature-replay-viewer/src/app/theater/ReplayService.ts | 3 ++- 6 files changed, 6 insertions(+), 9 deletions(-) delete mode 100644 apps/desktop-frontend/src/app/backend/watchBackendStatus.ts delete mode 100644 apps/desktop-frontend/src/app/electron/electron-api.ts diff --git a/apps/desktop-frontend/src/app/backend/watchBackendStatus.ts b/apps/desktop-frontend/src/app/backend/watchBackendStatus.ts deleted file mode 100644 index ec5c68d0..00000000 --- a/apps/desktop-frontend/src/app/backend/watchBackendStatus.ts +++ /dev/null @@ -1 +0,0 @@ -function* watchBackendStatus() {} diff --git a/apps/desktop-frontend/src/app/electron/electron-api.ts b/apps/desktop-frontend/src/app/electron/electron-api.ts deleted file mode 100644 index e16c6ff5..00000000 --- a/apps/desktop-frontend/src/app/electron/electron-api.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { createAction } from "@reduxjs/toolkit"; - -const selectDirectoryDialog = createAction("electron/selectDirectoryDialog"); diff --git a/libs/api/common/src/blueprints/LocalBlueprintController.ts b/libs/api/common/src/blueprints/LocalBlueprintController.ts index d7bb97e9..ab186255 100644 --- a/libs/api/common/src/blueprints/LocalBlueprintController.ts +++ b/libs/api/common/src/blueprints/LocalBlueprintController.ts @@ -42,7 +42,7 @@ export class LocalBlueprintController { async redirectToFolder(@Res() res: Response, @Param("md5hash") md5hash: string, @Param("file") file: string) { const blueprintMetaData = await this.blueprint(md5hash); const { folderName } = blueprintMetaData; - const url = `/static/songs/${folderName}/${file}`; + const url = `/static/songs/${encodeURIComponent(folderName)}/${encodeURIComponent(file)}`; res.redirect(url); } } diff --git a/libs/api/common/src/replays/LocalReplayController.ts b/libs/api/common/src/replays/LocalReplayController.ts index 7968bc3e..e6ae6a20 100644 --- a/libs/api/common/src/replays/LocalReplayController.ts +++ b/libs/api/common/src/replays/LocalReplayController.ts @@ -8,7 +8,7 @@ import { LocalReplayService } from "./LocalReplayService"; */ @Controller("replays") export class LocalReplayController { - private logger = new Logger("LocalReplayController"); + private logger = new Logger(LocalReplayController.name); constructor(private localReplayService: LocalReplayService) {} diff --git a/libs/feature-replay-viewer/src/app/theater/BlueprintService.ts b/libs/feature-replay-viewer/src/app/theater/BlueprintService.ts index a2314385..589c8259 100644 --- a/libs/feature-replay-viewer/src/app/theater/BlueprintService.ts +++ b/libs/feature-replay-viewer/src/app/theater/BlueprintService.ts @@ -15,7 +15,7 @@ export class BlueprintService { constructor(@inject(TYPES.API_URL) private apiUrl: string, private readonly textureManager: TextureManager) {} async retrieveBlueprint(blueprintId: string) { - const url = `${this.apiUrl}/api/blueprints/${blueprintId}/osu`; + const url = `${this.apiUrl}/api/blueprints/${encodeURIComponent(blueprintId)}/osu`; const res = await fetch(url); const data = await res.text(); // TODO: Emit @@ -29,7 +29,7 @@ export class BlueprintService { // - (?) Storyboard async retrieveBlueprintResources(blueprintId: string) { - const url = `${this.apiUrl}/api/blueprints/${blueprintId}/bg`; + const url = `${this.apiUrl}/api/blueprints/${encodeURIComponent(blueprintId)}/bg`; return this.textureManager.loadTexture("BACKGROUND", url); } } diff --git a/libs/feature-replay-viewer/src/app/theater/ReplayService.ts b/libs/feature-replay-viewer/src/app/theater/ReplayService.ts index a60fc068..f0a1f7b3 100644 --- a/libs/feature-replay-viewer/src/app/theater/ReplayService.ts +++ b/libs/feature-replay-viewer/src/app/theater/ReplayService.ts @@ -10,7 +10,8 @@ export class ReplayService { constructor(@inject(TYPES.API_URL) private apiUrl: string) {} async retrieveReplay(replayId: string): Promise { - const url = [this.apiUrl, "api", "replays", "exported", replayId].join("/"); + const url = [this.apiUrl, "api", "replays", "exported", encodeURIComponent(replayId)].join("/"); + console.log(url); // const url = ""; const res = (await axios .get(url) From f18b8d5c22aa6c0adb58d855285a6bd93d0a3238 Mon Sep 17 00:00:00 2001 From: abstrakt Date: Tue, 14 Sep 2021 19:45:59 +0200 Subject: [PATCH 02/13] Loading background is not essential and won't crash now --- .../common/src/blueprints/LocalBlueprintController.ts | 3 +++ .../src/app/theater/RewindStageCreator.ts | 3 ++- .../src/app/theater/TextureManager.ts | 9 +++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libs/api/common/src/blueprints/LocalBlueprintController.ts b/libs/api/common/src/blueprints/LocalBlueprintController.ts index ab186255..631138c9 100644 --- a/libs/api/common/src/blueprints/LocalBlueprintController.ts +++ b/libs/api/common/src/blueprints/LocalBlueprintController.ts @@ -42,6 +42,9 @@ export class LocalBlueprintController { async redirectToFolder(@Res() res: Response, @Param("md5hash") md5hash: string, @Param("file") file: string) { const blueprintMetaData = await this.blueprint(md5hash); const { folderName } = blueprintMetaData; + // We need to encode the URI components for cases such as: + // "E:\osu!\Songs\1192060 Camellia - #1f1e33\Camellia - #1f1e33 (Realazy) [Amethyst Storm].osu" + // The two `#` characters need to be encoded to `%23` in both cases. const url = `/static/songs/${encodeURIComponent(folderName)}/${encodeURIComponent(file)}`; res.redirect(url); } diff --git a/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts b/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts index 91393179..d76ec298 100644 --- a/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts +++ b/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts @@ -26,9 +26,10 @@ export class RewindStageCreator { this.blueprintService.retrieveBlueprint(blueprintId), this.replayService.retrieveReplay(replayId), this.skinService.loadSkin(defaultSkinName), - this.blueprintService.retrieveBlueprintResources(blueprintId), ]); + await this.blueprintService.retrieveBlueprintResources(blueprintId); + // If the building is too slow or unbearable, we should push the building to a WebWorker const beatmap = buildBeatmap(blueprint, { addStacking: true, mods: replay.mods }); diff --git a/libs/feature-replay-viewer/src/app/theater/TextureManager.ts b/libs/feature-replay-viewer/src/app/theater/TextureManager.ts index c89e40ba..bd4ea2fd 100644 --- a/libs/feature-replay-viewer/src/app/theater/TextureManager.ts +++ b/libs/feature-replay-viewer/src/app/theater/TextureManager.ts @@ -23,7 +23,12 @@ export class TextureManager { } async loadTexture(textureId: RewindTextureId, url: string) { - const texture = await Texture.fromURL(url); - this.dict.set(textureId, texture); + try { + const texture = await Texture.fromURL(url); + this.dict.set(textureId, texture); + } catch (err) { + console.error(`Could not load texture ${textureId}, replacing with empty texture`); + this.dict.set(textureId, Texture.EMPTY); + } } } From 8f8051d8239cfc954b1a1015c02a459f0e6ca5c8 Mon Sep 17 00:00:00 2001 From: abstrakt Date: Wed, 15 Sep 2021 11:34:36 +0200 Subject: [PATCH 03/13] nx migration 12.9.0 --- apps/desktop/.eslintrc.json | 15 ++- migrations.json | 20 ++++ package.json | 25 +++-- workspace.json | 81 +++++++++----- yarn.lock | 213 +++++++++++++++++++++--------------- 5 files changed, 220 insertions(+), 134 deletions(-) create mode 100644 migrations.json diff --git a/apps/desktop/.eslintrc.json b/apps/desktop/.eslintrc.json index 80a09e39..1cf5ee42 100644 --- a/apps/desktop/.eslintrc.json +++ b/apps/desktop/.eslintrc.json @@ -2,8 +2,17 @@ "extends": "../../.eslintrc.json", "ignorePatterns": ["!**/*"], "overrides": [ - { "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], "rules": {} }, - { "files": ["*.ts", "*.tsx"], "rules": {} }, - { "files": ["*.js", "*.jsx"], "rules": {} } + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } ] } diff --git a/migrations.json b/migrations.json new file mode 100644 index 00000000..9d712eb6 --- /dev/null +++ b/migrations.json @@ -0,0 +1,20 @@ +{ + "migrations": [ + { + "cli": "nx", + "version": "12.9.0-beta.0", + "description": "Add outputs for caching", + "factory": "./src/migrations/update-12-9-0/add-outputs", + "package": "@nrwl/linter", + "name": "add-outputs" + }, + { + "cli": "nx", + "version": "12.9.0-beta.0", + "description": "Remove ESLint parserOptions.project config if no rules requiring type-checking are in use", + "factory": "./src/migrations/update-12-4-0/remove-eslint-project-config-if-no-type-checking-rules", + "package": "@nrwl/linter", + "name": "remove-eslint-project-config-if-no-type-checking-rules-again" + } + ] +} diff --git a/package.json b/package.json index d4ac03bc..d6d406a1 100644 --- a/package.json +++ b/package.json @@ -113,18 +113,18 @@ "@babel/preset-typescript": "7.15.0", "@nestjs/schematics": "^8.0.3", "@nestjs/testing": "^8.0.6", - "@nrwl/cli": "12.8.0", - "@nrwl/cypress": "12.8.0", - "@nrwl/eslint-plugin-nx": "12.8.0", - "@nrwl/jest": "12.8.0", - "@nrwl/linter": "12.8.0", - "@nrwl/nest": "^12.8.0", - "@nrwl/node": "12.8.0", - "@nrwl/react": "^12.8.0", - "@nrwl/storybook": "12.8.0", - "@nrwl/tao": "12.8.0", - "@nrwl/web": "12.8.0", - "@nrwl/workspace": "12.8.0", + "@nrwl/cli": "12.9.0", + "@nrwl/cypress": "12.9.0", + "@nrwl/eslint-plugin-nx": "12.9.0", + "@nrwl/jest": "12.9.0", + "@nrwl/linter": "12.9.0", + "@nrwl/nest": "12.9.0", + "@nrwl/node": "12.9.0", + "@nrwl/react": "12.9.0", + "@nrwl/storybook": "12.9.0", + "@nrwl/tao": "12.9.0", + "@nrwl/web": "12.9.0", + "@nrwl/workspace": "12.9.0", "@storybook/addon-actions": "^6.3.8", "@storybook/addon-essentials": "^6.3.8", "@storybook/addon-links": "^6.3.8", @@ -184,3 +184,4 @@ ] } } + diff --git a/workspace.json b/workspace.json index d5875f6b..581cc247 100644 --- a/workspace.json +++ b/workspace.json @@ -56,7 +56,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/desktop/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -77,7 +78,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/api/common/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -98,7 +100,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/api/desktop/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -163,7 +166,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/desktop/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -213,7 +217,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/desktop-backend/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -263,7 +268,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/desktop-backend-preload/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -338,7 +344,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/desktop-frontend/**/*.{ts,tsx,js,jsx}"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -372,7 +379,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/desktop-frontend-e2e/**/*.{js,ts}"] - } + }, + "outputs": ["{options.outputFile}"] } } }, @@ -414,7 +422,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/desktop-frontend-preload/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -435,7 +444,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/electron/api/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -456,7 +466,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/feature-replay-viewer/**/*.{ts,tsx,js,jsx}"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -521,7 +532,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/feature-replay-viewer-e2e/**/*.{js,ts}"] - } + }, + "outputs": ["{options.outputFile}"] } } }, @@ -534,7 +546,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/osu/core/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -555,7 +568,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/osu-local/db-reader/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -576,7 +590,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/osu-local/gosumemory/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -597,7 +612,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/osu-local/osr-reader/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -618,7 +634,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/osu-local/skin-reader/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -639,7 +656,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/osu-local/utils/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -660,7 +678,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/osu/math/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -681,7 +700,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/osu-pixi/classic-components/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -702,7 +722,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["libs/osu/skin/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -752,7 +773,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/osu-stable-test-generator/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -802,7 +824,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/rewind-electron/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -876,7 +899,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/web/**/*.{ts,tsx,js,jsx}"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -926,7 +950,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/web-api/**/*.ts"] - } + }, + "outputs": ["{options.outputFile}"] }, "test": { "executor": "@nrwl/jest:jest", @@ -960,7 +985,8 @@ "executor": "@nrwl/linter:eslint", "options": { "lintFilePatterns": ["apps/web-e2e/**/*.{js,ts}"] - } + }, + "outputs": ["{options.outputFile}"] } } } @@ -994,6 +1020,5 @@ "linter": "eslint", "unitTestRunner": "jest" } - }, - "defaultProject": "web" + } } diff --git a/yarn.lock b/yarn.lock index 2baeae82..27b50aa7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2281,26 +2281,26 @@ node-gyp "^7.1.0" read-package-json-fast "^2.0.1" -"@nrwl/cli@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-12.8.0.tgz#51527fbabe3248cf4f910329e472665728312064" - integrity sha512-QUIICAXPeWfsM8EMIavdjGHmLFrDoSQEjXC0PiAZqiR9prcqp4jOWOZ/J1CTQfpAyINgjYoBQo+ao+YC7jX5Sw== +"@nrwl/cli@*", "@nrwl/cli@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-12.9.0.tgz#f5fccd973006ad2802d7c823b28820ac1fa6c27c" + integrity sha512-YKTZ3G07f6Y4MedOOkBmCi1Y72gu3ssCk2J50wL76SaiSjJTUSAz1NkKLsPwO6S8/QloMSR71tI42HJG2bbpwQ== dependencies: - "@nrwl/tao" "12.8.0" + "@nrwl/tao" "12.9.0" chalk "4.1.0" v8-compile-cache "2.3.0" yargs "15.4.1" yargs-parser "20.0.0" -"@nrwl/cypress@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-12.8.0.tgz#87ac27c9e0832512f8dfbe7409a07a5c8bb84104" - integrity sha512-TALGruMK+8FRQAxPxh9UG5mcgsiTGJ0oGhHjJwCaaK5Eqg+/je8f4xaRmLo8YoX2CVl8B1q3pG599/nABtALOQ== +"@nrwl/cypress@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-12.9.0.tgz#7e451569b53764b5aa5160d428de8d29d7c6725e" + integrity sha512-hiPo8zDCBwAEcedTxH3zmXIlgAObeG3K5S1QeVOrJbrNYscz7l69h9fXKJ8CLmCZcflijgK2/6ZwC85DGhllhg== dependencies: "@cypress/webpack-preprocessor" "4.1.5" - "@nrwl/devkit" "12.8.0" - "@nrwl/linter" "12.8.0" - "@nrwl/workspace" "12.8.0" + "@nrwl/devkit" "12.9.0" + "@nrwl/linter" "12.9.0" + "@nrwl/workspace" "12.9.0" chalk "4.1.0" fork-ts-checker-webpack-plugin "6.2.10" rxjs "^6.5.4" @@ -2322,36 +2322,38 @@ strip-json-comments "2.0.1" tslib "^2.0.0" -"@nrwl/devkit@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-12.8.0.tgz#7bdce01d8ee39b206e503ca18c3223fd424515e7" - integrity sha512-V35yxBM5yyahsFzwCGRwNNzHfh698UsWUJAgeGPUJLYN4y8LCrKxiRvVlRCPgkjd46P2SuClJx6NjEm2DRoQ9Q== +"@nrwl/devkit@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-12.9.0.tgz#fbf6eb715d1deb22fa919bceb3dff7a5c990d415" + integrity sha512-mobW2XKmQicTdhn0XQStNnYmhMC0Aj7qqX9lS/8IX561PtgocR0MPH9rTWOfNECpwHhj2YwTRTHjQfgv29btxw== dependencies: - "@nrwl/tao" "12.8.0" + "@nrwl/tao" "12.9.0" ejs "^3.1.5" ignore "^5.0.4" rxjs "^6.5.4" semver "7.3.4" tslib "^2.0.0" -"@nrwl/eslint-plugin-nx@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-12.8.0.tgz#264cb3b73d538e9f2205eda282ec92e421eed44c" - integrity sha512-xbstWCJ2/gUtgIOQ6VJ7FTvjfrvMq/4iGtv49b9bKIrxTZlVLnGPnqi8OYYLP7eUrp6q9Jr3lkSlHGwO52Hd8A== +"@nrwl/eslint-plugin-nx@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-12.9.0.tgz#4e8fb2ffbf2528702f182ccff9074375b60cebfd" + integrity sha512-j1TL2GfgEEifKY74mupq9z0FRnE1RAtng640TomtqVYHNifAHp21e2i055S6Mf1Q7pT5OefYBzwtCxBiCNlDpg== dependencies: - "@nrwl/devkit" "12.8.0" - "@nrwl/workspace" "12.8.0" + "@nrwl/devkit" "12.9.0" + "@nrwl/workspace" "12.9.0" "@typescript-eslint/experimental-utils" "~4.28.3" confusing-browser-globals "^1.0.9" + ts-node "^9.1.1" + tsconfig-paths "^3.9.0" -"@nrwl/jest@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-12.8.0.tgz#65ab4844bdc07bac1faaa444403ad29c9f294da6" - integrity sha512-ATqhv6K/1+hFMLUKoG4lhn2a4FS3iDJOCenP4T9YAiYJQ2tIc+g9bh2agM3EW2EeSP7fHm2zeCdvprd4sJG6DQ== +"@nrwl/jest@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-12.9.0.tgz#fb20631274c2462b73a0cb88d73ba7897c35e303" + integrity sha512-PHPG6DlwNgrT4+uplJqM814k+gqNV/m85FIes6JkzRO8XMK9jmqF0hwJvyymCZHDmGXMqwa0muoxkjoJs2CI/A== dependencies: "@jest/reporters" "27.0.6" "@jest/test-result" "27.0.6" - "@nrwl/devkit" "12.8.0" + "@nrwl/devkit" "12.9.0" chalk "4.1.0" identity-obj-proxy "3.0.0" jest-config "27.0.6" @@ -2371,12 +2373,13 @@ strip-json-comments "2.0.1" tslib "^2.0.0" -"@nrwl/linter@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/linter/-/linter-12.8.0.tgz#6f6c6192a19bb7ab7020576465871372a77459c7" - integrity sha512-8FJwa5Fj3qlWfJoCTq1rccCBicgSfJXA+FKfkm1fT3hvriJuMlC3hMXXKuB9WGdJMIxs2X7OEzR8mMgwH77V/Q== +"@nrwl/linter@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/linter/-/linter-12.9.0.tgz#1633045cb64871fb89eaced8c5b66664211237c6" + integrity sha512-8acZTT0nkwi914uJ6fMhZT6fZMMKOUGGjEWhvw9D3Lhe0aACsnXXSB+hJh+E8qchcGMYliqXuSi3X4Liq/fUFw== dependencies: - "@nrwl/devkit" "12.8.0" + "@nrwl/devkit" "12.9.0" + "@nrwl/jest" "12.9.0" glob "7.1.4" minimatch "3.0.4" tmp "~0.2.1" @@ -2393,26 +2396,26 @@ tmp "0.0.33" tslib "^2.0.0" -"@nrwl/nest@^12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-12.8.0.tgz#b82ffcd7e8a3f50c220fe89ac5f6e794b6da9888" - integrity sha512-lLGcK0TO3hfMte9W/kHRcZCQ9cLnbocYBKTs+ofBDn98tQ6fHPOyFjgX14lUBWWg+2QqfBswv2U/TI/o2lYOZg== +"@nrwl/nest@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-12.9.0.tgz#d3c479bc73a79b1134f502bede977527611cd830" + integrity sha512-V71A1+rF0hb7l1q5yULujxRAsTv7KO5fk5yIj3TnGEgbM2DHVPlgAWavj8+t2th2U9TdCJ67qn2PQjpWk1/NBA== dependencies: "@nestjs/schematics" "^7.0.0" - "@nrwl/devkit" "12.8.0" - "@nrwl/jest" "12.8.0" - "@nrwl/linter" "12.8.0" - "@nrwl/node" "12.8.0" - -"@nrwl/node@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-12.8.0.tgz#0bf80351a744cde2b659cba3794dba9c9790fbaf" - integrity sha512-Y6wahv/1omLgnnZJdFSj2w+GIHMmxS6vZvqU2UPBHOXoH2NPwH6Eb0iV9UXbu11sTdb8S4gtBzG9Y9FnJptXJA== - dependencies: - "@nrwl/devkit" "12.8.0" - "@nrwl/jest" "12.8.0" - "@nrwl/linter" "12.8.0" - "@nrwl/workspace" "12.8.0" + "@nrwl/devkit" "12.9.0" + "@nrwl/jest" "12.9.0" + "@nrwl/linter" "12.9.0" + "@nrwl/node" "12.9.0" + +"@nrwl/node@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-12.9.0.tgz#fbc0a878d47f0ddff4cda28cdb34c3fe04a830c7" + integrity sha512-AluoSQVMKMCPMvlPZbBxTNlVQTx6/nFOZZMOYCrNLWgWuyfX29jrghCw3WSDAW41B9+ruhxPLxzmER/T58FfuQ== + dependencies: + "@nrwl/devkit" "12.9.0" + "@nrwl/jest" "12.9.0" + "@nrwl/linter" "12.9.0" + "@nrwl/workspace" "12.9.0" chalk "4.1.0" circular-dependency-plugin "5.2.0" copy-webpack-plugin "6.4.1" @@ -2431,20 +2434,20 @@ webpack-merge "4.2.1" webpack-node-externals "1.7.2" -"@nrwl/react@^12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/react/-/react-12.8.0.tgz#c09e717ec541c5ecad46598e0200338917c6dc5c" - integrity sha512-PJOi+5k37IsQpbYY3DTBb8WhpDxlY7Vp+5Z0fX/tB9qTmGKsimDZBdE18Yu+4WNDyJTrtAnF5+3LFntDSkT74w== +"@nrwl/react@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/react/-/react-12.9.0.tgz#dd10aa3b6933ef319f97d3f464b71bcce0f58626" + integrity sha512-CezxJ6qFf6LszaR/NI8rQlXFGqieRMa4ORGmzQVTahdjnot5xTRT+c3RV6yLmHqkKoXgHXZNJi1PMtbD4kRsCw== dependencies: "@babel/core" "^7.15.0" "@babel/preset-react" "^7.14.5" - "@nrwl/cypress" "12.8.0" - "@nrwl/devkit" "12.8.0" - "@nrwl/jest" "12.8.0" - "@nrwl/linter" "12.8.0" - "@nrwl/storybook" "12.8.0" - "@nrwl/web" "12.8.0" - "@nrwl/workspace" "12.8.0" + "@nrwl/cypress" "12.9.0" + "@nrwl/devkit" "12.9.0" + "@nrwl/jest" "12.9.0" + "@nrwl/linter" "12.9.0" + "@nrwl/storybook" "12.9.0" + "@nrwl/web" "12.9.0" + "@nrwl/workspace" "12.9.0" "@pmmmwh/react-refresh-webpack-plugin" "^0.4.3" "@storybook/node-logger" "6.1.20" "@svgr/webpack" "^5.5.0" @@ -2459,15 +2462,15 @@ webpack "4.46.0" webpack-merge "4.2.1" -"@nrwl/storybook@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-12.8.0.tgz#4d110e99f4a7b1c9e487841850490a44d06be31e" - integrity sha512-NO8weLhaNrHIUsTZP8tb08JUB5aEAkeuwvkVtARf+qhd83gbJg1N2SnoBSvCKxnsJ6qXM+0wQQbWSdsb08w44w== +"@nrwl/storybook@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-12.9.0.tgz#7af62231f58994546c33ee386967ca5a68e26863" + integrity sha512-J6hAfPVh3WK97qvs7vI2xTYx2Afn3hxFkew19Z4HQeJjsKpJ0xVz9OFPVmWnAmL9A3NpYzfIvE7aRwNAKlA8oQ== dependencies: - "@nrwl/cypress" "12.8.0" - "@nrwl/devkit" "12.8.0" - "@nrwl/linter" "12.8.0" - "@nrwl/workspace" "12.8.0" + "@nrwl/cypress" "12.9.0" + "@nrwl/devkit" "12.9.0" + "@nrwl/linter" "12.9.0" + "@nrwl/workspace" "12.9.0" core-js "^3.6.5" semver "7.3.4" ts-loader "5.4.5" @@ -2490,15 +2493,16 @@ tslib "^2.0.0" yargs-parser "20.0.0" -"@nrwl/tao@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-12.8.0.tgz#fafbcf1885c8405df92e18633407add9d56c07d0" - integrity sha512-AspbhwKvuPbWqRGJIt13VIhL/D+73QhQQ6z94osfCaXfEmkMDjHJ8KUfxdVOYYLuRtE+cqeLMDZWPmBgfzbXtA== +"@nrwl/tao@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-12.9.0.tgz#f8470ac0dccd5df414afc244fbbf37c23eb75764" + integrity sha512-a97JYoLohhBRthnWAGMh3++8Ri/yvCQUG/INBAYxW6sWAk2owJ6DIEIERP4yhIW29HPdqZ/fA2k9iqU6EgIAew== dependencies: chalk "4.1.0" enquirer "~2.3.6" fs-extra "^9.1.0" jsonc-parser "3.0.0" + nx "12.9.0" rxjs "^6.5.4" rxjs-for-await "0.0.2" semver "7.3.4" @@ -2506,10 +2510,10 @@ tslib "^2.0.0" yargs-parser "20.0.0" -"@nrwl/web@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-12.8.0.tgz#fa0585d1f31055f50165926f4ffb0ad2343ea0da" - integrity sha512-oOGyjMZzryiZzCDbWDscpmT7KOsmYz5b8yefPH7X+w4PHpxFwx+Ew+ha4x6VKbt7ViaNUe1yGXJPxEbZNRlPjg== +"@nrwl/web@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-12.9.0.tgz#04a938335a4707a4e26439fffea36a454b61c545" + integrity sha512-81iPFI4eoQSUabU6udwrzoL3LJxpOo95cSJ/cnKozoPPGQQnbmnhfNC8gPESvBUa735t6bOYTDMPGZXwYZcqbQ== dependencies: "@babel/core" "^7.15.0" "@babel/plugin-proposal-class-properties" "^7.14.5" @@ -2519,11 +2523,11 @@ "@babel/preset-env" "^7.15.0" "@babel/preset-typescript" "^7.15.0" "@babel/runtime" "^7.14.8" - "@nrwl/cypress" "12.8.0" - "@nrwl/devkit" "12.8.0" - "@nrwl/jest" "12.8.0" - "@nrwl/linter" "12.8.0" - "@nrwl/workspace" "12.8.0" + "@nrwl/cypress" "12.9.0" + "@nrwl/devkit" "12.9.0" + "@nrwl/jest" "12.9.0" + "@nrwl/linter" "12.9.0" + "@nrwl/workspace" "12.9.0" "@rollup/plugin-babel" "^5.3.0" "@rollup/plugin-commonjs" "^20.0.0" "@rollup/plugin-image" "^2.1.0" @@ -2591,15 +2595,15 @@ webpack-subresource-integrity "^1.5.2" worker-plugin "3.2.0" -"@nrwl/workspace@12.8.0": - version "12.8.0" - resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-12.8.0.tgz#fb2a79a803e94dbc49365670f147cea6ef9f98a6" - integrity sha512-L/PHZze29pqosfCHQg0AuUG9QpDLROAcl8gdhYiRMrx4jbrox2nGHWE+lpICX3VVtbFJP6W9iQoFzGBvoCXu6A== +"@nrwl/workspace@12.9.0": + version "12.9.0" + resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-12.9.0.tgz#218ac0bba8f1cd84235bc636ed6a928ec3550f86" + integrity sha512-P8jab7DebwU1fMnpA9A+7oBXNLxVYPqdGPIusOsvpRaJ9tjzhXhVM4OCYu3ZnmcpHboskmSwUMcIvOARRcwWLg== dependencies: - "@nrwl/cli" "12.8.0" - "@nrwl/devkit" "12.8.0" - "@nrwl/jest" "12.8.0" - "@nrwl/linter" "12.8.0" + "@nrwl/cli" "12.9.0" + "@nrwl/devkit" "12.9.0" + "@nrwl/jest" "12.9.0" + "@nrwl/linter" "12.9.0" chalk "4.1.0" chokidar "^3.5.1" cosmiconfig "^4.0.0" @@ -14235,6 +14239,13 @@ nx-electron@^11.1.3: webpack-merge "^5.7.3" webpack-node-externals "^2.5.2" +nx@12.9.0: + version "12.9.0" + resolved "https://registry.yarnpkg.com/nx/-/nx-12.9.0.tgz#8553ce806fd19181ad8f81395f7812ab9fe5d4e2" + integrity sha512-AOyMJPpioeMtY1UJ2Zgxyjfsc6rg31uztqiCZIQEOLwXoYIYiPuz54IhTngW7c1MjtxDl8B62G8xCjlRv2zjhw== + dependencies: + "@nrwl/cli" "*" + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -17477,6 +17488,14 @@ source-map-support@0.5.19, source-map-support@^0.5.16, source-map-support@^0.5.1 buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@^0.5.17: + version "0.5.20" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" + integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" @@ -18633,6 +18652,18 @@ ts-loader@^8.0.14: micromatch "^4.0.0" semver "^7.3.4" +ts-node@^9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== + dependencies: + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + ts-node@~10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.2.1.tgz#4cc93bea0a7aba2179497e65bb08ddfc198b3ab5" From 8799836d5fedbc63a518d6c35ac264928b32d1a0 Mon Sep 17 00:00:00 2001 From: abstrakt Date: Wed, 15 Sep 2021 11:41:34 +0200 Subject: [PATCH 04/13] Remove unnecessary stuff --- libs/api/desktop/test/setup.spec.ts | 3 +-- libs/electron/api/src/index.ts | 18 ------------------ 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/libs/api/desktop/test/setup.spec.ts b/libs/api/desktop/test/setup.spec.ts index 94f0f48e..b2575861 100644 --- a/libs/api/desktop/test/setup.spec.ts +++ b/libs/api/desktop/test/setup.spec.ts @@ -1,5 +1,4 @@ import * as request from "supertest"; -import { setupBootstrap } from "@rewind/api/desktop"; import { INestApplication } from "@nestjs/common"; import { DesktopConfigService } from "../src/config/DesktopConfigService"; import { join } from "path"; @@ -17,7 +16,7 @@ describe("Setup E2E", () => { let app: INestApplication; beforeAll(async () => { - app = await setupBootstrap({ userDataPath: applicationDataPath }); + // app = await setupBootstrap({ userDataPath: applicationDataPath }); }); it("/GET desktop", () => { diff --git a/libs/electron/api/src/index.ts b/libs/electron/api/src/index.ts index 043baf3f..7f079731 100644 --- a/libs/electron/api/src/index.ts +++ b/libs/electron/api/src/index.ts @@ -1,21 +1,3 @@ -export interface ElectronAPI { - getAppVersion: () => Promise; - platform: string; -} - -export const validSendChannels = ["openDirectorySelect", "reboot"] as const; -export type ValidSendChannel = typeof validSendChannels[number]; - -export const validReceiveChannels = ["directorySelected"] as const; -export type ValidReceiveChannel = typeof validReceiveChannels[number]; - -type Destroyer = () => void; - -export interface SecureElectronAPI { - send: (channel: ValidSendChannel, ...args: string[]) => void; - receive: (channel: ValidReceiveChannel, func: (...args: any[]) => void) => Destroyer; -} - export interface FrontendPreloadAPI { getAppVersion: () => Promise; getPlatform: () => Promise; // actually NodeJS.Platform From 12f8f9879574e1ebe64c9de35ab2032dc81e2917 Mon Sep 17 00:00:00 2001 From: abstrakt Date: Wed, 15 Sep 2021 11:49:22 +0200 Subject: [PATCH 05/13] Added a Rewind Pixi UI component library --- libs/osu-pixi/rewind/.babelrc | 3 +++ libs/osu-pixi/rewind/.eslintrc.json | 18 +++++++++++++++ libs/osu-pixi/rewind/README.md | 7 ++++++ libs/osu-pixi/rewind/jest.config.js | 14 ++++++++++++ libs/osu-pixi/rewind/src/index.ts | 1 + .../rewind/src/lib/osu-pixi-rewind.spec.ts | 7 ++++++ .../rewind/src/lib/osu-pixi-rewind.ts | 3 +++ libs/osu-pixi/rewind/tsconfig.json | 13 +++++++++++ libs/osu-pixi/rewind/tsconfig.lib.json | 10 +++++++++ libs/osu-pixi/rewind/tsconfig.spec.json | 9 ++++++++ nx.json | 3 +++ package.json | 1 - tsconfig.base.json | 1 + workspace.json | 22 +++++++++++++++++++ 14 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 libs/osu-pixi/rewind/.babelrc create mode 100644 libs/osu-pixi/rewind/.eslintrc.json create mode 100644 libs/osu-pixi/rewind/README.md create mode 100644 libs/osu-pixi/rewind/jest.config.js create mode 100644 libs/osu-pixi/rewind/src/index.ts create mode 100644 libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.spec.ts create mode 100644 libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.ts create mode 100644 libs/osu-pixi/rewind/tsconfig.json create mode 100644 libs/osu-pixi/rewind/tsconfig.lib.json create mode 100644 libs/osu-pixi/rewind/tsconfig.spec.json diff --git a/libs/osu-pixi/rewind/.babelrc b/libs/osu-pixi/rewind/.babelrc new file mode 100644 index 00000000..cf7ddd99 --- /dev/null +++ b/libs/osu-pixi/rewind/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]] +} diff --git a/libs/osu-pixi/rewind/.eslintrc.json b/libs/osu-pixi/rewind/.eslintrc.json new file mode 100644 index 00000000..3456be9b --- /dev/null +++ b/libs/osu-pixi/rewind/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/osu-pixi/rewind/README.md b/libs/osu-pixi/rewind/README.md new file mode 100644 index 00000000..13428050 --- /dev/null +++ b/libs/osu-pixi/rewind/README.md @@ -0,0 +1,7 @@ +# osu-pixi-rewind + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test osu-pixi-rewind` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/osu-pixi/rewind/jest.config.js b/libs/osu-pixi/rewind/jest.config.js new file mode 100644 index 00000000..67629721 --- /dev/null +++ b/libs/osu-pixi/rewind/jest.config.js @@ -0,0 +1,14 @@ +module.exports = { + displayName: "osu-pixi-rewind", + preset: "../../../jest.preset.js", + globals: { + "ts-jest": { + tsconfig: "/tsconfig.spec.json", + }, + }, + transform: { + "^.+\\.[tj]sx?$": "ts-jest", + }, + moduleFileExtensions: ["ts", "tsx", "js", "jsx"], + coverageDirectory: "../../../coverage/libs/osu-pixi/rewind", +}; diff --git a/libs/osu-pixi/rewind/src/index.ts b/libs/osu-pixi/rewind/src/index.ts new file mode 100644 index 00000000..3efda6f2 --- /dev/null +++ b/libs/osu-pixi/rewind/src/index.ts @@ -0,0 +1 @@ +export * from "./lib/osu-pixi-rewind"; diff --git a/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.spec.ts b/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.spec.ts new file mode 100644 index 00000000..2a8d6da5 --- /dev/null +++ b/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.spec.ts @@ -0,0 +1,7 @@ +import { osuPixiRewind } from "./osu-pixi-rewind"; + +describe("osuPixiRewind", () => { + it("should work", () => { + expect(osuPixiRewind()).toEqual("osu-pixi-rewind"); + }); +}); diff --git a/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.ts b/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.ts new file mode 100644 index 00000000..eee3a015 --- /dev/null +++ b/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.ts @@ -0,0 +1,3 @@ +export function osuPixiRewind(): string { + return "osu-pixi-rewind"; +} diff --git a/libs/osu-pixi/rewind/tsconfig.json b/libs/osu-pixi/rewind/tsconfig.json new file mode 100644 index 00000000..667a3463 --- /dev/null +++ b/libs/osu-pixi/rewind/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/osu-pixi/rewind/tsconfig.lib.json b/libs/osu-pixi/rewind/tsconfig.lib.json new file mode 100644 index 00000000..efdd77fb --- /dev/null +++ b/libs/osu-pixi/rewind/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": [] + }, + "include": ["**/*.ts"], + "exclude": ["**/*.spec.ts"] +} diff --git a/libs/osu-pixi/rewind/tsconfig.spec.json b/libs/osu-pixi/rewind/tsconfig.spec.json new file mode 100644 index 00000000..65aff509 --- /dev/null +++ b/libs/osu-pixi/rewind/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js", "**/*.spec.jsx", "**/*.d.ts"] +} diff --git a/nx.json b/nx.json index af7fc421..3f690a6d 100644 --- a/nx.json +++ b/nx.json @@ -89,6 +89,9 @@ "osu-pixi-classic-components": { "tags": [] }, + "osu-pixi-rewind": { + "tags": [] + }, "osu-skin": { "tags": [] }, diff --git a/package.json b/package.json index d6d406a1..1bdfec42 100644 --- a/package.json +++ b/package.json @@ -184,4 +184,3 @@ ] } } - diff --git a/tsconfig.base.json b/tsconfig.base.json index 1564151c..a276f0c3 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -26,6 +26,7 @@ "@rewind/osu-local/skin-reader": ["libs/osu-local/skin-reader/src/index.ts"], "@rewind/osu-local/utils": ["libs/osu-local/utils/src/index.ts"], "@rewind/osu-pixi/classic-components": ["libs/osu-pixi/classic-components/src/index.ts"], + "@rewind/osu-pixi/rewind": ["libs/osu-pixi/rewind/src/index.ts"], "@rewind/osu/core": ["libs/osu/core/src/index.ts"], "@rewind/osu/math": ["libs/osu/math/src/index.ts"], "@rewind/osu/skin": ["libs/osu/skin/src/index.ts"], diff --git a/workspace.json b/workspace.json index 581cc247..14bbdf10 100644 --- a/workspace.json +++ b/workspace.json @@ -713,6 +713,28 @@ } } }, + "osu-pixi-rewind": { + "root": "libs/osu-pixi/rewind", + "sourceRoot": "libs/osu-pixi/rewind/src", + "projectType": "library", + "targets": { + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["libs/osu-pixi/rewind/**/*.ts"] + } + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["coverage/libs/osu-pixi/rewind"], + "options": { + "jestConfig": "libs/osu-pixi/rewind/jest.config.js", + "passWithNoTests": true + } + } + } + }, "osu-skin": { "root": "libs/osu/skin", "sourceRoot": "libs/osu/skin/src", From 7c9a76a5fd0dca4f0e4a9806fb712e8b008735a4 Mon Sep 17 00:00:00 2001 From: abstrakt Date: Wed, 15 Sep 2021 11:54:34 +0200 Subject: [PATCH 06/13] Moved HitErrorBar and AnalysisCursor to corresponding modules --- .../stage/rewind/components/hud/ForegroundHUDPreparer.ts | 6 +++--- .../stage/rewind/components/playfield/CursorPreparer.ts | 2 +- .../classic-components/src/hud}/HitErrorBar.ts | 8 ++------ libs/osu-pixi/classic-components/src/index.ts | 1 + libs/osu-pixi/rewind/src/index.ts | 2 +- .../rewind/src/lib}/AnalysisCursor.ts | 0 libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.spec.ts | 7 ------- libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.ts | 3 --- 8 files changed, 8 insertions(+), 21 deletions(-) rename libs/{feature-replay-viewer/src/app/pixi/components => osu-pixi/classic-components/src/hud}/HitErrorBar.ts (92%) rename libs/{feature-replay-viewer/src/app/pixi/components => osu-pixi/rewind/src/lib}/AnalysisCursor.ts (100%) delete mode 100644 libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.spec.ts delete mode 100644 libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.ts diff --git a/libs/feature-replay-viewer/src/app/stage/rewind/components/hud/ForegroundHUDPreparer.ts b/libs/feature-replay-viewer/src/app/stage/rewind/components/hud/ForegroundHUDPreparer.ts index eb704162..fa6ea923 100644 --- a/libs/feature-replay-viewer/src/app/stage/rewind/components/hud/ForegroundHUDPreparer.ts +++ b/libs/feature-replay-viewer/src/app/stage/rewind/components/hud/ForegroundHUDPreparer.ts @@ -1,7 +1,7 @@ import { inject, injectable } from "inversify"; import { GameSimulator } from "../../GameSimulator"; import { Container, Text } from "pixi.js"; -import { AnalysisHitErrorBar } from "../../../../pixi/components/HitErrorBar"; +import { OsuClassicHitErrorBar } from "@rewind/osu-pixi/classic-components"; import { calculateDigits, OsuClassicAccuracy, OsuClassicNumber } from "@rewind/osu-pixi/classic-components"; import { hitWindowsForOD } from "@rewind/osu/math"; import { STAGE_HEIGHT, STAGE_WIDTH } from "../stage/GameStagePreparer"; @@ -13,7 +13,7 @@ import { STAGE_TYPES } from "../../../STAGE_TYPES"; export class ForegroundHUDPreparer { container: Container; stats: Text; - hitErrorBar: AnalysisHitErrorBar; + hitErrorBar: OsuClassicHitErrorBar; constructor( @inject(STAGE_TYPES.BEATMAP) private readonly beatmap: Beatmap, @@ -22,7 +22,7 @@ export class ForegroundHUDPreparer { ) { this.container = new Container(); this.stats = new Text("", { fontSize: 16, fill: 0xeeeeee, fontFamily: "Arial", align: "left" }); - this.hitErrorBar = new AnalysisHitErrorBar(); + this.hitErrorBar = new OsuClassicHitErrorBar(); } prepare() { diff --git a/libs/feature-replay-viewer/src/app/stage/rewind/components/playfield/CursorPreparer.ts b/libs/feature-replay-viewer/src/app/stage/rewind/components/playfield/CursorPreparer.ts index c3a7ecfc..e541c5f7 100644 --- a/libs/feature-replay-viewer/src/app/stage/rewind/components/playfield/CursorPreparer.ts +++ b/libs/feature-replay-viewer/src/app/stage/rewind/components/playfield/CursorPreparer.ts @@ -1,7 +1,7 @@ import { Container } from "pixi.js"; import { OsuClassicCursor } from "@rewind/osu-pixi/classic-components"; import { findIndexInReplayAtTime, interpolateReplayPosition } from "../../../../../utils/Replay"; -import { AnalysisCursor } from "../../../../pixi/components/AnalysisCursor"; +import { AnalysisCursor } from "@rewind/osu-pixi/rewind"; import { OsuAction } from "@rewind/osu/core"; import { inject, injectable } from "inversify"; import { STAGE_TYPES } from "../../../STAGE_TYPES"; diff --git a/libs/feature-replay-viewer/src/app/pixi/components/HitErrorBar.ts b/libs/osu-pixi/classic-components/src/hud/HitErrorBar.ts similarity index 92% rename from libs/feature-replay-viewer/src/app/pixi/components/HitErrorBar.ts rename to libs/osu-pixi/classic-components/src/hud/HitErrorBar.ts index 555d75cb..29f14a59 100644 --- a/libs/feature-replay-viewer/src/app/pixi/components/HitErrorBar.ts +++ b/libs/osu-pixi/classic-components/src/hud/HitErrorBar.ts @@ -1,8 +1,6 @@ -import { Container, Graphics, Sprite, Texture } from "pixi.js"; +import { Container, Sprite, Texture } from "pixi.js"; import { applyInterpolation, rgbToInt } from "@rewind/osu/math"; -// fixed width - type HitEvent = { offset: number; timeAgo: number; @@ -32,9 +30,7 @@ function coloredSprite(color: number) { return sprite; } -// TODO: Move to osu-classic ? -// We can have a more advanced one here -export class AnalysisHitErrorBar { +export class OsuClassicHitErrorBar { container: Container; bg50: Sprite; bg100: Sprite; diff --git a/libs/osu-pixi/classic-components/src/index.ts b/libs/osu-pixi/classic-components/src/index.ts index a1db5b53..6459e862 100644 --- a/libs/osu-pixi/classic-components/src/index.ts +++ b/libs/osu-pixi/classic-components/src/index.ts @@ -9,6 +9,7 @@ export * from "./hitobjects/OsuClassicSliderTick"; export * from "./hitobjects/OsuClassicCursor"; export * from "./hitobjects/OsuClassicSpinner"; +export * from "./hud/HitErrorBar"; export * from "./hud/OsuClassicNumber"; export * from "./hud/OsuClassicAccuracy"; export * from "./hud/OsuClassicJudgement"; diff --git a/libs/osu-pixi/rewind/src/index.ts b/libs/osu-pixi/rewind/src/index.ts index 3efda6f2..9937e33c 100644 --- a/libs/osu-pixi/rewind/src/index.ts +++ b/libs/osu-pixi/rewind/src/index.ts @@ -1 +1 @@ -export * from "./lib/osu-pixi-rewind"; +export * from "./lib/AnalysisCursor"; diff --git a/libs/feature-replay-viewer/src/app/pixi/components/AnalysisCursor.ts b/libs/osu-pixi/rewind/src/lib/AnalysisCursor.ts similarity index 100% rename from libs/feature-replay-viewer/src/app/pixi/components/AnalysisCursor.ts rename to libs/osu-pixi/rewind/src/lib/AnalysisCursor.ts diff --git a/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.spec.ts b/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.spec.ts deleted file mode 100644 index 2a8d6da5..00000000 --- a/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.spec.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { osuPixiRewind } from "./osu-pixi-rewind"; - -describe("osuPixiRewind", () => { - it("should work", () => { - expect(osuPixiRewind()).toEqual("osu-pixi-rewind"); - }); -}); diff --git a/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.ts b/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.ts deleted file mode 100644 index eee3a015..00000000 --- a/libs/osu-pixi/rewind/src/lib/osu-pixi-rewind.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function osuPixiRewind(): string { - return "osu-pixi-rewind"; -} From 8cdab76f98fdce32d017b7e9da0da0bfc1cb61e4 Mon Sep 17 00:00:00 2001 From: abstrakt Date: Wed, 15 Sep 2021 12:47:06 +0200 Subject: [PATCH 07/13] Moved more files --- .../src/app/{pixi => stage}/pooling/ObjectPool.ts | 0 .../src/app/{pixi => stage}/pooling/TemporaryObjectPool.ts | 0 .../app/stage/rewind/components/playfield/SliderPreparer.ts | 5 ++--- .../src/utils => osu/math/src}/Sliders.ts | 0 libs/osu/math/src/index.ts | 1 + 5 files changed, 3 insertions(+), 3 deletions(-) rename libs/feature-replay-viewer/src/app/{pixi => stage}/pooling/ObjectPool.ts (100%) rename libs/feature-replay-viewer/src/app/{pixi => stage}/pooling/TemporaryObjectPool.ts (100%) rename libs/{feature-replay-viewer/src/utils => osu/math/src}/Sliders.ts (100%) diff --git a/libs/feature-replay-viewer/src/app/pixi/pooling/ObjectPool.ts b/libs/feature-replay-viewer/src/app/stage/pooling/ObjectPool.ts similarity index 100% rename from libs/feature-replay-viewer/src/app/pixi/pooling/ObjectPool.ts rename to libs/feature-replay-viewer/src/app/stage/pooling/ObjectPool.ts diff --git a/libs/feature-replay-viewer/src/app/pixi/pooling/TemporaryObjectPool.ts b/libs/feature-replay-viewer/src/app/stage/pooling/TemporaryObjectPool.ts similarity index 100% rename from libs/feature-replay-viewer/src/app/pixi/pooling/TemporaryObjectPool.ts rename to libs/feature-replay-viewer/src/app/stage/pooling/TemporaryObjectPool.ts diff --git a/libs/feature-replay-viewer/src/app/stage/rewind/components/playfield/SliderPreparer.ts b/libs/feature-replay-viewer/src/app/stage/rewind/components/playfield/SliderPreparer.ts index 99cdd6f7..fdb50233 100644 --- a/libs/feature-replay-viewer/src/app/stage/rewind/components/playfield/SliderPreparer.ts +++ b/libs/feature-replay-viewer/src/app/stage/rewind/components/playfield/SliderPreparer.ts @@ -8,13 +8,12 @@ import { OsuClassicSliderTick, SliderBodySettings, } from "@rewind/osu-pixi/classic-components"; -import { RGB, Vec2 } from "@rewind/osu/math"; -import { sliderRepeatAngle } from "../../../../../utils/Sliders"; +import { RGB, sliderRepeatAngle, Vec2 } from "@rewind/osu/math"; import { GameplayClock } from "../../../core/GameplayClock"; import { StageViewService } from "../../StageViewService"; import { StageSkinService } from "../../../StageSkinService"; import { injectable } from "inversify"; -import { TemporaryObjectPool } from "../../../../pixi/pooling/TemporaryObjectPool"; +import { TemporaryObjectPool } from "../../../pooling/TemporaryObjectPool"; import { SliderTextureService } from "../../SliderTextureService"; const DEBUG_FOLLOW_CIRCLE_COLOR = 0xff0000; diff --git a/libs/feature-replay-viewer/src/utils/Sliders.ts b/libs/osu/math/src/Sliders.ts similarity index 100% rename from libs/feature-replay-viewer/src/utils/Sliders.ts rename to libs/osu/math/src/Sliders.ts diff --git a/libs/osu/math/src/index.ts b/libs/osu/math/src/index.ts index 28b8ba6c..57f92448 100644 --- a/libs/osu/math/src/index.ts +++ b/libs/osu/math/src/index.ts @@ -3,4 +3,5 @@ export * from "./Difficulty"; export * from "./Easing"; export * from "./time"; export * from "./utils"; +export * from "./Sliders"; export * from "./Vec2"; From 110205fff249e3090fbb6a54d0a617b17c5c98da Mon Sep 17 00:00:00 2001 From: abstrakt Date: Wed, 15 Sep 2021 12:58:32 +0200 Subject: [PATCH 08/13] Background scales properly now --- .../stage/rewind/components/background/BackgroundPreparer.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libs/feature-replay-viewer/src/app/stage/rewind/components/background/BackgroundPreparer.ts b/libs/feature-replay-viewer/src/app/stage/rewind/components/background/BackgroundPreparer.ts index f37e6525..7caffbb3 100644 --- a/libs/feature-replay-viewer/src/app/stage/rewind/components/background/BackgroundPreparer.ts +++ b/libs/feature-replay-viewer/src/app/stage/rewind/components/background/BackgroundPreparer.ts @@ -22,9 +22,8 @@ export class BackgroundPreparer { } prepare() { - // this.background.texture = this.textureManager.getTexture("BACKGROUND"); - this.background.width = STAGE_WIDTH; - this.background.height = STAGE_HEIGHT; + const scaling = STAGE_WIDTH / this.background.texture.width; + this.background.scale.set(scaling, scaling); this.background.alpha = this.theaterViewService.getView().backgroundDim; return this.background; From 2f78a14d83a729ca4c7562c40feba65a5e2eadfe Mon Sep 17 00:00:00 2001 From: abstrakt Date: Wed, 15 Sep 2021 17:45:28 +0200 Subject: [PATCH 09/13] Using `encodeUriComponent` in order to get skin names with special characters. --- libs/api/common/src/skins/SkinController.ts | 5 +- libs/api/common/src/skins/SkinNameResolver.ts | 8 +-- libs/api/common/src/skins/SkinService.ts | 61 ++++++++++++++++--- .../background/BackgroundPreparer.ts | 2 +- .../src/app/theater/RewindStageCreator.ts | 7 ++- .../src/app/theater/SkinId.ts | 9 +++ .../src/app/theater/SkinService.ts | 20 +++--- .../skin-reader/src/SkinTextureResolver.ts | 37 ++++------- 8 files changed, 98 insertions(+), 51 deletions(-) create mode 100644 libs/feature-replay-viewer/src/app/theater/SkinId.ts diff --git a/libs/api/common/src/skins/SkinController.ts b/libs/api/common/src/skins/SkinController.ts index 0e6fb500..60fdbc18 100644 --- a/libs/api/common/src/skins/SkinController.ts +++ b/libs/api/common/src/skins/SkinController.ts @@ -14,9 +14,10 @@ export class SkinController { const { hd, animated, name } = query; const hdIfExists = hd === 1; const animatedIfExists = animated === 1; - this.logger.log(`Skin requested ${name} with hd=${hdIfExists} animated=${animatedIfExists}`); + const decodedName = decodeURIComponent(name); + this.logger.log(`Skin requested ${decodedName} with hd=${hdIfExists} animated=${animatedIfExists}`); // TODO: Inject these parameters ... - const info = await this.skinService.getSkinInfo(name); + const info = await this.skinService.getSkinInfo(decodedName); res.json(info); } } diff --git a/libs/api/common/src/skins/SkinNameResolver.ts b/libs/api/common/src/skins/SkinNameResolver.ts index 053113bf..e71dc545 100644 --- a/libs/api/common/src/skins/SkinNameResolver.ts +++ b/libs/api/common/src/skins/SkinNameResolver.ts @@ -14,12 +14,12 @@ export const SKIN_NAME_RESOLVER_CONFIG = "SkinsFolderConfig"; export class SkinNameResolver { constructor(@Inject(SKIN_NAME_RESOLVER_CONFIG) private readonly skinNameResolverConfig: SkinNameResolverConfig) {} - resolveNameToPath(name: string): string | null { - const [prefix, ...path] = name.split("/"); - const folderPath = this.skinNameResolverConfig.find((c) => c.prefix === prefix); + resolveNameToPath(name: string) { + const [source, folder] = name.split("/"); + const folderPath = this.skinNameResolverConfig.find((c) => c.prefix === source); if (folderPath === undefined) { return null; } - return join(folderPath.path, ...path); + return { source, name: folder, path: join(folderPath.path, folder) }; } } diff --git a/libs/api/common/src/skins/SkinService.ts b/libs/api/common/src/skins/SkinService.ts index af05873a..1640140d 100644 --- a/libs/api/common/src/skins/SkinService.ts +++ b/libs/api/common/src/skins/SkinService.ts @@ -1,6 +1,7 @@ import { Injectable, Logger } from "@nestjs/common"; -import { SkinFolderReader } from "@rewind/osu-local/skin-reader"; +import { GetTextureFileOption, OsuSkinTextureResolver, SkinFolderReader } from "@rewind/osu-local/skin-reader"; import { SkinNameResolver } from "./SkinNameResolver"; +import { DEFAULT_SKIN_TEXTURE_CONFIG, OsuSkinTextures } from "@rewind/osu/skin"; @Injectable() export class SkinService { @@ -8,22 +9,66 @@ export class SkinService { constructor(private readonly skinNameResolver: SkinNameResolver) {} + /** + * In the future we also want to get the skin info with the beatmap as the parameters in order to retrieve + * beatmap related skin files as well. + */ + + async resolve( + osuSkinTexture: OsuSkinTextures, + options: GetTextureFileOption, + list: { prefix: string; resolver: OsuSkinTextureResolver }[], + ) { + for (const { prefix, resolver } of list) { + const filePaths = await resolver.resolve(osuSkinTexture, options); + if (filePaths.length === 0) { + continue; + } + return filePaths.map((path) => `${prefix}/${path}`); + } + this.logger.warn(`No skin has the skin texture ${osuSkinTexture}`); + return []; + } + /** * @param skinName will be resolved through the given skin name resolver. */ async getSkinInfo(skinName: string) { - const path = this.skinNameResolver.resolveNameToPath(skinName); - if (path === null) { - this.logger.error(`Skin ${skinName} could not be resolved to a path.`); - throw new Error("Skin not found"); + this.logger.log(`Getting skin info for name=${skinName}`); + + const resolved = this.skinNameResolver.resolveNameToPath(skinName); + if (resolved === null) { + // Maybe error will be logged through middleware? + throw new Error(`Skin ${skinName} could not be found in the folders`); } + const { name, path, source } = resolved; + const skinResolver = await SkinFolderReader.getSkinResolver(path); + // TODO: Include default osu! skin + // const defaultSkinResolver = await SkinFolderReader.getSkinResolver(""); const { config } = skinResolver; - // Load from local config ? - const { hdIfExists, animatedIfExists } = { hdIfExists: true, animatedIfExists: true }; + // TODO: Give through params + const option = { hdIfExists: true, animatedIfExists: true }; - const files = await skinResolver.resolveAllTextureFiles({ hdIfExists, animatedIfExists }); + // const files = await skinResolver.resolveAllTextureFiles({ hdIfExists, animatedIfExists }); + const skinTextureKeys = Object.keys(DEFAULT_SKIN_TEXTURE_CONFIG); + const files = await Promise.all( + skinTextureKeys.map(async (key) => ({ + key, + paths: await this.resolve(key as OsuSkinTextures, option, [ + // In the future beatmap stuff can be listed here as well + { + prefix: ["static", "skins", source, name].map(encodeURIComponent).join("/"), + resolver: skinResolver, + }, + // { + // prefix: `/static/skins/${encodeURIComponent(skinName)}`, + // resolver: defaultSkinResolver, + // }, + ]), + })), + ); return { config, files }; } diff --git a/libs/feature-replay-viewer/src/app/stage/rewind/components/background/BackgroundPreparer.ts b/libs/feature-replay-viewer/src/app/stage/rewind/components/background/BackgroundPreparer.ts index 7caffbb3..3fa87123 100644 --- a/libs/feature-replay-viewer/src/app/stage/rewind/components/background/BackgroundPreparer.ts +++ b/libs/feature-replay-viewer/src/app/stage/rewind/components/background/BackgroundPreparer.ts @@ -1,7 +1,7 @@ import { Sprite, Texture } from "pixi.js"; import { inject, injectable } from "inversify"; import { StageViewService } from "../../StageViewService"; -import { STAGE_HEIGHT, STAGE_WIDTH } from "../stage/GameStagePreparer"; +import { STAGE_WIDTH } from "../stage/GameStagePreparer"; import type { RewindTextureMap } from "../../../STAGE_TYPES"; import { STAGE_TYPES } from "../../../STAGE_TYPES"; diff --git a/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts b/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts index d76ec298..d3b671d2 100644 --- a/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts +++ b/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts @@ -8,8 +8,9 @@ import { AudioService } from "./AudioService"; import { TextureManager } from "./TextureManager"; import { defaultViewSettings } from "../stage/rewind/ViewSettings"; import { determineDefaultPlaybackSpeed } from "../../utils"; +import { defaultSkinId } from "./SkinId"; -const defaultSkinName = "rewind/RewindDefaultSkin"; +// There will also be a default osu! std skin @injectable() export class RewindStageCreator { @@ -25,7 +26,9 @@ export class RewindStageCreator { const [blueprint, replay, skin] = await Promise.all([ this.blueprintService.retrieveBlueprint(blueprintId), this.replayService.retrieveReplay(replayId), - this.skinService.loadSkin(defaultSkinName), + + // TODO: Loading the beatmap specific skin + this.skinService.loadSkin(defaultSkinId), ]); await this.blueprintService.retrieveBlueprintResources(blueprintId); diff --git a/libs/feature-replay-viewer/src/app/theater/SkinId.ts b/libs/feature-replay-viewer/src/app/theater/SkinId.ts new file mode 100644 index 00000000..e2e840ea --- /dev/null +++ b/libs/feature-replay-viewer/src/app/theater/SkinId.ts @@ -0,0 +1,9 @@ +type SkinSource = "rewind" | "osu"; + +export interface SkinId { + source: SkinSource; + name: string; +} + +export const defaultSkinId: SkinId = { source: "rewind", name: "RewindDefaultSkin" }; +// export const defaultSkinId: SkinId = { source: "osu", name: "- 《CK》 WhiteCat 2.1 _ old -lite" }; diff --git a/libs/feature-replay-viewer/src/app/theater/SkinService.ts b/libs/feature-replay-viewer/src/app/theater/SkinService.ts index c6ca546e..ebb7bac6 100644 --- a/libs/feature-replay-viewer/src/app/theater/SkinService.ts +++ b/libs/feature-replay-viewer/src/app/theater/SkinService.ts @@ -5,6 +5,7 @@ import { OsuSkinTextures, SkinConfig } from "@rewind/osu/skin"; import { inject, injectable } from "inversify"; import { TYPES } from "./types"; import { Skin, SkinTexturesByKey } from "../stage/rewind/Skin"; +import { SkinId } from "./SkinId"; export type SkinTextureLocation = { key: OsuSkinTextures; paths: string[] }; @@ -34,24 +35,27 @@ export class SkinService { skinElementCounter = 0; // Maybe generalize it to skinSource or something + // TODO: Maybe just load into TextureManager constructor(@inject(TYPES.API_URL) private readonly apiUrl: string) { this.skins = {}; } // force such like reloading - async loadSkin(name: string, forceReload?: boolean): Promise { - if (this.skins[name] && !forceReload) { - console.info(`Skin ${name} is already loaded, using the one in cache`); - return this.skins[name]; + async loadSkin(skinId: SkinId, forceReload?: boolean): Promise { + const id = `${skinId.source}/${encodeURIComponent(skinId.name)}`; + if (this.skins[id] && !forceReload) { + console.info(`Skin ${id} is already loaded, using the one in cache`); + return this.skins[id]; } const loader = new Loader(); const skinInfoUrl = urljoin(this.apiUrl, "api", "skins"); - const skinStaticUrl = urljoin(this.apiUrl, "static", "skins", name); + // TODO: This needs also encodeUriComponent or similar for skin names such as : '- #(SK) Mathi 1.0 - NM' + // But we can't just use " // We could also put some GET parameters const res = await axios - .get(skinInfoUrl, { params: { animatedIfExists: 1, hdIfExists: 1, name: name } }) + .get(skinInfoUrl, { params: { animatedIfExists: 1, hdIfExists: 1, name: id } }) .then((value) => value.data); // Yeah ... @@ -69,7 +73,7 @@ export class SkinService { // `Loader` will die if the same `name` gets used twice therefore the unique skinElementCounter // Maybe even use a timestamp const name = `${this.skinElementCounter++}/${skinName}/${stl.key}-${index}`; - const url = urljoin(skinStaticUrl, path); + const url = urljoin(this.apiUrl, path); loader.add(name, url); queueFiles.push({ key: stl.key, name }); }); @@ -86,6 +90,6 @@ export class SkinService { textures[file.key]?.push(loader.resources[file.name].texture as Texture); }); - return (this.skins[name] = new Skin(config, textures)); + return (this.skins[id] = new Skin(config, textures)); } } diff --git a/libs/osu-local/skin-reader/src/SkinTextureResolver.ts b/libs/osu-local/skin-reader/src/SkinTextureResolver.ts index 707cb720..a9ec2ed5 100644 --- a/libs/osu-local/skin-reader/src/SkinTextureResolver.ts +++ b/libs/osu-local/skin-reader/src/SkinTextureResolver.ts @@ -42,34 +42,33 @@ export interface OsuSkinTextureResolver { const join = Path.posix.join; export class OsuLegacySkinTextureResolver implements OsuSkinTextureResolver { - constructor( - readonly folderPath: string, - readonly config: SkinConfig, - readonly fallbackSkin?: OsuSkinTextureResolver, - ) {} + constructor(readonly folderPath: string, readonly config: SkinConfig) {} // Special case for font textures since their `prefix` can be changed. // Best example would be WhiteCat 1.0 Skin where for example the combo prefix is `Assets\combo` -> even different // folder getFontPrefix(skinTexture: OsuSkinTextures): string | undefined { + const { hitCirclePrefix, comboPrefix, scorePrefix } = this.config.fonts; + + // join will also convert / to \\ if it's in Windows. + // This will be then Assets/combo/default0 for example + const combine = (prefix: string, id: number) => `${prefix}-${id}`; { const hitCircleId = hitCircleDigitFonts.indexOf(skinTexture as any); if (hitCircleId !== -1) { - // join will also convert / to \\ if it's in Windows. - // This will be then Assets/combo/default0 for example - return join(`${this.config.fonts.hitCirclePrefix}-${hitCircleId}`); + return combine(hitCirclePrefix, hitCircleId); } } { const comboId = comboDigitFonts.indexOf(skinTexture as any); if (comboId !== -1) { - return join(`${this.config.fonts.comboPrefix}-${comboId}`); + return combine(comboPrefix, comboId); } } { const scoreId = defaultDigitFonts.indexOf(skinTexture as any); if (scoreId !== -1) { - return join(`${this.config.fonts.scorePrefix}-${scoreId}`); + return combine(scorePrefix, scoreId); } } return undefined; @@ -191,21 +190,7 @@ export class OsuLegacySkinTextureResolver implements OsuSkinTextureResolver { } } - // If here we find nothing, we go ask for fallback skin - if (!this.fallbackSkin) { - return []; - } else { - return this.fallbackSkin.resolve(skinTexture, option); - } - } - - async resolveAllTextureFiles(option: GetTextureFileOption = {}): Promise { - const skinTextureKeys = Object.keys(DEFAULT_SKIN_TEXTURE_CONFIG); - return Promise.all( - skinTextureKeys.map(async (key) => ({ - key, - paths: await this.resolve(key as OsuSkinTextures, option), - })), - ); + // If here we find nothing, we don't ask for fallbackSkin + return []; } } From b5d8b007d3c103e22dcfe73451e47526ca9c6f6d Mon Sep 17 00:00:00 2001 From: abstrakt Date: Wed, 15 Sep 2021 18:16:21 +0200 Subject: [PATCH 10/13] OsuDefaultSkin will be downloaded as well in the build --- package.json | 2 +- resources/Skins/OsuDefaultSkin/README.md | 3 ++ resources/Skins/RewindDefaultSkin/README.md | 4 +- tools/downloadDefaultSkin.js | 48 +++++++++++++-------- 4 files changed, 36 insertions(+), 21 deletions(-) create mode 100644 resources/Skins/OsuDefaultSkin/README.md diff --git a/package.json b/package.json index 1bdfec42..27e2e4d7 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "build-storybook": "build-storybook", "postinstall": "exitzero electron-builder install-app-deps", "electron:build": "electron-builder", - "downloadDefaultSkin": "node tools/downloadDefaultSkin.js", + "downloadDefaultSkins": "node tools/downloadDefaultSkin.js", "desktop:build:dev": "nx run-many --target=build --projects=desktop-frontend,desktop-backend,desktop-frontend-preload,desktop-backend-preload,rewind-electron --parallel", "desktop:build:prod": "nx run-many --target=build --projects=desktop-frontend,desktop-backend,desktop-frontend-preload,desktop-backend-preload,rewind-electron --prod --force", "desktop:build-package:prod": "yarn run desktop:build:prod && yarn run electron:build", diff --git a/resources/Skins/OsuDefaultSkin/README.md b/resources/Skins/OsuDefaultSkin/README.md new file mode 100644 index 00000000..1b869440 --- /dev/null +++ b/resources/Skins/OsuDefaultSkin/README.md @@ -0,0 +1,3 @@ +This is the osu!legacy skin in https://github.com/ppy/osu-resources. + +This skin is used in a non-commercial manner. Please contact me if you are the owner of the skin, and it should be removed from Rewind. diff --git a/resources/Skins/RewindDefaultSkin/README.md b/resources/Skins/RewindDefaultSkin/README.md index 79094a9a..015ee711 100644 --- a/resources/Skins/RewindDefaultSkin/README.md +++ b/resources/Skins/RewindDefaultSkin/README.md @@ -1,5 +1,5 @@ -This is the -YUGEN- skin. +This is the -YUGEN- skin: https://osuskins.net/skin/wEaMJGb Not stored in the .git repository, instead just download and unzip it here. -https://osuskins.net/skin/wEaMJGb +This skin is used in a non-commercial manner. Please contact me if you are the owner of the skin, and it should be removed from Rewind. diff --git a/tools/downloadDefaultSkin.js b/tools/downloadDefaultSkin.js index 3d70ae3e..dc58d462 100644 --- a/tools/downloadDefaultSkin.js +++ b/tools/downloadDefaultSkin.js @@ -2,22 +2,34 @@ const request = require("superagent"); const fs = require("fs"); const AdmZip = require("adm-zip"); -const source = "https://drive.google.com/uc?id=1ftm6PDXGoe1Q3dlyZgejC4nnWKI21ZXd&export=download"; -const zipFile = "RewindDefaultSkin.zip"; +const sources = [ + { + url: "https://drive.google.com/uc?id=1tNHWSBlfNZp2h1C_LRyjddRd9AZhJj6p&export=download", + name: "OsuDefaultSkin", + }, + { + url: "https://drive.google.com/uc?id=1ftm6PDXGoe1Q3dlyZgejC4nnWKI21ZXd&export=download", + name: "RewindDefaultSkin", + }, +]; -request - .get(source) - .on("error", (error) => { - console.log(error); - process.exit(1); - }) - .pipe(fs.createWriteStream(zipFile)) - .on("finish", () => { - console.log("Finished downloading .zip file"); - const zip = new AdmZip(zipFile); - console.log("Starting to unzip the skin"); - zip.extractAllTo("resources/Skins", false); - console.log("Unzipped the skin"); - fs.rmSync(zipFile); - console.log("Cleanup done"); - }); +for (const source of sources) { + const { url, name } = source; + const zipFileName = `${name}.zip`; + request + .get(url) + .on("error", (error) => { + console.log(`Error downloading ${name}: ` + error); + process.exit(1); + }) + .pipe(fs.createWriteStream(zipFileName)) + .on("finish", () => { + console.log("Finished downloading .zip file"); + const zip = new AdmZip(zipFileName); + console.log("Starting to unzip the skin"); + zip.extractAllTo("resources/Skins", false); + console.log("Unzipped the skin"); + fs.rmSync(zipFileName); + console.log("Cleanup done"); + }); +} From 5d19d283161f3277021ffb34432a067277160b41 Mon Sep 17 00:00:00 2001 From: abstrakt Date: Wed, 15 Sep 2021 19:22:49 +0200 Subject: [PATCH 11/13] Using a default `skin.ini` file in case there is none and resolving comma,percent,x textures correctly with prefix --- libs/api/common/src/skins/SkinService.ts | 9 +++++++++ .../src/app/theater/SkinId.ts | 4 ++++ libs/osu-local/skin-reader/src/SkinFolderReader.ts | 14 ++++++++++---- .../skin-reader/src/SkinTextureResolver.ts | 12 ++++++++++++ libs/osu/skin/src/lib/OsuSkinTextureConfig.ts | 1 - 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/libs/api/common/src/skins/SkinService.ts b/libs/api/common/src/skins/SkinService.ts index 1640140d..08b21bf6 100644 --- a/libs/api/common/src/skins/SkinService.ts +++ b/libs/api/common/src/skins/SkinService.ts @@ -3,6 +3,8 @@ import { GetTextureFileOption, OsuSkinTextureResolver, SkinFolderReader } from " import { SkinNameResolver } from "./SkinNameResolver"; import { DEFAULT_SKIN_TEXTURE_CONFIG, OsuSkinTextures } from "@rewind/osu/skin"; +const OSU_DEFAULT_SKIN_ID = "rewind/OsuDefaultSkin"; + @Injectable() export class SkinService { private logger = new Logger(SkinService.name); @@ -43,6 +45,9 @@ export class SkinService { } const { name, path, source } = resolved; + const osuDefaultSkinResolver = await SkinFolderReader.getSkinResolver( + this.skinNameResolver.resolveNameToPath(OSU_DEFAULT_SKIN_ID)?.path, + ); const skinResolver = await SkinFolderReader.getSkinResolver(path); // TODO: Include default osu! skin // const defaultSkinResolver = await SkinFolderReader.getSkinResolver(""); @@ -62,6 +67,10 @@ export class SkinService { prefix: ["static", "skins", source, name].map(encodeURIComponent).join("/"), resolver: skinResolver, }, + { + prefix: ["static", "skins", "rewind", "OsuDefaultSkin"].map(encodeURIComponent).join("/"), + resolver: osuDefaultSkinResolver, + }, // { // prefix: `/static/skins/${encodeURIComponent(skinName)}`, // resolver: defaultSkinResolver, diff --git a/libs/feature-replay-viewer/src/app/theater/SkinId.ts b/libs/feature-replay-viewer/src/app/theater/SkinId.ts index e2e840ea..bb7b45ea 100644 --- a/libs/feature-replay-viewer/src/app/theater/SkinId.ts +++ b/libs/feature-replay-viewer/src/app/theater/SkinId.ts @@ -7,3 +7,7 @@ export interface SkinId { export const defaultSkinId: SkinId = { source: "rewind", name: "RewindDefaultSkin" }; // export const defaultSkinId: SkinId = { source: "osu", name: "- 《CK》 WhiteCat 2.1 _ old -lite" }; +// export const defaultSkinId: SkinId = { source: "osu", name: "idke+1.2" }; +// export const defaultSkinId: SkinId = { source: "osu", name: "Millhiore Lite" }; +// export const defaultSkinId: SkinId = { source: "osu", name: "Toy 2018-09-07" }; +// export const defaultSkinId: SkinId = { source: "osu", name: "- # BTMC ⌞Freedom Dive ↓⌝" }; diff --git a/libs/osu-local/skin-reader/src/SkinFolderReader.ts b/libs/osu-local/skin-reader/src/SkinFolderReader.ts index 3d9cf688..704cd6b0 100644 --- a/libs/osu-local/skin-reader/src/SkinFolderReader.ts +++ b/libs/osu-local/skin-reader/src/SkinFolderReader.ts @@ -1,6 +1,6 @@ import { posix } from "path"; import { promises as fs } from "fs"; -import { SkinConfigParser } from "@rewind/osu/skin"; +import { generateDefaultSkinConfig, SkinConfigParser } from "@rewind/osu/skin"; import { OsuLegacySkinTextureResolver } from "./SkinTextureResolver"; const join = posix.join; @@ -54,12 +54,18 @@ export class SkinFolderReader { /** * Reads the config file in the given skin folder and prepares a skin reader based on the given config. + * In case no config files exists, a default one will be generated according to https://osu.ppy.sh/wiki/el/Skinning/skin.ini * @param skinFolderPath path to the folder */ static async getSkinResolver(skinFolderPath: string): Promise { - const data = await fs.readFile(join(skinFolderPath, SKIN_CONFIG_FILENAME), { encoding: "utf-8" }); - const parser = new SkinConfigParser(data); - const config = parser.parse(); + let config; + try { + const data = await fs.readFile(join(skinFolderPath, SKIN_CONFIG_FILENAME), { encoding: "utf-8" }); + const parser = new SkinConfigParser(data); + config = parser.parse(); + } catch (err) { + config = generateDefaultSkinConfig(false); + } return new OsuLegacySkinTextureResolver(skinFolderPath, config); } } diff --git a/libs/osu-local/skin-reader/src/SkinTextureResolver.ts b/libs/osu-local/skin-reader/src/SkinTextureResolver.ts index a9ec2ed5..4546f2f4 100644 --- a/libs/osu-local/skin-reader/src/SkinTextureResolver.ts +++ b/libs/osu-local/skin-reader/src/SkinTextureResolver.ts @@ -71,6 +71,17 @@ export class OsuLegacySkinTextureResolver implements OsuSkinTextureResolver { return combine(scorePrefix, scoreId); } } + + // Special cases + const texConfig = DEFAULT_SKIN_TEXTURE_CONFIG[skinTexture]; + switch (skinTexture) { + case "SCORE_PERCENT": + case "SCORE_DOT": + return texConfig.filePrefix.replace("score", scorePrefix); + case "SCORE_X": + return texConfig.filePrefix.replace("score", comboPrefix); + } + return undefined; } @@ -84,6 +95,7 @@ export class OsuLegacySkinTextureResolver implements OsuSkinTextureResolver { } // Maybe there is something with prefix in config in between (for numbers for example) // FilePrefix could be overridden by skin config + // TODO: ??? join ??? return join(texConfig.filePrefix); } diff --git a/libs/osu/skin/src/lib/OsuSkinTextureConfig.ts b/libs/osu/skin/src/lib/OsuSkinTextureConfig.ts index 81fff9a9..93025c57 100644 --- a/libs/osu/skin/src/lib/OsuSkinTextureConfig.ts +++ b/libs/osu/skin/src/lib/OsuSkinTextureConfig.ts @@ -162,7 +162,6 @@ export const DEFAULT_SKIN_TEXTURE_CONFIG: Record Date: Wed, 15 Sep 2021 21:03:24 +0200 Subject: [PATCH 12/13] Added license --- LICENSE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..69ae3d9c --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 abstrakt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 9cfadb1d500a0d4b3d823527e1f557312222bfd0 Mon Sep 17 00:00:00 2001 From: abstrakt Date: Thu, 16 Sep 2021 08:01:40 +0200 Subject: [PATCH 13/13] Move playback speed determiner from mods to osu/core (also fixed NC bug) --- .../src/app/theater/RewindStageCreator.ts | 3 +-- libs/feature-replay-viewer/src/utils/index.ts | 9 --------- libs/osu/core/src/index.ts | 2 ++ libs/osu/core/src/utils/index.ts | 9 +++++++++ libs/osu/core/test/utils/playbackSpeed.spec.ts | 9 +++++++++ libs/osu/math/src/Sliders.ts | 2 +- 6 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 libs/osu/core/test/utils/playbackSpeed.spec.ts diff --git a/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts b/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts index d3b671d2..3477b162 100644 --- a/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts +++ b/libs/feature-replay-viewer/src/app/theater/RewindStageCreator.ts @@ -2,12 +2,11 @@ import { injectable } from "inversify"; import { BlueprintService } from "./BlueprintService"; import { ReplayService } from "./ReplayService"; import { createRewindStage } from "../stage/createRewindStage"; -import { buildBeatmap } from "@rewind/osu/core"; +import { buildBeatmap, determineDefaultPlaybackSpeed } from "@rewind/osu/core"; import { SkinService } from "./SkinService"; import { AudioService } from "./AudioService"; import { TextureManager } from "./TextureManager"; import { defaultViewSettings } from "../stage/rewind/ViewSettings"; -import { determineDefaultPlaybackSpeed } from "../../utils"; import { defaultSkinId } from "./SkinId"; // There will also be a default osu! std skin diff --git a/libs/feature-replay-viewer/src/utils/index.ts b/libs/feature-replay-viewer/src/utils/index.ts index 42e12f2c..e69de29b 100644 --- a/libs/feature-replay-viewer/src/utils/index.ts +++ b/libs/feature-replay-viewer/src/utils/index.ts @@ -1,9 +0,0 @@ -import { OsuClassicMod } from "@rewind/osu/core"; - -export function determineDefaultPlaybackSpeed(mods: OsuClassicMod[]) { - for (let i = 0; i < mods.length; i++) { - if (mods[i] === "DOUBLE_TIME" || mods[i] === "HALF_TIME") return 1.5; - if (mods[i] === "HALF_TIME") return 0.75; - } - return 1.0; -} diff --git a/libs/osu/core/src/index.ts b/libs/osu/core/src/index.ts index 689eb292..c37d74d1 100644 --- a/libs/osu/core/src/index.ts +++ b/libs/osu/core/src/index.ts @@ -49,3 +49,5 @@ export * from "./replays/Replay"; export { parseReplayFramesFromRaw } from "./replays/ReplayParser"; export * from "./playfield"; + +export * from "./utils/index"; diff --git a/libs/osu/core/src/utils/index.ts b/libs/osu/core/src/utils/index.ts index 19832c8c..cf334520 100644 --- a/libs/osu/core/src/utils/index.ts +++ b/libs/osu/core/src/utils/index.ts @@ -1,5 +1,6 @@ import { Slider } from "../hitobjects/Slider"; import { AllHitObjects, OsuHitObject } from "../hitobjects/Types"; +import { OsuClassicMod } from "../mods/Mods"; export function normalizeHitObjects(hitObjects: OsuHitObject[]): Record { const hitObjectById: Record = {}; @@ -14,3 +15,11 @@ export function normalizeHitObjects(hitObjects: OsuHitObject[]): Record { + expect(determineDefaultPlaybackSpeed(["NIGHT_CORE"])).toEqual(1.5); + expect(determineDefaultPlaybackSpeed(["DOUBLE_TIME"])).toEqual(1.5); + expect(determineDefaultPlaybackSpeed(["HALF_TIME"])).toEqual(0.75); + expect(determineDefaultPlaybackSpeed(["HIDDEN"])).toEqual(1.0); + expect(determineDefaultPlaybackSpeed([])).toEqual(1.0); +}); diff --git a/libs/osu/math/src/Sliders.ts b/libs/osu/math/src/Sliders.ts index f8495706..9aab791a 100644 --- a/libs/osu/math/src/Sliders.ts +++ b/libs/osu/math/src/Sliders.ts @@ -1,4 +1,4 @@ -import { Position, Vec2 } from "@rewind/osu/math"; +import { Position, Vec2 } from "./Vec2"; // TODO: Maybe move this to osu/Math