From 3ba467d03bda979a0d4054bfcb79412b637e0dd4 Mon Sep 17 00:00:00 2001 From: fnrir Date: Sat, 24 Jun 2023 14:09:22 +0200 Subject: [PATCH 1/3] Fix paths Replaced backslashes in paths with slashes. I did not touch function that do the same with paths. Those can be removed manually. Also dataDir() returns a path that ends with a slash so I got rid of duplicated slashes. --- .vscode/settings.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/ui/Debug.tsx | 6 ++-- src/ui/components/ServerLaunchSection.tsx | 2 +- src/ui/components/menu/Downloads.tsx | 44 +++++++++++------------ src/ui/components/menu/Game.tsx | 4 +-- src/ui/components/menu/Options.tsx | 2 +- src/utils/configuration.ts | 2 +- src/utils/game.ts | 4 +-- src/utils/rsa.ts | 6 ++-- src/utils/themes.ts | 2 +- 11 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 53e875e..36e7d29 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "rust-analyzer.linkedProjects": [".\\src-tauri\\Cargo.toml"] + "rust-analyzer.linkedProjects": ["src-tauri/Cargo.toml"] } diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 631c762..d1c5b20 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,5 +1,5 @@ { - "$schema": "..\\node_modules/@tauri-apps/cli\\schema.json", + "$schema": "../node_modules/@tauri-apps/cli/schema.json", "build": { "beforeDevCommand": "yarn start", "devPath": "http://localhost:3000", diff --git a/src/ui/Debug.tsx b/src/ui/Debug.tsx index 41ad966..54c76fb 100644 --- a/src/ui/Debug.tsx +++ b/src/ui/Debug.tsx @@ -15,7 +15,7 @@ async function setProxyAddress(address: string) { } async function startProxy() { - await invoke('connect', { port: 2222, certificatePath: (await dataDir()) + '\\cultivation\\ca' }) + await invoke('connect', { port: 2222, certificatePath: (await dataDir()) + 'cultivation/ca' }) await invoke('open_in_browser', { url: 'https://hoyoverse.com' }) } @@ -24,12 +24,12 @@ async function stopProxy() { } async function generateCertificates() { - await invoke('generate_ca_files', { path: (await dataDir()) + '\\cultivation' }) + await invoke('generate_ca_files', { path: (await dataDir()) + 'cultivation' }) } async function generateInfo() { console.log({ - certificatePath: (await dataDir()) + '\\cultivation\\ca', + certificatePath: (await dataDir()) + 'cultivation/ca', isAdmin: await invoke('is_elevated'), connectingTo: proxyAddress, }) diff --git a/src/ui/components/ServerLaunchSection.tsx b/src/ui/components/ServerLaunchSection.tsx index ad038a0..55776c3 100644 --- a/src/ui/components/ServerLaunchSection.tsx +++ b/src/ui/components/ServerLaunchSection.tsx @@ -166,7 +166,7 @@ export default class ServerLaunchSection extends React.Component addr: (this.state.httpsEnabled ? 'https' : 'http') + '://' + this.state.ip + ':' + this.state.port, }) // Connect to proxy - await invoke('connect', { port: 8365, certificatePath: (await dataDir()) + '\\cultivation\\ca' }) + await invoke('connect', { port: 8365, certificatePath: (await dataDir()) + 'cultivation/ca' }) } // Open server as well if the options are set diff --git a/src/ui/components/menu/Downloads.tsx b/src/ui/components/menu/Downloads.tsx index 973d3e9..badd477 100644 --- a/src/ui/components/menu/Downloads.tsx +++ b/src/ui/components/menu/Downloads.tsx @@ -85,15 +85,15 @@ export default class Downloads extends React.Component { return } - const path = gc_path.substring(0, gc_path.lastIndexOf('\\')) + const path = gc_path.substring(0, gc_path.lastIndexOf('/')) if (gc_path) { const resources_exist: boolean = ((await invoke('dir_exists', { - path: path + '\\resources', + path: path + '/resources', })) as boolean) && (!(await invoke('dir_is_empty', { - path: path + '\\resources', + path: path + '/resources', })) as boolean) this.setState({ @@ -110,7 +110,7 @@ export default class Downloads extends React.Component { // Set to default if not set if (!path || path === '') { const appdata = await dataDir() - folderPath = appdata + 'cultivation\\grasscutter' + folderPath = appdata + 'cultivation/grasscutter' // Early return since its formatted properly return folderPath @@ -133,8 +133,8 @@ export default class Downloads extends React.Component { async downloadGrasscutterFullBuild() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(FULL_BUILD_DOWNLOAD, folder + '\\GrasscutterCulti.zip', async () => { - await unzip(folder + '\\GrasscutterCulti.zip', folder + '\\', true) + this.props.downloadManager.addDownload(FULL_BUILD_DOWNLOAD, folder + '/GrasscutterCulti.zip', async () => { + await unzip(folder + '/GrasscutterCulti.zip', folder + '/', true) this.toggleButtons() }) @@ -143,8 +143,8 @@ export default class Downloads extends React.Component { async downloadGrasscutterFullQuest() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(FULL_QUEST_DOWNLOAD, folder + '\\GrasscutterQuests.zip', async () => { - await unzip(folder + '\\GrasscutterQuests.zip', folder + '\\', true) + this.props.downloadManager.addDownload(FULL_QUEST_DOWNLOAD, folder + '/GrasscutterQuests.zip', async () => { + await unzip(folder + '/GrasscutterQuests.zip', folder + '/', true) this.toggleButtons() }) @@ -153,8 +153,8 @@ export default class Downloads extends React.Component { async downloadGrasscutterStableRepo() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(STABLE_REPO_DOWNLOAD, folder + '\\grasscutter_repo.zip', async () => { - await unzip(folder + '\\grasscutter_repo.zip', folder + '\\', true) + this.props.downloadManager.addDownload(STABLE_REPO_DOWNLOAD, folder + '/grasscutter_repo.zip', async () => { + await unzip(folder + '/grasscutter_repo.zip', folder + '/', true) this.toggleButtons() }) @@ -163,8 +163,8 @@ export default class Downloads extends React.Component { async downloadGrasscutterDevRepo() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(DEV_REPO_DOWNLOAD, folder + '\\grasscutter_repo.zip', async () => { - await unzip(folder + '\\grasscutter_repo.zip', folder + '\\', true) + this.props.downloadManager.addDownload(DEV_REPO_DOWNLOAD, folder + '/grasscutter_repo.zip', async () => { + await unzip(folder + '/grasscutter_repo.zip', folder + '/', true) this.toggleButtons() }) @@ -173,8 +173,8 @@ export default class Downloads extends React.Component { async downloadGrasscutterLatest() { const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(DEV_DOWNLOAD, folder + '\\grasscutter.zip', async () => { - await unzip(folder + '\\grasscutter.zip', folder + '\\', true) + this.props.downloadManager.addDownload(DEV_DOWNLOAD, folder + '/grasscutter.zip', async () => { + await unzip(folder + '/grasscutter.zip', folder + '/', true) this.toggleButtons() }) @@ -190,22 +190,22 @@ export default class Downloads extends React.Component { 'Extracting resources can take time! If your resources appear to be "stuck" extracting for less than 15-20 mins, they likely still are extracting.' ) const folder = await this.getGrasscutterFolder() - this.props.downloadManager.addDownload(RESOURCES_DOWNLOAD, folder + '\\resources.zip', async () => { + this.props.downloadManager.addDownload(RESOURCES_DOWNLOAD, folder + '/resources.zip', async () => { // Delete the existing folder if it exists if ( await invoke('dir_exists', { - path: folder + '\\resources', + path: folder + '/resources', }) ) { await invoke('dir_delete', { - path: folder + '\\resources', + path: folder + '/resources', }) } - await unzip(folder + '\\resources.zip', folder + '\\', true) + await unzip(folder + '/resources.zip', folder + '/', true) // Rename folder to resources invoke('rename', { - path: folder + '\\Resources', + path: folder + '/Resources', newName: 'resources', }) @@ -216,13 +216,13 @@ export default class Downloads extends React.Component { } async downloadMigoto() { - const folder = (await this.getCultivationFolder()) + '\\3dmigoto' + const folder = (await this.getCultivationFolder()) + '/3dmigoto' await invoke('dir_create', { path: folder, }) - this.props.downloadManager.addDownload(MIGOTO_DOWNLOAD, folder + '\\GIMI-3dmigoto.zip', async () => { - await unzip(folder + '\\GIMI-3dmigoto.zip', folder + '\\', true) + this.props.downloadManager.addDownload(MIGOTO_DOWNLOAD, folder + '/GIMI-3dmigoto.zip', async () => { + await unzip(folder + '/GIMI-3dmigoto.zip', folder + '/', true) this.toggleButtons() }) diff --git a/src/ui/components/menu/Game.tsx b/src/ui/components/menu/Game.tsx index c623ba5..384a775 100644 --- a/src/ui/components/menu/Game.tsx +++ b/src/ui/components/menu/Game.tsx @@ -45,8 +45,8 @@ export default class Downloads extends React.Component { async downloadGame() { const folder = this.state.gameDownloadFolder - this.props.downloadManager.addDownload(GAME_DOWNLOAD, folder + '\\game.zip', async () => { - await unzip(folder + '\\game.zip', folder + '\\', true) + this.props.downloadManager.addDownload(GAME_DOWNLOAD, folder + '/game.zip', async () => { + await unzip(folder + '/game.zip', folder + '/', true) this.setState({ gameDownloading: false, }) diff --git a/src/ui/components/menu/Options.tsx b/src/ui/components/menu/Options.tsx index 01b5e73..7b93a86 100644 --- a/src/ui/components/menu/Options.tsx +++ b/src/ui/components/menu/Options.tsx @@ -240,7 +240,7 @@ export default class Options extends React.Component { if (!isUrl) { const filename = value.replace(/\\/g, '/').split('/').pop() - const localBgPath = ((await dataDir()) as string).replace(/\\/g, '/') + const localBgPath = (await dataDir()).replace(/\\/g, '/') await setConfigOption('custom_background', `${localBgPath}/cultivation/bg/${filename}`) diff --git a/src/utils/configuration.ts b/src/utils/configuration.ts index ad7b997..f725024 100644 --- a/src/utils/configuration.ts +++ b/src/utils/configuration.ts @@ -118,7 +118,7 @@ async function readConfigFile() { await fs.createDir(local + 'cultivation').catch((e) => console.log(e)) } - const innerDirs = await fs.readDir(local + '/cultivation') + const innerDirs = await fs.readDir(local + 'cultivation') // Create grasscutter dir for potential installation if (!innerDirs.find((fileOrDir) => fileOrDir?.name === 'grasscutter')) { diff --git a/src/utils/game.ts b/src/utils/game.ts index 9d933ee..0c17edd 100644 --- a/src/utils/game.ts +++ b/src/utils/game.ts @@ -45,7 +45,7 @@ export async function getGameDataFolder() { return null } - return (await getGameFolder()) + '\\' + gameExec.replace('.exe', '_Data') + return (await getGameFolder()) + '/' + gameExec.replace('.exe', '_Data') } export async function getGameVersion() { @@ -57,7 +57,7 @@ export async function getGameVersion() { const settings = JSON.parse( await invoke('read_file', { - path: GameData + '\\StreamingAssets\\asb_settings.json', + path: GameData + '/StreamingAssets/asb_settings.json', }) ) diff --git a/src/utils/rsa.ts b/src/utils/rsa.ts index 7bf6071..0a381be 100644 --- a/src/utils/rsa.ts +++ b/src/utils/rsa.ts @@ -3,11 +3,11 @@ import { getGameFolder } from './game' // Patch file from: https://github.com/34736384/RSAPatch/ export async function patchGame() { - const patchPath = (await invoke('install_location')) + '\\patch\\version.dll' + const patchPath = (await invoke('install_location')) + '/patch/version.dll' // Are we already patched with mhypbase? If so, that's fine, just continue as normal const gameIsPatched = await invoke('are_files_identical', { path1: patchPath, - path2: (await getGameRSAPath()) + '\\mhypbase.dll', + path2: (await getGameRSAPath()) + '/mhypbase.dll', }) // Tell user they won't be unpatched with manual mhypbase patch @@ -33,7 +33,7 @@ export async function patchGame() { export async function unpatchGame() { // Just delete patch since it's not replacing any existing file const deleted = await invoke('delete_file', { - path: (await getGameRSAPath()) + '\\version.dll', + path: (await getGameRSAPath()) + '/version.dll', }) return deleted diff --git a/src/utils/themes.ts b/src/utils/themes.ts index 4310eb5..96bb0e2 100644 --- a/src/utils/themes.ts +++ b/src/utils/themes.ts @@ -40,7 +40,7 @@ const defaultTheme = { export async function getThemeList() { // Do some invoke to backend to get the theme list const themes = (await invoke('get_theme_list', { - dataDir: `${await dataDir()}/cultivation`, + dataDir: `${await dataDir()}cultivation`, })) as BackendThemeList[] const list: ThemeList[] = [ // ALWAYS include default theme From b9b09296683a40829661a25b6d5e65d639d57dcc Mon Sep 17 00:00:00 2001 From: fnrir Date: Tue, 27 Jun 2023 10:50:55 +0200 Subject: [PATCH 2/3] Fix trying to open nonexistant config If you try to open settings, or change the "Toggle Encryption" toggle, while GC's server config does not exist it no longer throws an error message. --- src/ui/components/menu/Options.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ui/components/menu/Options.tsx b/src/ui/components/menu/Options.tsx index 7b93a86..9c584dd 100644 --- a/src/ui/components/menu/Options.tsx +++ b/src/ui/components/menu/Options.tsx @@ -99,10 +99,13 @@ export default class Options extends React.Component { 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') + 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) From b56ad4e465eb87045eb17a2012d545f7e9be7510 Mon Sep 17 00:00:00 2001 From: fnrir Date: Tue, 27 Jun 2023 10:51:35 +0200 Subject: [PATCH 3/3] Increase read_file verbosity Changed the error message that gets printed when Culti tries to read a file, but fails. --- src-tauri/src/file_helpers.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src-tauri/src/file_helpers.rs b/src-tauri/src/file_helpers.rs index 042db97..3caf0c8 100644 --- a/src-tauri/src/file_helpers.rs +++ b/src-tauri/src/file_helpers.rs @@ -131,11 +131,10 @@ pub fn read_file(path: String) -> String { let mut file = match fs::File::open(path_buf) { Ok(file) => file, Err(e) => { + println!("Failed to open file {}: {}", &path, e); if path.contains("config") { // Server.ts won't print the error so handle the message here for the user println!("Server config not found or invalid. Be sure to run the server at least once to generate it before making edits."); - } else { - println!("Failed to open file: {}", e); } return String::new(); // Send back error for handling by the caller }