Files
OctoLauncher-personal/src/main/api/routers/general.ts
T
OctoWoW 5dca94a3fc OctoLauncher 1.3.1
Manifest-based CDN updater and mod manager for the OctoWoW 1.12.1 client:
launcher-owned realmlist, torrent-backed content sync with bundled aria2c,
antivirus and Defender exclusion handling, hardware-aware render distance,
optional client tweaks and mods, and the in-launcher news feed.
2026-08-14 01:45:50 +00:00

89 lines
2.6 KiB
TypeScript

import path from 'node:path';
import { app, dialog, shell } from 'electron';
import Logger from 'electron-log/main';
import { z } from 'zod';
import { mainWindow } from '~main/index';
import Preferences from '~main/modules/preferences';
import {
addDefenderExclusions,
detectAntivirusBlocks
} from '~main/modules/defender';
import { detectHardware, recommendFarClip } from '~main/modules/hardware';
import { createTRPCRouter, publicProcedure } from '../trpc';
export const generalRouter = createTRPCRouter({
appVersion: publicProcedure.query(() => app.getVersion()),
hardware: publicProcedure.query(() => {
const hardware = Preferences.data.hardware ?? null;
return { hardware, recommendedFarClip: recommendFarClip(hardware) };
}),
redetectHardware: publicProcedure.mutation(async () => {
const hardware = await detectHardware();
Preferences.data = { hardware };
return { hardware, recommendedFarClip: recommendFarClip(hardware) };
}),
quit: publicProcedure.mutation(() => app.quit()),
minimize: publicProcedure.mutation(() => mainWindow?.minimize()),
openLink: publicProcedure
.input(z.string().url())
.mutation(({ input }) => shell.openExternal(input)),
openInstallFolder: publicProcedure.mutation(() => {
// Explorer needs native separators; a stored forward-slash path fails to open.
const dir = Preferences.data.clientDir;
if (dir) shell.openPath(path.normalize(dir));
}),
openLogFile: publicProcedure.mutation(() => {
const file = Logger.transports.file.getFile().path;
shell.openPath(path.normalize(file));
}),
addDefenderExclusion: publicProcedure.mutation(() => addDefenderExclusions()),
antivirusBlocks: publicProcedure.query(() => detectAntivirusBlocks()),
filePicker: publicProcedure
.input(
z.object({
title: z.string().optional(),
message: z.string().optional(),
filters: z
.array(
z.object({
name: z.string(),
extensions: z.array(z.string())
})
)
.optional(),
properties: z
.array(
z.enum([
'openDirectory',
'openFile',
'multiSelections',
'showHiddenFiles',
'createDirectory',
'promptToCreate',
'noResolveAliases',
'treatPackageAsDirectory',
'dontAddToRecent'
])
)
.optional()
})
)
.mutation(async ({ input }) => {
if (!mainWindow) return { canceled: true } as const;
const { canceled, filePaths } = await dialog.showOpenDialog(
mainWindow,
input
);
return canceled
? ({ canceled: true } as const)
: ({
canceled: false,
path: filePaths as [string, ...string[]]
} as const);
})
});