diff --git a/build/installer.nsh b/build/installer.nsh new file mode 100644 index 00000000..89693a5c --- /dev/null +++ b/build/installer.nsh @@ -0,0 +1,6 @@ +!macro customUnInstall + ${ifNot} ${isUpdated} + RMDir /r "$APPDATA\${APP_PACKAGE_NAME}" + RMDir /r "$APPDATA\hydra" + ${endIf} +!macroend diff --git a/electron-builder.yml b/electron-builder.yml index 8d94d3ed..a085b1e9 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -27,6 +27,7 @@ nsis: createDesktopShortcut: always oneClick: false allowToChangeInstallationDirectory: true + include: installer.nsh portable: artifactName: ${name}-${version}-portable.${ext} mac: diff --git a/package.json b/package.json index c9f3885f..36fe8898 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydralauncher", - "version": "2.1.4", + "version": "2.1.5", "description": "Hydra", "main": "./out/main/index.js", "author": "Los Broxas", diff --git a/src/main/constants.ts b/src/main/constants.ts index c8cf182f..92973118 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -11,3 +11,5 @@ export const logsPath = path.join(app.getPath("appData"), "hydra", "logs"); export const seedsPath = app.isPackaged ? path.join(process.resourcesPath, "seeds") : path.join(__dirname, "..", "..", "seeds"); + +export const appVersion = app.getVersion(); diff --git a/src/main/events/index.ts b/src/main/events/index.ts index 54e63a3b..0337c9d8 100644 --- a/src/main/events/index.ts +++ b/src/main/events/index.ts @@ -1,5 +1,5 @@ -import { defaultDownloadsPath } from "@main/constants"; -import { app, ipcMain } from "electron"; +import { appVersion, defaultDownloadsPath } from "@main/constants"; +import { ipcMain } from "electron"; import "./catalogue/get-catalogue"; import "./catalogue/get-game-shop-details"; @@ -63,6 +63,6 @@ import "./profile/sync-friend-requests"; import { isPortableVersion } from "@main/helpers"; ipcMain.handle("ping", () => "pong"); -ipcMain.handle("getVersion", () => app.getVersion()); +ipcMain.handle("getVersion", () => appVersion); ipcMain.handle("isPortableVersion", () => isPortableVersion()); ipcMain.handle("getDefaultDownloadsPath", () => defaultDownloadsPath); diff --git a/src/main/knex-client.ts b/src/main/knex-client.ts index d7206677..b6ec3e3d 100644 --- a/src/main/knex-client.ts +++ b/src/main/knex-client.ts @@ -5,6 +5,7 @@ import { RepackUris } from "./migrations/20240830143906_RepackUris"; import { UpdateUserLanguage } from "./migrations/20240913213944_update_user_language"; import { EnsureRepackUris } from "./migrations/20240915035339_ensure_repack_uris"; import { app } from "electron"; +import { FixMissingColumns } from "./migrations/20240918001920_FixMissingColumns"; export type HydraMigration = Knex.Migration & { name: string }; @@ -15,6 +16,7 @@ class MigrationSource implements Knex.MigrationSource { RepackUris, UpdateUserLanguage, EnsureRepackUris, + FixMissingColumns, ]); } getMigrationName(migration: HydraMigration): string { diff --git a/src/main/migrations/20240918001920_FixMissingColumns.ts b/src/main/migrations/20240918001920_FixMissingColumns.ts new file mode 100644 index 00000000..d23662ed --- /dev/null +++ b/src/main/migrations/20240918001920_FixMissingColumns.ts @@ -0,0 +1,41 @@ +import type { HydraMigration } from "@main/knex-client"; +import type { Knex } from "knex"; + +export const FixMissingColumns: HydraMigration = { + name: "FixMissingColumns", + up: async (knex: Knex) => { + const timestamp = new Date().getTime(); + await knex.schema + .hasColumn("repack", "downloadSourceId") + .then(async (exists) => { + if (!exists) { + await knex.schema.table("repack", (table) => { + table + .integer("downloadSourceId") + .references("download_source.id") + .onDelete("CASCADE"); + }); + } + }); + + await knex.schema.hasColumn("game", "remoteId").then(async (exists) => { + if (!exists) { + await knex.schema.table("game", (table) => { + table + .text("remoteId") + .unique({ indexName: "game_remoteId_unique_" + timestamp }); + }); + } + }); + + await knex.schema.hasColumn("game", "uri").then(async (exists) => { + if (!exists) { + await knex.schema.table("game", (table) => { + table.text("uri"); + }); + } + }); + }, + + down: async (_knex: Knex) => {}, +}; diff --git a/src/main/services/hydra-api.ts b/src/main/services/hydra-api.ts index 90149038..769447a6 100644 --- a/src/main/services/hydra-api.ts +++ b/src/main/services/hydra-api.ts @@ -7,6 +7,7 @@ import { clearGamesRemoteIds } from "./library-sync/clear-games-remote-id"; import { logger } from "./logger"; import { UserNotLoggedInError } from "@shared"; import { omit } from "lodash-es"; +import { appVersion } from "@main/constants"; interface HydraApiOptions { needsAuth: boolean; @@ -80,12 +81,16 @@ export class HydraApi { static async setupApi() { this.instance = axios.create({ baseURL: import.meta.env.MAIN_VITE_API_URL, + headers: { "User-Agent": `Hydra Launcher v${appVersion}` }, }); this.instance.interceptors.request.use( (request) => { logger.log(" ---- REQUEST -----"); - logger.log(request.method, request.url, request.params, request.data); + const data = Array.isArray(request.data) + ? request.data + : omit(request.data, ["refreshToken"]); + logger.log(request.method, request.url, request.params, data); return request; }, (error) => {