Merge pull request #83 from 4Benj/main

Fix some filesystem related bugs
This commit is contained in:
SpikeHD
2022-09-04 14:09:03 -07:00
committed by GitHub
5 changed files with 74 additions and 20 deletions

View File

@@ -63,7 +63,7 @@ pub fn copy_file(path: String, new_path: String) -> bool {
let path_buf = std::path::PathBuf::from(&path); let path_buf = std::path::PathBuf::from(&path);
// If the new path doesn't exist, create it. // If the new path doesn't exist, create it.
if !dir_exists(new_path_buf.pop().to_string().as_str()) { if !dir_exists(std::path::PathBuf::from(&new_path).pop().to_string().as_str()) {
std::fs::create_dir_all(&new_path).unwrap(); std::fs::create_dir_all(&new_path).unwrap();
} }
@@ -85,7 +85,7 @@ pub fn copy_file_with_new_name(path: String, new_path: String, new_name: String)
let path_buf = std::path::PathBuf::from(&path); let path_buf = std::path::PathBuf::from(&path);
// If the new path doesn't exist, create it. // If the new path doesn't exist, create it.
if !dir_exists(new_path_buf.pop().to_string().as_str()) { if !dir_exists(std::path::PathBuf::from(&new_path).pop().to_string().as_str()) {
match std::fs::create_dir_all(&new_path) { match std::fs::create_dir_all(&new_path) {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
@@ -95,8 +95,10 @@ pub fn copy_file_with_new_name(path: String, new_path: String, new_name: String)
}; };
} }
new_path_buf.push(new_name);
// Copy old to new // Copy old to new
match std::fs::copy(&path_buf, format!("{}/{}", new_path, new_name)) { match std::fs::copy(&path_buf, &new_path_buf) {
Ok(_) => true, Ok(_) => true,
Err(e) => { Err(e) => {
println!("Failed to copy file: {}", e); println!("Failed to copy file: {}", e);

View File

@@ -1,8 +1,5 @@
use regex::Regex; use regex::Regex;
use std::fs::File; use std::{fs, path::Path, fs::File, fs::OpenOptions, io::Read, io::Write};
use std::fs::OpenOptions;
use std::io::Read;
use std::io::Write;
// For these two functions, a non-zero return value indicates failure. // For these two functions, a non-zero return value indicates failure.
extern "C" { extern "C" {
@@ -13,6 +10,12 @@ extern "C" {
#[tauri::command] #[tauri::command]
pub fn patch_metadata(metadata_folder: &str) -> bool { pub fn patch_metadata(metadata_folder: &str) -> bool {
let metadata_file = &(metadata_folder.to_owned() + "\\global-metadata-unpatched.dat"); let metadata_file = &(metadata_folder.to_owned() + "\\global-metadata-unpatched.dat");
// check if metadata_file exists
if !Path::new(metadata_file).exists() {
println!("Metadata file not found");
return false;
}
println!("Patching metadata file: {}", metadata_file); println!("Patching metadata file: {}", metadata_file);
let decrypted = decrypt_metadata(metadata_file); let decrypted = decrypt_metadata(metadata_file);
if do_vecs_match(&decrypted, &Vec::new()) { if do_vecs_match(&decrypted, &Vec::new()) {
@@ -111,20 +114,17 @@ fn replace_keys(data: &[u8]) -> Vec<u8> {
fn replace_rsa_key(old_data: &str, to_replace: &str, file_name: &str) -> String { fn replace_rsa_key(old_data: &str, to_replace: &str, file_name: &str) -> String {
// Read dispatch key file // Read dispatch key file
unsafe { unsafe {
// Get key folder from exe path // Get key path from current directory
let mut exe_path = std::env::current_exe().unwrap(); let key_file_path = std::env::current_dir().unwrap().join("keys").join(file_name);
exe_path.pop();
let key_folder = exe_path.to_str().unwrap().to_string(); let key_data = match fs::read(&key_file_path) {
let mut new_key_file = match File::open(format!("{}/keys/{}", key_folder, file_name)) {
Ok(file) => file, Ok(file) => file,
Err(e) => { Err(e) => {
println!("Failed to open keys/{}: {}", file_name, e); println!("Failed to open {}: {}", key_file_path.to_str().unwrap(), e);
return String::new(); return String::new();
} }
}; };
let mut key_data = Vec::new();
new_key_file.read_to_end(&mut key_data).unwrap();
let new_key = String::from_utf8_unchecked(key_data.to_vec()); let new_key = String::from_utf8_unchecked(key_data.to_vec());
// Replace old key with new key // Replace old key with new key
@@ -134,6 +134,7 @@ fn replace_rsa_key(old_data: &str, to_replace: &str, file_name: &str) -> String
fn encrypt_metadata(old_data: &[u8]) -> Vec<u8> { fn encrypt_metadata(old_data: &[u8]) -> Vec<u8> {
let mut data = old_data.to_vec(); let mut data = old_data.to_vec();
let success = unsafe { encrypt_global_metadata(data.as_mut_ptr(), data.len()) } == 0; let success = unsafe { encrypt_global_metadata(data.as_mut_ptr(), data.len()) } == 0;
if success { if success {
println!("Successfully encrypted global-metadata"); println!("Successfully encrypted global-metadata");

View File

@@ -12,7 +12,7 @@ import Plus from '../../resources/icons/plus.svg'
import './ServerLaunchSection.css' import './ServerLaunchSection.css'
import { dataDir } from '@tauri-apps/api/path' import { dataDir } from '@tauri-apps/api/path'
import { getGameExecutable } from '../../utils/game' import { getGameExecutable, getGameVersion } from '../../utils/game'
import { patchGame, unpatchGame } from '../../utils/metadata' import { patchGame, unpatchGame } from '../../utils/metadata'
interface IProps { interface IProps {
@@ -110,6 +110,24 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
// Connect to proxy // Connect to proxy
if (config.toggle_grasscutter) { if (config.toggle_grasscutter) {
if (config.patch_metadata) { if (config.patch_metadata) {
const gameVersion = await getGameVersion()
console.log(gameVersion)
if(gameVersion == null) {
alert('Game version could not be determined. Please make sure you have the game correctly selected and try again.')
return
}
if(gameVersion?.major == 2 && gameVersion?.minor < 8) {
alert('Game version is too old for metadata patching. Please disable metadata patching in the settings and try again.')
return
}
if(gameVersion?.major == 3 && gameVersion?.minor >= 1) {
alert('Game version is too new for metadata patching. Please disable metadata patching in the settings to launch the game.\nNOTE: You will require a UA patch to play the game.')
return
}
const patched = await patchGame() const patched = await patchGame()
if (!patched) { if (!patched) {

View File

@@ -1,3 +1,4 @@
import { invoke } from '@tauri-apps/api'
import { getConfig } from './configuration' import { getConfig } from './configuration'
export async function getGameExecutable() { export async function getGameExecutable() {
@@ -25,3 +26,34 @@ export async function getGameFolder() {
return path return path
} }
export async function getGameDataFolder() {
const gameExec = await getGameExecutable()
if (!gameExec) {
return null
}
return (await getGameFolder()) + '\\' + gameExec.replace('.exe', '_Data')
}
export async function getGameVersion() {
const GameData = await getGameDataFolder();
if (!GameData) {
return null
}
const settings = JSON.parse(await invoke('read_file', {
path: GameData + '\\StreamingAssets\\asb_settings.json',
}))
const versionRaw = settings.variance.split('.');
const version = {
major: parseInt(versionRaw[0]),
minor: parseInt(versionRaw[1].split('_')[0]),
release: parseInt(versionRaw[1].split('_')[1]),
}
return version;
}

View File

@@ -1,7 +1,7 @@
import { invoke } from '@tauri-apps/api' import { invoke } from '@tauri-apps/api'
import { dataDir } from '@tauri-apps/api/path' import { dataDir } from '@tauri-apps/api/path'
import DownloadHandler from './download' import DownloadHandler from './download'
import { getGameExecutable, getGameFolder } from './game' import { getGameDataFolder, getGameExecutable, getGameFolder, getGameVersion } from './game'
export async function patchMetadata() { export async function patchMetadata() {
const metadataExists = await invoke('dir_exists', { const metadataExists = await invoke('dir_exists', {
@@ -171,13 +171,13 @@ export async function unpatchGame() {
} }
export async function getGameMetadataPath() { export async function getGameMetadataPath() {
const gameExec = await getGameExecutable() const gameData = await getGameDataFolder()
if (!gameExec) { if (!gameData) {
return null return null
} }
return ((await getGameFolder()) + '\\' + gameExec.replace('.exe', '_Data') + '\\Managed\\Metadata').replace( return (gameData + '\\Managed\\Metadata').replace(
/\\/g, /\\/g,
'/' '/'
) )
@@ -188,6 +188,7 @@ export async function getBackupMetadataPath() {
} }
export async function globalMetadataLink() { export async function globalMetadataLink() {
// TODO: Get metadata based on current game version.
const versionAPIUrl = const versionAPIUrl =
'https://sdk-os-static.mihoyo.com/hk4e_global/mdk/launcher/api/resource?channel_id=1&key=gcStgarh&launcher_id=10&sub_channel_id=0' 'https://sdk-os-static.mihoyo.com/hk4e_global/mdk/launcher/api/resource?channel_id=1&key=gcStgarh&launcher_id=10&sub_channel_id=0'