Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass "args" via .json file rather than arguments to rust program #20

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ edition = "2021"
[dependencies]
Inflector = "*"
log = "0.4.20"
serde = { version = "1.0.201", features = ["derive"] }
serde_json = "1.0.117"
simplelog = "0.12.1"
51 changes: 38 additions & 13 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def findWorkingExecutablePath(executable_paths, flags):
}

class BuildVariant:
def __init__(self, short_description, chapter, unity, system, target_crc32=None, translation_default=False):
def __init__(self, short_description, chapter, unity, system, target_crc32=None, translation_default=False, path_id_overrides=None):
self.chapter = chapter
self.unity = unity
self.system = system
Expand All @@ -63,14 +63,21 @@ def __init__(self, short_description, chapter, unity, system, target_crc32=None,
self.data_dir = f"HigurashiEp{self.chapter_number:02}_Data"
self.translation_default = translation_default
self.short_description = short_description

def get_build_command(self) -> str:
args = [self.chapter, self.unity, self.system]

if self.target_crc32 is not None:
args.append(self.target_crc32)

return " ".join(args)
self.path_id_overrides = []
if path_id_overrides is not None:
self.path_id_overrides = path_id_overrides

def get_build_settings(self) -> dict[str, object]:
return {
"chapter": self.chapter,
"unity": self.unity,
"system": self.system,
"crc32": self.target_crc32,
"path_id_overrides": self.path_id_overrides,
}

def get_build_settings_json(self) -> str:
return json.dumps(self.get_build_settings())

def get_translation_sharedassets_name(self) -> str:
operatingSystem = None
Expand Down Expand Up @@ -356,7 +363,7 @@ def save(self):

# Get a list of build variants (like 'onikakushi 5.2.2f1 win') depending on commmand line arguments
build_variants = get_build_variants(chapter_name)
build_variants_list = "\n - ".join([b.get_build_command() for b in build_variants])
build_variants_list = "\n - ".join([b.get_build_settings_json() for b in build_variants])
print(f"-------- Build Started --------")
print(f"Chapter: [{chapter_name}] | Translation Archive Output: [{('Enabled' if translation else 'Disabled')}]")
print(f"Variants:")
Expand Down Expand Up @@ -440,11 +447,29 @@ def save(self):

# Build all the requested variants
for build_variant in build_variants:
print(f"Building .assets for {build_variant.get_build_command()}...")
print(f"Building .assets for {build_variant.get_build_settings_json()}...")

# Delete any old .json settings to make sure we don't reuse it accidentally
settings_path = 'rust_script_settings.json'
if os.path.exists(settings_path):
os.remove(settings_path)

# Write json settings file for rust to use
json_settings = build_variant.get_build_settings_json()
print(f"Calling rust script with settings: {json_settings}")
with open(settings_path, 'w', encoding='utf-8') as f:
f.write(json_settings)

# Build command line arguments
command = []
if working_cargo:
call(f"cargo run {build_variant.get_build_command()}")
command += ["cargo", "run"]
else:
call(f"ui-compiler.exe {build_variant.get_build_command()}")
command += ["ui-compiler.exe"]
command += [settings_path]

# Call the rust script
call(command)

if translation:
source_sharedassets = os.path.join("output", build_variant.data_dir, "sharedassets0.assets")
Expand Down
82 changes: 73 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,65 @@ use std::process;
use inflector::Inflector;
use log::*;
use simplelog::{TermLogger, TerminalMode, ColorChoice,Config};
use serde::{Deserialize, Serialize};

// The settings this program takes from the .json file
// The .json file should be structured matching this struct
#[derive(Serialize, Deserialize, Debug)]
struct Settings {
chapter: String,
unity: String,
system: String,
checksum: Option<String>,
path_id_overrides: Vec<(String, usize)>
}

// Force a particular file to use a Unity .assets PathID by renaming the file, typically in the 'output/assets' folder
fn force_path_id(directory_assets: &str, original_name: &str, path_id_override: usize) -> std::io::Result<()>
{
let new_name = format!("{} {}", path_id_override, original_name);
let original_path = format!("{}/{}", directory_assets, original_name);
let new_path = format!("{}/{}", directory_assets, new_name);

println!("Forcing path id {}: {} -> {}", path_id_override, original_path, new_path);
fs::rename(original_path, new_path)
}

// Previously settings were read from cmd line, but now we load from .json
// When loading from .json, the first argument should be the path to the .json file.
fn read_settings_from_args_or_json() -> Settings
{
let args: Vec<String> = env::args().collect();

if args[1].ends_with(".json")
{
let json_path = args[1].to_string();
println!("Loading settings from json file {}", json_path);
let json_str = fs::read_to_string(json_path).expect("Unable to read json config file");
serde_json::from_str(json_str.as_str()).expect("Unable to parse json file")
}
else
{
let chapter = args[1].to_string();
let unity = args[2].to_string();
let system = args[3].to_string();
let checksum = if args.len() > 4 {
Some(args[4].to_string())
} else {
None
};

Settings {
chapter,
unity,
system,
checksum,
path_id_overrides: Vec::new()
}
}
}



fn main() -> ExitCode {
TermLogger::init(
Expand All @@ -17,15 +76,12 @@ fn main() -> ExitCode {
)
.expect("Failed to init logger");

let args: Vec<String> = env::args().collect();
let chapter = &args[1];
let unity = &args[2];
let system = &args[3];
let checksum = if args.len() > 4 {
Some(&args[4])
} else {
None
};
let settings = read_settings_from_args_or_json();
let chapter = &settings.chapter;
let unity = &settings.unity;
let system = &settings.system;
let checksum = settings.checksum.as_ref();
println!("Rust Settings: {:?}", settings);

// Check if python is correctly installed
println!("Running 'python --version' to check if python is correctly installed...");
Expand Down Expand Up @@ -207,6 +263,14 @@ fn main() -> ExitCode {

println!();

// 4a. Force certain assets to have specific PathIDs
if settings.path_id_overrides.len() > 0 {
println!("------ Forcing PathIDs ------");
}
for (original_name, path_id_override) in settings.path_id_overrides {
force_path_id(&directory_assets, &original_name, path_id_override).expect("Failed to force ID");
}

// 5. generate emip
let status = Command::new("python")
.env("PYTHONIOENCODING", "utf-8")
Expand Down