mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-02-25 15:01:08 +00:00
Some globalisation stuff
Game executable now selectable in settings. Translations need updating for "Set Game Path".
This commit is contained in:
parent
99687f0550
commit
f35b596eb2
26278
package-lock.json
generated
Normal file
26278
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@
|
|||||||
"files_extracting": "文件解压中:"
|
"files_extracting": "文件解压中:"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"game_exec": "选择游戏可执行文件",
|
"game_executable": "选择游戏可执行文件",
|
||||||
"grasscutter_jar": "选择 Grasscutter JAR 文件",
|
"grasscutter_jar": "选择 Grasscutter JAR 文件",
|
||||||
"java_path": "设置自定义 Java 路径",
|
"java_path": "设置自定义 Java 路径",
|
||||||
"grasscutter_with_game": "随游戏自动启动 Grasscutter",
|
"grasscutter_with_game": "随游戏自动启动 Grasscutter",
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"enabled": "已啟用",
|
"enabled": "已啟用",
|
||||||
"disabled": "未啟用",
|
"disabled": "未啟用",
|
||||||
"game_exec": "選擇遊戲執行檔",
|
"game_executable": "選擇遊戲執行檔",
|
||||||
"grasscutter_jar": "選擇伺服器JAR檔案",
|
"grasscutter_jar": "選擇伺服器JAR檔案",
|
||||||
"toggle_encryption": "設定加密",
|
"toggle_encryption": "設定加密",
|
||||||
"java_path": "設定自定義Java路徑",
|
"java_path": "設定自定義Java路徑",
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"enabled": "Aktiviert",
|
"enabled": "Aktiviert",
|
||||||
"disabled": "Deaktiviert",
|
"disabled": "Deaktiviert",
|
||||||
"game_exec": "Spiel Datei auswählen",
|
"game_executable": "Spiel Datei auswählen",
|
||||||
"grasscutter_jar": "Grasscuter JAR auswählen",
|
"grasscutter_jar": "Grasscuter JAR auswählen",
|
||||||
"toggle_encryption": "Verschlüsselung umschalten",
|
"toggle_encryption": "Verschlüsselung umschalten",
|
||||||
"java_path": "Benutzerdefinierten Java Pfad setzen",
|
"java_path": "Benutzerdefinierten Java Pfad setzen",
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"enabled": "Enabled",
|
"enabled": "Enabled",
|
||||||
"disabled": "Disabled",
|
"disabled": "Disabled",
|
||||||
"game_exec": "Set Game Executable",
|
"game_path": "Set Game Install Path",
|
||||||
|
"game_executable": "Set Game Executable",
|
||||||
"grasscutter_jar": "Set Grasscutter JAR",
|
"grasscutter_jar": "Set Grasscutter JAR",
|
||||||
"toggle_encryption": "Toggle Encryption",
|
"toggle_encryption": "Toggle Encryption",
|
||||||
"java_path": "Set Custom Java Path",
|
"java_path": "Set Custom Java Path",
|
||||||
@ -57,7 +58,6 @@
|
|||||||
"gc_dev_jar": "Download the latest development Grasscutter build, which includes jar file and data files.",
|
"gc_dev_jar": "Download the latest development Grasscutter build, which includes jar file and data files.",
|
||||||
"gc_stable_data": "Download the current stable Grasscutter data files, which does not come with a jar file. This is useful for updating.",
|
"gc_stable_data": "Download the current stable Grasscutter data files, which does not come with a jar file. This is useful for updating.",
|
||||||
"gc_dev_data": "Download the latest development Grasscutter data files, which does not come with a jar file. This is useful for updating.",
|
"gc_dev_data": "Download the latest development Grasscutter data files, which does not come with a jar file. This is useful for updating.",
|
||||||
"resources": "These are also required to run a Grasscutter server. This button will be grey if you have an existing resources folder with contents inside",
|
"resources": "These are also required to run a Grasscutter server. This button will be grey if you have an existing resources folder with contents inside"
|
||||||
"game": "This will download a fresh copy of \"the certain anime game\" and set your game executable to it. This is useful if you don't want to patch your main game."
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,7 +13,7 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"enabled": "active",
|
"enabled": "active",
|
||||||
"disabled": "desactiver",
|
"disabled": "desactiver",
|
||||||
"game_exec": "definir l'executable du jeu",
|
"game_executable": "definir l'executable du jeu",
|
||||||
"grasscutter_jar": "definir le Jar Grasscutter",
|
"grasscutter_jar": "definir le Jar Grasscutter",
|
||||||
"toggle_encryption": "activer l'encryption",
|
"toggle_encryption": "activer l'encryption",
|
||||||
"java_path": "definir un chemin java personnalise",
|
"java_path": "definir un chemin java personnalise",
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
"files_extracting": "MengExtract File: "
|
"files_extracting": "MengExtract File: "
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"game_exec": "Set Game Executable",
|
"game_executable": "Set Game Executable",
|
||||||
"grasscutter_jar": "Path ke Grasscutter JAR",
|
"grasscutter_jar": "Path ke Grasscutter JAR",
|
||||||
"java_path": "Atur kustom Java path",
|
"java_path": "Atur kustom Java path",
|
||||||
"grasscutter_with_game": "Otomatis Menjalankan Grasscutter Dengan Game",
|
"grasscutter_with_game": "Otomatis Menjalankan Grasscutter Dengan Game",
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"enabled": "Iespējots",
|
"enabled": "Iespējots",
|
||||||
"disabled": "Atspējots",
|
"disabled": "Atspējots",
|
||||||
"game_exec": "Iestatīt spēles izpildāmu",
|
"game_executable": "Iestatīt spēles izpildāmu",
|
||||||
"grasscutter_jar": "Iestatiet Grasscutter JAR",
|
"grasscutter_jar": "Iestatiet Grasscutter JAR",
|
||||||
"toggle_encryption": "Pārslēgt Šifrēšanu",
|
"toggle_encryption": "Pārslēgt Šifrēšanu",
|
||||||
"java_path": "Iestatiet pielāgotu Java ceļu",
|
"java_path": "Iestatiet pielāgotu Java ceļu",
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"enabled": "Включено",
|
"enabled": "Включено",
|
||||||
"disabled": "Выключено",
|
"disabled": "Выключено",
|
||||||
"game_exec": "Установить исполняемый файл игры",
|
"game_executable": "Установить исполняемый файл игры",
|
||||||
"grasscutter_jar": "Установить Grasscutter JAR",
|
"grasscutter_jar": "Установить Grasscutter JAR",
|
||||||
"toggle_encryption": "Переключить шифрование",
|
"toggle_encryption": "Переключить шифрование",
|
||||||
"java_path": "Установить пользовательский путь Java",
|
"java_path": "Установить пользовательский путь Java",
|
||||||
|
@ -3,7 +3,7 @@ import Checkbox from './common/Checkbox'
|
|||||||
import BigButton from './common/BigButton'
|
import BigButton from './common/BigButton'
|
||||||
import TextInput from './common/TextInput'
|
import TextInput from './common/TextInput'
|
||||||
import HelpButton from './common/HelpButton'
|
import HelpButton from './common/HelpButton'
|
||||||
import { getConfig, saveConfig, setConfigOption } from '../../utils/configuration'
|
import { Configuration, getConfig, saveConfig, setConfigOption } from '../../utils/configuration'
|
||||||
import { translate } from '../../utils/language'
|
import { translate } from '../../utils/language'
|
||||||
import { invoke } from '@tauri-apps/api/tauri'
|
import { invoke } from '@tauri-apps/api/tauri'
|
||||||
|
|
||||||
@ -72,6 +72,24 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getGameExecutable(config : Configuration) {
|
||||||
|
if(!config.game_install_path || !config.game_executable) {
|
||||||
|
alert('Game executable and/or path not set!')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.game_install_path + '\\' + config.game_executable
|
||||||
|
}
|
||||||
|
|
||||||
|
getGameMetadataLocation(config : Configuration) {
|
||||||
|
if(!config.game_install_path || !config.game_executable) {
|
||||||
|
alert('Game executable and/or path not set!')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.game_install_path + '\\' + config.game_executable.replace('.exe', '_Data') + '\\Managed\\Metadata'
|
||||||
|
}
|
||||||
|
|
||||||
async toggleGrasscutter() {
|
async toggleGrasscutter() {
|
||||||
const config = await getConfig()
|
const config = await getConfig()
|
||||||
|
|
||||||
@ -89,7 +107,7 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
const config = await getConfig()
|
const config = await getConfig()
|
||||||
|
|
||||||
// Copy unpatched metadata to backup location
|
// Copy unpatched metadata to backup location
|
||||||
if(await invoke('copy_file_with_new_name', { path: config.game_install_path + '\\GenshinImpact_Data\\Managed\\Metadata\\global-metadata.dat', newPath: await dataDir() + 'cultivation\\metadata', newName: 'global-metadata-unpatched.dat' })) {
|
if(await invoke('copy_file_with_new_name', { path: this.getGameMetadataLocation(config) + '\\global-metadata.dat', newPath: await dataDir() + 'cultivation\\metadata', newName: 'global-metadata-unpatched.dat' })) {
|
||||||
// Backup successful
|
// Backup successful
|
||||||
|
|
||||||
// Patch backedup metadata
|
// Patch backedup metadata
|
||||||
@ -97,7 +115,7 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
// Patch successful
|
// Patch successful
|
||||||
|
|
||||||
// Replace game metadata with patched metadata
|
// Replace game metadata with patched metadata
|
||||||
if(!(await invoke('copy_file_with_new_name', { path: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat', newPath: config.game_install_path + '\\GenshinImpact_Data\\Managed\\Metadata', newName: 'global-metadata.dat' }))) {
|
if(!(await invoke('copy_file_with_new_name', { path: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat', newPath: this.getGameMetadataLocation(config), newName: 'global-metadata.dat' }))) {
|
||||||
// Replace failed
|
// Replace failed
|
||||||
alert('Failed to replace game metadata!')
|
alert('Failed to replace game metadata!')
|
||||||
return
|
return
|
||||||
@ -114,8 +132,10 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
|
|
||||||
async playGame() {
|
async playGame() {
|
||||||
const config = await getConfig()
|
const config = await getConfig()
|
||||||
|
|
||||||
if (!config.game_install_path) return alert('Game path not set!')
|
if(this.getGameExecutable(config) == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Connect to proxy
|
// Connect to proxy
|
||||||
if (config.toggle_grasscutter) {
|
if (config.toggle_grasscutter) {
|
||||||
@ -124,13 +144,13 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
// Assume metadata has been patched
|
// Assume metadata has been patched
|
||||||
|
|
||||||
// Compare metadata files
|
// Compare metadata files
|
||||||
if (!(await invoke('are_files_identical', { path1: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat', path2: config.game_install_path + '\\GenshinImpact_Data\\Managed\\Metadata\\global-metadata.dat'}))) {
|
if (!(await invoke('are_files_identical', { path1: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat', path2: this.getGameMetadataLocation(config) + '\\global-metadata.dat'}))) {
|
||||||
// Metadata is not patched
|
// Metadata is not patched
|
||||||
|
|
||||||
// Check to see if unpatched backup matches the game's version
|
// Check to see if unpatched backup matches the game's version
|
||||||
if (await invoke('are_files_identical', { path1: await dataDir() + 'cultivation/metadata/global-metadata-unpatched.dat', path2: config.game_install_path + '\\GenshinImpact_Data\\Managed\\Metadata\\global-metadata.dat'})) {
|
if (await invoke('are_files_identical', { path1: await dataDir() + 'cultivation/metadata/global-metadata-unpatched.dat', path2: this.getGameMetadataLocation(config) + '\\global-metadata.dat'})) {
|
||||||
// Game's metadata is not patched, so we need to patch it
|
// Game's metadata is not patched, so we need to patch it
|
||||||
if(!(await invoke('copy_file_with_new_name', { path: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat', newPath: config.game_install_path + '\\GenshinImpact_Data\\Managed\\Metadata', newName: 'global-metadata.dat' }))) {
|
if(!(await invoke('copy_file_with_new_name', { path: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat', newPath: this.getGameMetadataLocation(config), newName: 'global-metadata.dat' }))) {
|
||||||
// Replace failed
|
// Replace failed
|
||||||
alert('Failed to replace game metadata!')
|
alert('Failed to replace game metadata!')
|
||||||
return
|
return
|
||||||
@ -140,7 +160,7 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
alert('Deleting old metadata')
|
alert('Deleting old metadata')
|
||||||
|
|
||||||
// Delete backed up metadata
|
// Delete backed up metadata
|
||||||
if(!(await invoke('delete_file', { path: await dataDir() + 'cultivation/metadata/global-metadata-unpatched.dat' }) && !(await invoke('delete_file', { path: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat' })))) {
|
if(!(await invoke('delete_file', { path: await dataDir() + 'cultivation/metadata/global-metadata-unpatched.dat' })) && !(await invoke('delete_file', { path: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat' }))) {
|
||||||
// Delete failed
|
// Delete failed
|
||||||
alert('Failed to delete backed up metadata!')
|
alert('Failed to delete backed up metadata!')
|
||||||
return
|
return
|
||||||
@ -154,12 +174,12 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
await this.patchMetadata()
|
await this.patchMetadata()
|
||||||
}
|
}
|
||||||
|
|
||||||
let game_exe = config.game_install_path + '\\GenshinImpact.exe'
|
let game_exe = this.getGameExecutable(config) as string
|
||||||
|
|
||||||
if (game_exe.includes('\\')) {
|
if (game_exe.includes('\\')) {
|
||||||
game_exe = game_exe.substring(config.game_install_path.lastIndexOf('\\') + 1)
|
game_exe = game_exe.substring((this.getGameExecutable(config) as string).lastIndexOf('\\') + 1)
|
||||||
} else {
|
} else {
|
||||||
game_exe = game_exe.substring(config.game_install_path.lastIndexOf('/') + 1)
|
game_exe = game_exe.substring((this.getGameExecutable(config) as string).lastIndexOf('/') + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save last connected server and port
|
// Save last connected server and port
|
||||||
@ -197,9 +217,9 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
// Check if metadata is patched
|
// Check if metadata is patched
|
||||||
|
|
||||||
// Compare metadata files
|
// Compare metadata files
|
||||||
if (await invoke('are_files_identical', { path1: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat', path2: config.game_install_path + '\\GenshinImpact_Data\\Managed\\Metadata\\global-metadata.dat'})) {
|
if (await invoke('are_files_identical', { path1: await dataDir() + 'cultivation/metadata/global-metadata-patched.dat', path2: this.getGameMetadataLocation(config) + '\\global-metadata.dat'})) {
|
||||||
// Metadata is patched, so we need to unpatch it
|
// Metadata is patched, so we need to unpatch it
|
||||||
if(!(await invoke('copy_file_with_new_name', { path: await dataDir() + 'cultivation/metadata/global-metadata-unpatched.dat', newPath: config.game_install_path + '\\GenshinImpact_Data\\Managed\\Metadata', newName: 'global-metadata.dat' }))) {
|
if(!(await invoke('copy_file_with_new_name', { path: await dataDir() + 'cultivation/metadata/global-metadata-unpatched.dat', newPath: this.getGameMetadataLocation(config), newName: 'global-metadata.dat' }))) {
|
||||||
// Replace failed
|
// Replace failed
|
||||||
alert('Failed to unpatch game metadata!')
|
alert('Failed to unpatch game metadata!')
|
||||||
return
|
return
|
||||||
@ -210,11 +230,11 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
|||||||
|
|
||||||
// Launch the program
|
// Launch the program
|
||||||
const gameExists = await invoke('dir_exists', {
|
const gameExists = await invoke('dir_exists', {
|
||||||
path: config.game_install_path + '\\GenshinImpact.exe'
|
path: this.getGameExecutable(config)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (gameExists) await invoke('run_program', { path: config.game_install_path + '\\GenshinImpact.exe' })
|
if (gameExists) await invoke('run_program', { path: this.getGameExecutable(config) })
|
||||||
else alert('Game not found! At: ' + config.game_install_path)
|
else alert('Game not found! At: ' + this.getGameExecutable(config))
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchServer() {
|
async launchServer() {
|
||||||
|
@ -14,7 +14,8 @@ interface IProps {
|
|||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
folder?: boolean
|
folder?: boolean
|
||||||
customClearBehaviour?: () => void
|
customClearBehaviour?: () => void,
|
||||||
|
openFolder?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
@ -67,10 +68,12 @@ export default class DirInput extends React.Component<IProps, IState> {
|
|||||||
directory: true
|
directory: true
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
console.log(this.props.openFolder)
|
||||||
path = await open({
|
path = await open({
|
||||||
filters: [
|
filters: [
|
||||||
{ name: 'Files', extensions: this.props.extensions || ['*'] }
|
{ name: 'Files', extensions: this.props.extensions || ['*'] }
|
||||||
]
|
],
|
||||||
|
defaultPath: this.props.openFolder
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,16 +18,17 @@ interface IProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
game_install_path: string
|
game_install_path: string;
|
||||||
grasscutter_path: string
|
game_executable: string;
|
||||||
java_path: string
|
grasscutter_path: string;
|
||||||
grasscutter_with_game: boolean
|
java_path: string;
|
||||||
language_options: { [key: string]: string }[],
|
grasscutter_with_game: boolean;
|
||||||
current_language: string
|
language_options: { [key: string]: string }[];
|
||||||
bg_url_or_path: string
|
current_language: string;
|
||||||
themes: string[]
|
bg_url_or_path: string;
|
||||||
theme: string
|
themes: string[];
|
||||||
encryption: boolean
|
theme: string;
|
||||||
|
encryption: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Options extends React.Component<IProps, IState> {
|
export default class Options extends React.Component<IProps, IState> {
|
||||||
@ -36,6 +37,7 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
game_install_path: '',
|
game_install_path: '',
|
||||||
|
game_executable: '',
|
||||||
grasscutter_path: '',
|
grasscutter_path: '',
|
||||||
java_path: '',
|
java_path: '',
|
||||||
grasscutter_with_game: false,
|
grasscutter_with_game: false,
|
||||||
@ -44,10 +46,11 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
bg_url_or_path: '',
|
bg_url_or_path: '',
|
||||||
themes: ['default'],
|
themes: ['default'],
|
||||||
theme: '',
|
theme: '',
|
||||||
encryption: false
|
encryption: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setGameExec = this.setGameExec.bind(this)
|
this.setGamePath = this.setGamePath.bind(this)
|
||||||
|
this.setGameExecutable = this.setGameExecutable.bind(this)
|
||||||
this.setGrasscutterJar = this.setGrasscutterJar.bind(this)
|
this.setGrasscutterJar = this.setGrasscutterJar.bind(this)
|
||||||
this.setJavaPath = this.setJavaPath.bind(this)
|
this.setJavaPath = this.setJavaPath.bind(this)
|
||||||
this.toggleGrasscutterWithGame = this.toggleGrasscutterWithGame.bind(this)
|
this.toggleGrasscutterWithGame = this.toggleGrasscutterWithGame.bind(this)
|
||||||
@ -58,7 +61,7 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const config = await getConfig()
|
const config = await getConfig()
|
||||||
const languages = await getLanguages()
|
const languages = await getLanguages()
|
||||||
|
|
||||||
// Remove jar from path
|
// Remove jar from path
|
||||||
const path = config.grasscutter_path.replace(/\\/g, '/')
|
const path = config.grasscutter_path.replace(/\\/g, '/')
|
||||||
const folderPath = path.substring(0, path.lastIndexOf('/'))
|
const folderPath = path.substring(0, path.lastIndexOf('/'))
|
||||||
@ -66,33 +69,52 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
game_install_path: config.game_install_path || '',
|
game_install_path: config.game_install_path || '',
|
||||||
|
game_executable: config.game_executable || '',
|
||||||
grasscutter_path: config.grasscutter_path || '',
|
grasscutter_path: config.grasscutter_path || '',
|
||||||
java_path: config.java_path || '',
|
java_path: config.java_path || '',
|
||||||
grasscutter_with_game: config.grasscutter_with_game || false,
|
grasscutter_with_game: config.grasscutter_with_game || false,
|
||||||
language_options: languages,
|
language_options: languages,
|
||||||
current_language: config.language || 'en',
|
current_language: config.language || 'en',
|
||||||
bg_url_or_path: config.customBackground || '',
|
bg_url_or_path: config.customBackground || '',
|
||||||
themes: (await getThemeList()).map(t => t.name),
|
themes: (await getThemeList()).map((t) => t.name),
|
||||||
theme: config.theme || 'default',
|
theme: config.theme || 'default',
|
||||||
encryption: await translate(encEnabled ? 'options.enabled' : 'options.disabled')
|
encryption: await translate(encEnabled ? 'options.enabled' : 'options.disabled'),
|
||||||
})
|
})
|
||||||
|
|
||||||
this.forceUpdate()
|
this.forceUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
setGameExec(value: string) {
|
setGamePath(value: string) {
|
||||||
setConfigOption('game_install_path', value)
|
setConfigOption('game_install_path', value)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
game_install_path: value
|
game_install_path: value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setGameExecutable(value: string) {
|
||||||
|
if (this.state.game_install_path != '') {
|
||||||
|
if (value.includes(this.state.game_install_path)) {
|
||||||
|
value = value.replace(this.state.game_install_path + '\\', '')
|
||||||
|
|
||||||
|
setConfigOption('game_executable', value)
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
game_executable: value,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
alert('Game executable must be inside the game folder!')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert('Please set the game install path first!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setGrasscutterJar(value: string) {
|
setGrasscutterJar(value: string) {
|
||||||
setConfigOption('grasscutter_path', value)
|
setConfigOption('grasscutter_path', value)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
grasscutter_path: value
|
grasscutter_path: value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +122,7 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
setConfigOption('java_path', value)
|
setConfigOption('java_path', value)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
java_path: value
|
java_path: value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +141,7 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
setConfigOption('grasscutter_with_game', changedVal)
|
setConfigOption('grasscutter_with_game', changedVal)
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
grasscutter_with_game: changedVal
|
grasscutter_with_game: changedVal,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,16 +152,16 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
if (!isUrl) {
|
if (!isUrl) {
|
||||||
const filename = value.replace(/\\/g, '/').split('/').pop()
|
const filename = value.replace(/\\/g, '/').split('/').pop()
|
||||||
const localBgPath = (await dataDir() as string).replace(/\\/g, '/')
|
const localBgPath = ((await dataDir()) as string).replace(/\\/g, '/')
|
||||||
|
|
||||||
await setConfigOption('customBackground', `${localBgPath}/cultivation/bg/${filename}`)
|
await setConfigOption('customBackground', `${localBgPath}/cultivation/bg/${filename}`)
|
||||||
|
|
||||||
// Copy the file over to the local directory
|
// Copy the file over to the local directory
|
||||||
await invoke('copy_file', {
|
await invoke('copy_file', {
|
||||||
path: value.replace(/\\/g, '/'),
|
path: value.replace(/\\/g, '/'),
|
||||||
newPath: `${localBgPath}cultivation/bg/`
|
newPath: `${localBgPath}cultivation/bg/`,
|
||||||
})
|
})
|
||||||
|
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
} else {
|
} else {
|
||||||
await setConfigOption('customBackground', value)
|
await setConfigOption('customBackground', value)
|
||||||
@ -163,68 +185,81 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
await server.toggleEncryption(folderPath + '/config.json')
|
await server.toggleEncryption(folderPath + '/config.json')
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
encryption: await translate(await server.encryptionEnabled(folderPath + '/config.json') ? 'options.enabled' : 'options.disabled')
|
encryption: await translate(
|
||||||
|
(await server.encryptionEnabled(folderPath + '/config.json')) ? 'options.enabled' : 'options.disabled'
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Menu closeFn={this.props.closeFn} className="Options" heading="Options">
|
<Menu closeFn={this.props.closeFn} className="Options" heading="Options">
|
||||||
<div className='OptionSection' id="menuOptionsContainerGameExec">
|
<div className="OptionSection" id="menuOptionsContainerGamePath">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelGameExec">
|
<div className="OptionLabel" id="menuOptionsLabelGamePath">
|
||||||
<Tr text="options.game_exec" />
|
<Tr text="options.game_path" />
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionValue' id="menuOptionsDirGameExec">
|
<div className="OptionValue" id="menuOptionsDirGamePath">
|
||||||
<DirInput onChange={this.setGameExec} value={this.state?.game_install_path} folder={true} />
|
<DirInput onChange={this.setGamePath} value={this.state?.game_install_path} folder={true} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionSection' id="menuOptionsContainerGCJar">
|
<div className="OptionSection" id="menuOptionsContainerGameExecutable">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelGCJar">
|
<div className="OptionLabel" id="menuOptionsLabelGameExecutable">
|
||||||
|
<Tr text="options.game_executable" />
|
||||||
|
</div>
|
||||||
|
<div className="OptionValue" id="menuOptionsDirGameExecutable">
|
||||||
|
<DirInput onChange={this.setGameExecutable} value={this.state?.game_executable} folder={false} extensions={['exe']} openFolder={this.state?.game_install_path} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="OptionSection" id="menuOptionsContainerGCJar">
|
||||||
|
<div className="OptionLabel" id="menuOptionsLabelGCJar">
|
||||||
<Tr text="options.grasscutter_jar" />
|
<Tr text="options.grasscutter_jar" />
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionValue' id="menuOptionsDirGCJar">
|
<div className="OptionValue" id="menuOptionsDirGCJar">
|
||||||
<DirInput onChange={this.setGrasscutterJar} value={this.state?.grasscutter_path} extensions={['jar']} />
|
<DirInput onChange={this.setGrasscutterJar} value={this.state?.grasscutter_path} extensions={['jar']} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionSection' id="menuOptionsContainerToggleEnc">
|
<div className="OptionSection" id="menuOptionsContainerToggleEnc">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelToggleEnc">
|
<div className="OptionLabel" id="menuOptionsLabelToggleEnc">
|
||||||
<Tr text="options.toggle_encryption" />
|
<Tr text="options.toggle_encryption" />
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionValue' id="menuOptionsButtonToggleEnc">
|
<div className="OptionValue" id="menuOptionsButtonToggleEnc">
|
||||||
<BigButton onClick={this.toggleEncryption} id="toggleEnc">
|
<BigButton onClick={this.toggleEncryption} id="toggleEnc">
|
||||||
{
|
{this.state.encryption}
|
||||||
this.state.encryption
|
|
||||||
}
|
|
||||||
</BigButton>
|
</BigButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<div className='OptionSection' id="menuOptionsContainerGCWGame">
|
<div className="OptionSection" id="menuOptionsContainerGCWGame">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelGCWDame">
|
<div className="OptionLabel" id="menuOptionsLabelGCWDame">
|
||||||
<Tr text="options.grasscutter_with_game" />
|
<Tr text="options.grasscutter_with_game" />
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionValue' id="menuOptionsCheckboxGCWGame">
|
<div className="OptionValue" id="menuOptionsCheckboxGCWGame">
|
||||||
<Checkbox onChange={this.toggleGrasscutterWithGame} checked={this.state?.grasscutter_with_game} id="gcWithGame" />
|
<Checkbox
|
||||||
|
onChange={this.toggleGrasscutterWithGame}
|
||||||
|
checked={this.state?.grasscutter_with_game}
|
||||||
|
id="gcWithGame"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<div className='OptionSection' id="menuOptionsContainerThemes">
|
<div className="OptionSection" id="menuOptionsContainerThemes">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelThemes">
|
<div className="OptionLabel" id="menuOptionsLabelThemes">
|
||||||
<Tr text="options.theme" />
|
<Tr text="options.theme" />
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionValue' id="menuOptionsSelectThemes">
|
<div className="OptionValue" id="menuOptionsSelectThemes">
|
||||||
<select value={this.state.theme} id="menuOptionsSelectMenuThemes" onChange={(event) => {
|
<select
|
||||||
this.setTheme(event.target.value)
|
value={this.state.theme}
|
||||||
}}>
|
id="menuOptionsSelectMenuThemes"
|
||||||
{this.state.themes.map(t => (
|
onChange={(event) => {
|
||||||
<option
|
this.setTheme(event.target.value)
|
||||||
key={t}
|
}}
|
||||||
value={t}>
|
>
|
||||||
|
{this.state.themes.map((t) => (
|
||||||
|
<option key={t} value={t}>
|
||||||
{t}
|
{t}
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
@ -234,20 +269,20 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<div className='OptionSection' id="menuOptionsContainerJavaPath">
|
<div className="OptionSection" id="menuOptionsContainerJavaPath">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelJavaPath">
|
<div className="OptionLabel" id="menuOptionsLabelJavaPath">
|
||||||
<Tr text="options.java_path" />
|
<Tr text="options.java_path" />
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionValue' id="menuOptionsDirJavaPath">
|
<div className="OptionValue" id="menuOptionsDirJavaPath">
|
||||||
<DirInput onChange={this.setJavaPath} value={this.state?.java_path} extensions={['exe']} />
|
<DirInput onChange={this.setJavaPath} value={this.state?.java_path} extensions={['exe']} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='OptionSection' id="menuOptionsContainerBG">
|
<div className="OptionSection" id="menuOptionsContainerBG">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelBG">
|
<div className="OptionLabel" id="menuOptionsLabelBG">
|
||||||
<Tr text="options.background" />
|
<Tr text="options.background" />
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionValue' id="menuOptionsDirBG">
|
<div className="OptionValue" id="menuOptionsDirBG">
|
||||||
<DirInput
|
<DirInput
|
||||||
onChange={this.setCustomBackground}
|
onChange={this.setCustomBackground}
|
||||||
value={this.state?.bg_url_or_path}
|
value={this.state?.bg_url_or_path}
|
||||||
@ -262,19 +297,20 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='OptionSection' id="menuOptionsContainerLang">
|
<div className="OptionSection" id="menuOptionsContainerLang">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelLang">
|
<div className="OptionLabel" id="menuOptionsLabelLang">
|
||||||
<Tr text="options.language" />
|
<Tr text="options.language" />
|
||||||
</div>
|
</div>
|
||||||
<div className='OptionValue' id="menuOptionsSelectLang">
|
<div className="OptionValue" id="menuOptionsSelectLang">
|
||||||
<select value={this.state.current_language} id="menuOptionsSelectMenuLang" onChange={(event) => {
|
<select
|
||||||
this.setLanguage(event.target.value)
|
value={this.state.current_language}
|
||||||
}}>
|
id="menuOptionsSelectMenuLang"
|
||||||
{this.state.language_options.map(lang => (
|
onChange={(event) => {
|
||||||
<option
|
this.setLanguage(event.target.value)
|
||||||
key={Object.keys(lang)[0]}
|
}}
|
||||||
value={Object.keys(lang)[0]}>
|
>
|
||||||
|
{this.state.language_options.map((lang) => (
|
||||||
|
<option key={Object.keys(lang)[0]} value={Object.keys(lang)[0]}>
|
||||||
{lang[Object.keys(lang)[0]]}
|
{lang[Object.keys(lang)[0]]}
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
@ -284,4 +320,4 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
</Menu>
|
</Menu>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ let defaultConfig: Configuration
|
|||||||
defaultConfig = {
|
defaultConfig = {
|
||||||
toggle_grasscutter: false,
|
toggle_grasscutter: false,
|
||||||
game_install_path: 'C:\\Program Files\\Genshin Impact\\Genshin Impact game',
|
game_install_path: 'C:\\Program Files\\Genshin Impact\\Genshin Impact game',
|
||||||
game_version: 'global',
|
game_executable: 'GenshinImpact.exe',
|
||||||
grasscutter_with_game: false,
|
grasscutter_with_game: false,
|
||||||
grasscutter_path: '',
|
grasscutter_path: '',
|
||||||
java_path: '',
|
java_path: '',
|
||||||
@ -31,7 +31,7 @@ let defaultConfig: Configuration
|
|||||||
export interface Configuration {
|
export interface Configuration {
|
||||||
toggle_grasscutter: boolean
|
toggle_grasscutter: boolean
|
||||||
game_install_path: string
|
game_install_path: string
|
||||||
game_version: string
|
game_executable: string
|
||||||
grasscutter_with_game: boolean
|
grasscutter_with_game: boolean
|
||||||
grasscutter_path: string
|
grasscutter_path: string
|
||||||
java_path: string
|
java_path: string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user