mirror of
https://github.com/shijimasoft/cia-unix.git
synced 2025-06-18 14:25:34 -04:00
Replace shell backticks with Process.new for better escaping
This avoids issues with filenames containing spaces and improves reliability when passing arguments to external tools.
This commit is contained in:
parent
a7c2ba7b04
commit
26b758a723
69
cia-unix.cr
69
cia-unix.cr
@ -1,7 +1,7 @@
|
|||||||
require "colorize"
|
require "colorize"
|
||||||
|
|
||||||
log : File = File.new "cia-unix.log", "w"
|
LOG = File.new "cia-unix.log", "w"
|
||||||
log.puts Time.utc.to_s
|
LOG.puts Time.utc.to_s
|
||||||
|
|
||||||
# dependencies check
|
# dependencies check
|
||||||
tools = ["./ctrtool", "./ctrdecrypt", "./makerom", "seeddb.bin"]
|
tools = ["./ctrtool", "./ctrdecrypt", "./makerom", "seeddb.bin"]
|
||||||
@ -9,13 +9,13 @@ tools.each do |tool|
|
|||||||
case tool
|
case tool
|
||||||
when "./ctrtool", "./ctrdecrypt", "./makerom"
|
when "./ctrtool", "./ctrdecrypt", "./makerom"
|
||||||
if !File.exists? %x[which #{tool}].chomp
|
if !File.exists? %x[which #{tool}].chomp
|
||||||
log.delete if File.exists? "cia-unix.log"
|
LOG.delete if File.exists? "cia-unix.log"
|
||||||
download_dep
|
download_dep
|
||||||
abort "#{tool.lchop("./").colorize.mode(:bold)} not found. Make sure it's located in the #{"same directory".colorize.mode(:underline)}" if !File.exists? tool
|
abort "#{tool.lchop("./").colorize.mode(:bold)} not found. Make sure it's located in the #{"same directory".colorize.mode(:underline)}" if !File.exists? tool
|
||||||
end
|
end
|
||||||
when "seeddb.bin"
|
when "seeddb.bin"
|
||||||
if !File.exists? tool
|
if !File.exists? tool
|
||||||
log.delete if File.exists? "cia-unix.log"
|
LOG.delete if File.exists? "cia-unix.log"
|
||||||
download_dep
|
download_dep
|
||||||
abort "#{tool.colorize.mode(:bold)} not found. Make sure it's located in the #{"same directory".colorize.mode(:underline)}" if !File.exists? tool
|
abort "#{tool.colorize.mode(:bold)} not found. Make sure it's located in the #{"same directory".colorize.mode(:underline)}" if !File.exists? tool
|
||||||
end
|
end
|
||||||
@ -31,10 +31,19 @@ end
|
|||||||
|
|
||||||
# roms presence check
|
# roms presence check
|
||||||
if Dir["*.cia"].size.zero? && Dir["*.3ds"].size.zero?
|
if Dir["*.cia"].size.zero? && Dir["*.3ds"].size.zero?
|
||||||
log.delete if File.exists? "cia-unix.log"
|
LOG.delete if File.exists? "cia-unix.log"
|
||||||
abort "No #{"CIA".colorize.mode(:bold)}/#{"3DS".colorize.mode(:bold)} roms were found."
|
abort "No #{"CIA".colorize.mode(:bold)}/#{"3DS".colorize.mode(:bold)} roms were found."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def run_tool(name : String, args : Array(String)) : String
|
||||||
|
process = Process.new("./#{name}", args: args, output: Process::Redirect::Pipe)
|
||||||
|
content = process.output.gets_to_end
|
||||||
|
LOG.puts content
|
||||||
|
exit_code = process.wait.exit_code
|
||||||
|
raise "#{name} failed with exit code #{exit_code}" if exit_code != 0
|
||||||
|
content
|
||||||
|
end
|
||||||
|
|
||||||
def check_decrypt(name : String, ext : String)
|
def check_decrypt(name : String, ext : String)
|
||||||
if File.exists? "#{name}-decrypted.#{ext}"
|
if File.exists? "#{name}-decrypted.#{ext}"
|
||||||
puts "Decryption completed\n".colorize.mode(:underline)
|
puts "Decryption completed\n".colorize.mode(:underline)
|
||||||
@ -43,11 +52,11 @@ def check_decrypt(name : String, ext : String)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def gen_args(name : String, part_count : Int32) : String
|
def gen_args(name : String, part_count : Int32) : Array(String)
|
||||||
args : String = ""
|
args = [] of String
|
||||||
part_count.times do |partition|
|
part_count.times do |partition|
|
||||||
if File.exists? "#{name}.#{partition}.ncch"
|
if File.exists? "#{name}.#{partition}.ncch"
|
||||||
args += "-i '#{name}.#{partition}.ncch:#{partition}:#{partition}' "
|
args += ["-i", "#{name}.#{partition}.ncch:#{partition}:#{partition}"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return args
|
return args
|
||||||
@ -60,18 +69,16 @@ def remove_cache
|
|||||||
Dir["*.ncch"].each do |fname| File.delete(fname) end
|
Dir["*.ncch"].each do |fname| File.delete(fname) end
|
||||||
end
|
end
|
||||||
|
|
||||||
args : String = ""
|
|
||||||
|
|
||||||
# 3ds decrypting
|
# 3ds decrypting
|
||||||
Dir["*.3ds"].each do |ds|
|
Dir["*.3ds"].each do |ds|
|
||||||
next if ds.includes? "decrypted"
|
next if ds.includes? "decrypted"
|
||||||
|
|
||||||
args = ""
|
|
||||||
i : UInt8 = 0
|
i : UInt8 = 0
|
||||||
dsn : String = ds.chomp ".3ds"
|
dsn : String = ds.chomp ".3ds"
|
||||||
|
args = ["-f", "cci", "-ignoresign", "-target", "p", "-o", "#{dsn}-decrypted.3ds"]
|
||||||
|
|
||||||
puts "Decrypting: #{ds.colorize.mode(:bold)}..."
|
puts "Decrypting: #{ds.colorize.mode(:bold)}..."
|
||||||
log.puts %x[./ctrdecrypt '#{ds}']
|
run_tool("ctrdecrypt", [ds])
|
||||||
|
|
||||||
Dir["#{dsn}.*.ncch"].each do |ncch|
|
Dir["#{dsn}.*.ncch"].each do |ncch|
|
||||||
case ncch
|
case ncch
|
||||||
@ -92,10 +99,10 @@ Dir["*.3ds"].each do |ds|
|
|||||||
when "#{dsn}.UpdateData.ncch"
|
when "#{dsn}.UpdateData.ncch"
|
||||||
i = 7
|
i = 7
|
||||||
end
|
end
|
||||||
args += "-i '#{ncch}:#{i}:#{i}' "
|
args += ["-i", "#{ncch}:#{i}:#{i}"]
|
||||||
end
|
end
|
||||||
puts "Building decrypted #{dsn} 3DS..."
|
puts "Building decrypted #{dsn} 3DS..."
|
||||||
log.puts %x[./makerom -f cci -ignoresign -target p -o '#{dsn}-decrypted.3ds' #{args}]
|
run_tool("makerom", args)
|
||||||
check_decrypt(dsn, "3ds")
|
check_decrypt(dsn, "3ds")
|
||||||
remove_cache
|
remove_cache
|
||||||
end
|
end
|
||||||
@ -106,39 +113,41 @@ Dir["*.cia"].each do |cia|
|
|||||||
|
|
||||||
puts "Decrypting: #{cia.colorize.mode(:bold)}..."
|
puts "Decrypting: #{cia.colorize.mode(:bold)}..."
|
||||||
cutn : String = cia.chomp ".cia"
|
cutn : String = cia.chomp ".cia"
|
||||||
args = ""
|
content = run_tool("ctrtool", ["--seeddb=seeddb.bin", cia])
|
||||||
content = %x[./ctrtool --seeddb=seeddb.bin '#{cia}']
|
|
||||||
|
|
||||||
# game
|
# game
|
||||||
if content.match /T.*d.*00040000/
|
if content.match /T.*d.*00040000/
|
||||||
puts "CIA Type: Game"
|
puts "CIA Type: Game"
|
||||||
log.puts %x[./ctrdecrypt '#{cia}']
|
run_tool("ctrdecrypt", [cia])
|
||||||
|
|
||||||
|
args = ["-f", "cia", "-ignoresign", "-target", "p", "-o", "#{cutn}-decfirst.cia"]
|
||||||
i : UInt8 = 0
|
i : UInt8 = 0
|
||||||
Dir["*.ncch"].sort.each do |ncch|
|
Dir["*.ncch"].sort.each do |ncch|
|
||||||
args += "-i '#{ncch}:#{i}:#{i}' "
|
args += ["-i", "#{ncch}:#{i}:#{i}"]
|
||||||
i += 1
|
i += 1
|
||||||
end
|
end
|
||||||
log.puts %x[./makerom -f cia -ignoresign -target p -o '#{cutn}-decfirst.cia' #{args}]
|
run_tool("makerom", args)
|
||||||
# patch
|
# patch
|
||||||
elsif content.match /T.*d.*0004000(e|E)/
|
elsif content.match /T.*d.*0004000(e|E)/
|
||||||
puts "CIA Type: #{"Patch".colorize.mode(:bold)}"
|
puts "CIA Type: #{"Patch".colorize.mode(:bold)}"
|
||||||
log.puts %x[./ctrdecrypt '#{cia}']
|
run_tool("ctrdecrypt", [cia])
|
||||||
|
|
||||||
|
args = ["-f", "cia", "-ignoresign", "-target", "p", "-o", "#{cutn} (Patch)-decrypted.cia"]
|
||||||
patch_parts : Int32 = Dir["#{cutn}.*.ncch"].size
|
patch_parts : Int32 = Dir["#{cutn}.*.ncch"].size
|
||||||
args = gen_args(cutn, patch_parts)
|
args += gen_args(cutn, patch_parts)
|
||||||
|
|
||||||
log.puts %x[./makerom -f cia -ignoresign -target p -o '#{cutn} (Patch)-decrypted.cia' #{args}]
|
run_tool("makerom", args)
|
||||||
check_decrypt("#{cutn} (Patch)", "cia")
|
check_decrypt("#{cutn} (Patch)", "cia")
|
||||||
# dlc
|
# dlc
|
||||||
elsif content.match /T.*d.*0004008(c|C)/
|
elsif content.match /T.*d.*0004008(c|C)/
|
||||||
puts "CIA Type: #{"DLC".colorize.mode(:bold)}"
|
puts "CIA Type: #{"DLC".colorize.mode(:bold)}"
|
||||||
log.puts %x[./ctrdecrypt '#{cia}']
|
run_tool("ctrdecrypt", [cia])
|
||||||
|
|
||||||
|
args = ["-f", "cia", "-dlc", "-ignoresign", "-target", "p", "-o", "#{cutn} (DLC)-decrypted.cia"]
|
||||||
dlc_parts : Int32 = Dir["#{cutn}.*.ncch"].size
|
dlc_parts : Int32 = Dir["#{cutn}.*.ncch"].size
|
||||||
args = gen_args(cutn, dlc_parts)
|
args += gen_args(cutn, dlc_parts)
|
||||||
|
|
||||||
log.puts %x[./makerom -f cia -dlc -ignoresign -target p -o '#{cutn} (DLC)-decrypted.cia' #{args}]
|
run_tool("makerom", args)
|
||||||
check_decrypt("#{cutn} (DLC)", "cia")
|
check_decrypt("#{cutn} (DLC)", "cia")
|
||||||
else
|
else
|
||||||
puts "Unsupported CIA"
|
puts "Unsupported CIA"
|
||||||
@ -148,13 +157,13 @@ Dir["*.cia"].each do |cia|
|
|||||||
cutn = decfirst.chomp "-decfirst.cia"
|
cutn = decfirst.chomp "-decfirst.cia"
|
||||||
|
|
||||||
puts "Building decrypted #{cutn} CCI..."
|
puts "Building decrypted #{cutn} CCI..."
|
||||||
log.puts %x[./makerom -ciatocci '#{decfirst}' -o '#{cutn}-decrypted.cci']
|
run_tool("makerom", ["-ciatocci", decfirst, "-o", "#{cutn}-decrypted.cci"])
|
||||||
check_decrypt(cutn, "cci")
|
check_decrypt(cutn, "cci")
|
||||||
end
|
end
|
||||||
|
|
||||||
remove_cache
|
remove_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
log.flush
|
LOG.flush
|
||||||
log.close
|
LOG.close
|
||||||
puts "Log saved"
|
puts "Log saved"
|
||||||
|
Loading…
Reference in New Issue
Block a user