import React from 'react' import { invoke } from '@tauri-apps/api' import { dataDir } from '@tauri-apps/api/path' import DirInput from '../common/DirInput' import Menu from './Menu' import Tr, { getLanguages, translate } from '../../../utils/language' import { setConfigOption, getConfig, getConfigOption, Configuration } from '../../../utils/configuration' import Checkbox from '../common/Checkbox' import Divider from './Divider' import { getThemeList } from '../../../utils/themes' import * as server from '../../../utils/server' import './Options.css' import BigButton from '../common/BigButton' import DownloadHandler from '../../../utils/download' import * as meta from '../../../utils/metadata' import HelpButton from '../common/HelpButton' import TextInput from '../common/TextInput' interface IProps { closeFn: () => void downloadManager: DownloadHandler } interface IState { game_install_path: string grasscutter_path: string java_path: string grasscutter_with_game: boolean language_options: { [key: string]: string }[] current_language: string bg_url_or_path: string themes: string[] theme: string encryption: boolean patch_metadata: boolean use_internal_proxy: boolean wipe_login: boolean horny_mode: boolean swag: boolean platform: string // Swag stuff akebi_path: string migoto_path: string reshade_path: string } export default class Options extends React.Component { constructor(props: IProps) { super(props) this.state = { game_install_path: '', grasscutter_path: '', java_path: '', grasscutter_with_game: false, language_options: [], current_language: 'en', bg_url_or_path: '', themes: ['default'], theme: '', encryption: false, patch_metadata: false, use_internal_proxy: false, wipe_login: false, horny_mode: false, swag: false, platform: '', // Swag stuff akebi_path: '', migoto_path: '', reshade_path: '', } this.setGameExecutable = this.setGameExecutable.bind(this) this.setGrasscutterJar = this.setGrasscutterJar.bind(this) this.setJavaPath = this.setJavaPath.bind(this) this.setAkebi = this.setAkebi.bind(this) this.setMigoto = this.setMigoto.bind(this) this.toggleGrasscutterWithGame = this.toggleGrasscutterWithGame.bind(this) this.setCustomBackground = this.setCustomBackground.bind(this) this.toggleEncryption = this.toggleEncryption.bind(this) this.restoreMetadata = this.restoreMetadata.bind(this) } async componentDidMount() { const config = await getConfig() const languages = await getLanguages() const platform: string = await invoke('get_platform') // Remove jar from path const path = config.grasscutter_path.replace(/\\/g, '/') const folderPath = path.substring(0, path.lastIndexOf('/')) const encEnabled = await server.encryptionEnabled(folderPath + '/config.json') console.log(platform) this.setState({ game_install_path: config.game_install_path || '', grasscutter_path: config.grasscutter_path || '', java_path: config.java_path || '', grasscutter_with_game: config.grasscutter_with_game || false, language_options: languages, current_language: config.language || 'en', bg_url_or_path: config.customBackground || '', themes: (await getThemeList()).map((t) => t.name), theme: config.theme || 'default', encryption: await translate(encEnabled ? 'options.enabled' : 'options.disabled'), patch_metadata: config.patch_metadata || false, use_internal_proxy: config.use_internal_proxy || false, wipe_login: config.wipe_login || false, horny_mode: config.horny_mode || false, swag: config.swag_mode || false, platform, // Swag stuff akebi_path: config.akebi_path || '', migoto_path: config.migoto_path || '', reshade_path: config.reshade_path || '', }) this.forceUpdate() } setGameExecutable(value: string) { setConfigOption('game_install_path', value) // I hope this stops people setting launcher.exe because oml it's annoying if (value.endsWith('launcher.exe')) { const pathArr = value.replace(/\\/g, '/').split('/') pathArr.pop() const path = pathArr.join('/') + '/Genshin Impact Game/' alert( `You have set your game execuatable to "launcher.exe". You should not do this. Your game executable is located in:\n\n${path}` ) } this.setState({ game_install_path: value, }) } setGrasscutterJar(value: string) { setConfigOption('grasscutter_path', value) this.setState({ grasscutter_path: value, }) } setJavaPath(value: string) { setConfigOption('java_path', value) this.setState({ java_path: value, }) } setAkebi(value: string) { setConfigOption('akebi_path', value) this.setState({ akebi_path: value, }) } setMigoto(value: string) { setConfigOption('migoto_path', value) this.setState({ migoto_path: value, }) // Set game exe in Migoto ini invoke('set_migoto_target', { path: this.state.game_install_path, migotoPath: value, }) } setReshade(value: string) { setConfigOption('reshade_path', value) this.setState({ reshade_path: value, }) } async setLanguage(value: string) { await setConfigOption('language', value) window.location.reload() } async setTheme(value: string) { await setConfigOption('theme', value) window.location.reload() } async toggleGrasscutterWithGame() { const changedVal = !(await getConfigOption('grasscutter_with_game')) setConfigOption('grasscutter_with_game', changedVal) this.setState({ grasscutter_with_game: changedVal, }) } async setCustomBackground(value: string) { const isUrl = /^(?:http(s)?:\/\/)/gm.test(value) if (!value) return await setConfigOption('customBackground', '') if (!isUrl) { const filename = value.replace(/\\/g, '/').split('/').pop() const localBgPath = ((await dataDir()) as string).replace(/\\/g, '/') await setConfigOption('customBackground', `${localBgPath}/cultivation/bg/${filename}`) // Copy the file over to the local directory await invoke('copy_file', { path: value.replace(/\\/g, '/'), newPath: `${localBgPath}cultivation/bg/`, }) window.location.reload() } else { await setConfigOption('customBackground', value) window.location.reload() } } async toggleEncryption() { const config = await getConfig() // Check if grasscutter path is set if (!config.grasscutter_path) { alert('Grasscutter not set!') return } // Remove jar from path const path = config.grasscutter_path.replace(/\\/g, '/') const folderPath = path.substring(0, path.lastIndexOf('/')) await server.toggleEncryption(folderPath + '/config.json') this.setState({ encryption: await translate( (await server.encryptionEnabled(folderPath + '/config.json')) ? 'options.enabled' : 'options.disabled' ), }) } async restoreMetadata() { await meta.restoreMetadata(this.props.downloadManager) } async installCert() { await invoke('generate_ca_files', { path: (await dataDir()) + 'cultivation', }) } async toggleOption(opt: keyof Configuration) { const changedVal = !(await getConfigOption(opt)) await setConfigOption(opt, changedVal) // @ts-expect-error shut up bitch this.setState({ [opt]: changedVal, }) } render() { return ( {!this.state.platform || this.state.platform === 'windows' ? ( ) : ( )} {this.state.swag && ( <> )} {this.state.swag ? ( ) : null} ) } }