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 } 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/rsa' import HelpButton from '../common/HelpButton' import SmallButton from '../common/SmallButton' 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 use_theme_background: boolean encryption: boolean patch_rsa: boolean use_internal_proxy: boolean wipe_login: boolean horny_mode: boolean auto_mongodb: boolean swag: boolean platform: string un_elevated: boolean redirect_more: boolean // 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: '', use_theme_background: false, encryption: false, patch_rsa: false, use_internal_proxy: false, wipe_login: false, horny_mode: false, swag: false, auto_mongodb: false, platform: '', un_elevated: false, redirect_more: false, // 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.removeRSA = this.removeRSA.bind(this) this.addMigotoDelay = this.addMigotoDelay.bind(this) this.toggleUnElevatedGame = this.toggleUnElevatedGame.bind(this) } async componentDidMount() { const config = await getConfig() const languages = await getLanguages() const platform: string = await invoke('get_platform') let encEnabled if (config.grasscutter_path) { // Remove jar from path const path = config.grasscutter_path.replace(/\\/g, '/') const folderPath = path.substring(0, path.lastIndexOf('/')) 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.custom_background || '', themes: (await getThemeList()).map((t) => t.name), theme: config.theme || 'default', use_theme_background: config.use_theme_background || false, encryption: encEnabled || false, patch_rsa: config.patch_rsa || 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, auto_mongodb: config.auto_mongodb || false, platform, un_elevated: config.un_elevated || false, redirect_more: config.redirect_more || false, // 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}` ) } // If setting any other game, automatically set to redirect more if (!value.toLowerCase().includes('genshin' || 'yuanshen')) { if (!this.state.redirect_more) { this.toggleOption('redirect_more') } } this.setState({ game_install_path: value, }) } async setGrasscutterJar(value: string) { setConfigOption('grasscutter_path', value) this.setState({ grasscutter_path: value, }) const config = await getConfig() const path = config.grasscutter_path.replace(/\\/g, '/') const folderPath = path.substring(0, path.lastIndexOf('/')) const encEnabled = await server.encryptionEnabled(folderPath + '/config.json') // Update encryption button when setting new jar this.setState({ encryption: encEnabled, }) window.location.reload() } 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, }) } 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('custom_background', '') if (!isUrl) { const filename = value.replace(/\\/g, '/').split('/').pop() const localBgPath = (await dataDir()).replace(/\\/g, '/') await setConfigOption('custom_background', `${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('custom_background', 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 server.encryptionEnabled(folderPath + '/config.json'), }) // Check if Grasscutter is running, and restart if so to apply changes if (await invoke('is_grasscutter_running')) { alert('Automatically restarting Grasscutter to apply encryption changes!') await invoke('restart_grasscutter') } } async toggleUnElevatedGame() { const changedVal = !(await getConfigOption('un_elevated')) setConfigOption('un_elevated', changedVal) this.setState({ un_elevated: changedVal, }) } async removeRSA() { await meta.unpatchGame() } async addMigotoDelay() { invoke('set_migoto_delay', { migotoPath: this.state.migoto_path, }) } 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.swag && ( <> )} {this.state.swag ? ( ) : null} ) } }