diff --git a/ChovySign-GUI/Global/ProgressStatus.axaml.cs b/ChovySign-GUI/Global/ProgressStatus.axaml.cs index a993bbb..861e741 100644 --- a/ChovySign-GUI/Global/ProgressStatus.axaml.cs +++ b/ChovySign-GUI/Global/ProgressStatus.axaml.cs @@ -2,6 +2,7 @@ using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Threading; using ChovySign_GUI.Popup.Global; +using ChovySign_GUI.Settings; using Li.Progress; using LibChovy; using System; @@ -13,6 +14,8 @@ namespace ChovySign_GUI.Global public partial class ProgressStatus : UserControl { public ChovySignParameters? Parameters = null; + public event EventHandler? Finished; + public event EventHandler? BeforeStart; private ChovySign chovySign; public ProgressStatus() { @@ -21,14 +24,12 @@ namespace ChovySign_GUI.Global chovySign = new ChovySign(); chovySign.RegisterCallback(onProgress); } - public event EventHandler? BeforeStart; protected virtual void OnBeforeStart(EventArgs e) { if (BeforeStart is not null) BeforeStart(this, e); } - public event EventHandler? Finished; protected virtual void OnFinished(EventArgs e) { @@ -45,8 +46,10 @@ namespace ChovySign_GUI.Global this.goButton.IsEnabled = false; OnBeforeStart(new EventArgs()); - + // sanity check it if(Parameters is null) { await MessageBox.Show(currentWindow, "ChovySignParameters was null, cannot start!", "Invalid Parameters", MessageBoxButtons.Ok); return; } + // apply settings that are global to all signs + if(SettingsTab.Settings is not null) Parameters.BuildStreamType = SettingsTab.Settings.BuildStreamType; try { diff --git a/ChovySign-GUI/Settings/ConfigDropDown.axaml b/ChovySign-GUI/Settings/ConfigDropDown.axaml index fcfe461..c501a05 100644 --- a/ChovySign-GUI/Settings/ConfigDropDown.axaml +++ b/ChovySign-GUI/Settings/ConfigDropDown.axaml @@ -3,7 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Global="clr-namespace:ChovySign_GUI.Global" - mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="80" + mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="85" x:Class="ChovySign_GUI.Settings.ConfigDropDown"> diff --git a/ChovySign-GUI/Settings/SettingsTab.axaml b/ChovySign-GUI/Settings/SettingsTab.axaml index 68afd43..0443e12 100644 --- a/ChovySign-GUI/Settings/SettingsTab.axaml +++ b/ChovySign-GUI/Settings/SettingsTab.axaml @@ -17,6 +17,7 @@ + + + diff --git a/ChovySign-GUI/Settings/SettingsTab.axaml.cs b/ChovySign-GUI/Settings/SettingsTab.axaml.cs index 594db1e..8ef9846 100644 --- a/ChovySign-GUI/Settings/SettingsTab.axaml.cs +++ b/ChovySign-GUI/Settings/SettingsTab.axaml.cs @@ -1,5 +1,6 @@ using Avalonia.Controls; using GameBuilder.Pops.LibCrypt; +using GameBuilder; using System.IO; using Vita.ContentManager; @@ -9,6 +10,14 @@ namespace ChovySign_GUI.Settings { public static SettingsTab? Settings; + public StreamType BuildStreamType + { + get + { + return (StreamType) this.streamType.SelectedIndex; + } + } + public LibCryptMethod LibcryptMode { get @@ -51,10 +60,12 @@ namespace ChovySign_GUI.Settings InitializeComponent(); libCryptMode.Items = new string[2] { "Magic Word in ISO Header", "Sub Channel PGD" }; - + streamType.Items = new string[2] { "MemoryStream - Create EBOOT in memory, faster, but high memory usage", "FileStream - Create EBOOT with temporary files, slower, but less memory usage" }; + if (!Directory.Exists(this.CmaDirectory)) cmaDirectory.Value = SettingsReader.BackupsFolder; + Settings = this; } } diff --git a/GameBuilder/BuildStream.cs b/GameBuilder/BuildStream.cs new file mode 100644 index 0000000..f1603bd --- /dev/null +++ b/GameBuilder/BuildStream.cs @@ -0,0 +1,133 @@ +using DiscUtils.Streams; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GameBuilder +{ + public class BuildStream : Stream + { + public static StreamType BuildUsingStreamType = StreamType.TYPE_MEMORY_STREAM; + private Stream underylingStream; + + private StreamType uStreamType; + private string? filename = null; + + private void init() + { + this.uStreamType = BuildUsingStreamType; + if (this.uStreamType == StreamType.TYPE_MEMORY_STREAM) + { + this.underylingStream = new MemoryStream(); + } + else if (this.uStreamType == StreamType.TYPE_FILE_STREAM) + { + string tmpFolder = Path.Combine(Path.GetTempPath(), "chovysign2"); + Directory.CreateDirectory(tmpFolder); + + this.filename = Path.Combine(tmpFolder, Guid.NewGuid().ToString()); + this.underylingStream = File.Create(this.filename); + } + else + { + throw new Exception("unknown stream type"); + } + } + + public BuildStream(byte[] data) + { + init(); + this.Write(data, 0, data.Length); + this.Seek(0x00, SeekOrigin.Begin); + } + public BuildStream() + { + init(); + } + + public override bool CanRead { + get { + return underylingStream.CanRead; + } + } + + public override bool CanSeek { + get { + return underylingStream.CanSeek; + } + } + + public override bool CanWrite { + get { + return underylingStream.CanWrite; + } + } + + public override long Length { + get { + return underylingStream.Length; + } + } + + public override long Position { + get { + return underylingStream.Position; + } + set { + underylingStream.Position = value; + } + } + + public override void Close() + { + this.underylingStream.Close(); + + if(this.uStreamType == StreamType.TYPE_FILE_STREAM && this.filename is not null) + File.Delete(this.filename); + + base.Close(); + + } + + public override void Flush() + { + underylingStream.Flush(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + return underylingStream.Read(buffer, offset, count); + } + + public override long Seek(long offset, SeekOrigin origin) + { + return underylingStream.Seek(offset, origin); + } + + public override void SetLength(long value) + { + underylingStream.SetLength(value); + } + + public override void Write(byte[] buffer, int offset, int count) + { + underylingStream.Write(buffer, offset, count); + } + + public byte[] ToArray() + { + long oldLocation = this.Position; + + this.Seek(0x00, SeekOrigin.Begin); + + byte[] rdData = new byte[this.Length]; + this.Read(rdData, 0x00, rdData.Length); + + this.Seek(oldLocation, SeekOrigin.Begin); + + return rdData; + } + } +} diff --git a/GameBuilder/Cue/CueReader.cs b/GameBuilder/Cue/CueReader.cs index 6f5e1cf..6174628 100644 --- a/GameBuilder/Cue/CueReader.cs +++ b/GameBuilder/Cue/CueReader.cs @@ -269,7 +269,7 @@ namespace GameBuilder.Cue public byte[] CreateToc() { - using (MemoryStream toc = new MemoryStream()) + using (BuildStream toc = new BuildStream()) { StreamUtil tocUtil = new StreamUtil(toc); tocUtil.WriteBytes(createDummyTracks()); diff --git a/GameBuilder/Pops/DiscCompressor.cs b/GameBuilder/Pops/DiscCompressor.cs index dc98f24..cea1d0f 100644 --- a/GameBuilder/Pops/DiscCompressor.cs +++ b/GameBuilder/Pops/DiscCompressor.cs @@ -26,8 +26,8 @@ namespace GameBuilder.Pops this.disc = disc; this.cue = new CueReader(disc.CueFile); - this.IsoHeader = new MemoryStream(); - this.CompressedIso = new MemoryStream(); + this.IsoHeader = new BuildStream(); + this.CompressedIso = new BuildStream(); this.isoHeaderUtil = new StreamUtil(IsoHeader); this.atrac3Encoder = encoder; @@ -189,9 +189,9 @@ namespace GameBuilder.Pops writeCDAEntry(Convert.ToInt32(CompressedIso.Position), atracData.Length, key); - using (MemoryStream atracStream = new MemoryStream(atracData)) + using (BuildStream atracStream = new BuildStream(atracData)) { - using (MemoryStream encryptedAtracStream = new MemoryStream()) + using (BuildStream encryptedAtracStream = new BuildStream()) { AtracCrypto.ScrambleAtracData(atracStream, encryptedAtracStream, key); encryptedAtracStream.Seek(0x00, SeekOrigin.Begin); @@ -241,8 +241,8 @@ namespace GameBuilder.Pops private CueReader cue; private PopsImg srcImg; - public MemoryStream IsoHeader; - public MemoryStream CompressedIso; + public BuildStream IsoHeader; + public BuildStream CompressedIso; private StreamUtil isoHeaderUtil; private IAtracEncoderBase atrac3Encoder; diff --git a/GameBuilder/Pops/LibCrypt/SubChannel.cs b/GameBuilder/Pops/LibCrypt/SubChannel.cs index 2809517..24e7e28 100644 --- a/GameBuilder/Pops/LibCrypt/SubChannel.cs +++ b/GameBuilder/Pops/LibCrypt/SubChannel.cs @@ -12,7 +12,7 @@ namespace GameBuilder.Pops.LibCrypt { public static byte[] CreateSubchannelDat(int magicWord) { - using(MemoryStream subChannels = new MemoryStream()) + using(BuildStream subChannels = new BuildStream()) { StreamUtil subChannelsUtil = new StreamUtil(subChannels); // this header seems to mark the start of the sub channel data. diff --git a/GameBuilder/Pops/PopsImg.cs b/GameBuilder/Pops/PopsImg.cs index de30472..92a8a09 100644 --- a/GameBuilder/Pops/PopsImg.cs +++ b/GameBuilder/Pops/PopsImg.cs @@ -17,7 +17,7 @@ namespace GameBuilder.Pops public PopsImg(NpDrmInfo versionKey) : base(versionKey) { - simple = new MemoryStream(); + simple = new BuildStream(); simpleUtil = new StreamUtil(simple); this.StartDat = NpDrmPsar.CreateStartDat(Resources.STARTDATPOPS); @@ -86,7 +86,7 @@ namespace GameBuilder.Pops return loaderEnc.ToArray(); } - private MemoryStream simple; + private BuildStream simple; private StreamUtil simpleUtil; public byte[] EbootElf; diff --git a/GameBuilder/Pops/PsTitleImg.cs b/GameBuilder/Pops/PsTitleImg.cs index 932f4dc..2728991 100644 --- a/GameBuilder/Pops/PsTitleImg.cs +++ b/GameBuilder/Pops/PsTitleImg.cs @@ -50,10 +50,10 @@ namespace GameBuilder.Pops } - isoMap = new MemoryStream(); + isoMap = new BuildStream(); isoMapUtil = new StreamUtil(isoMap); - isoPart = new MemoryStream(); + isoPart = new BuildStream(); isoPartUtil = new StreamUtil(isoPart); @@ -174,10 +174,10 @@ namespace GameBuilder.Pops private PSInfo[] discs; private DiscCompressor[] compressors; - private MemoryStream isoPart; + private BuildStream isoPart; private StreamUtil isoPartUtil; - private MemoryStream isoMap; + private BuildStream isoMap; private StreamUtil isoMapUtil; } } diff --git a/GameBuilder/Psp/NpDrmPsar.cs b/GameBuilder/Psp/NpDrmPsar.cs index 2695ff7..726fd37 100644 --- a/GameBuilder/Psp/NpDrmPsar.cs +++ b/GameBuilder/Psp/NpDrmPsar.cs @@ -17,19 +17,19 @@ namespace GameBuilder.Psp { DrmInfo = npDrmInfo; - Psar = new MemoryStream(); + Psar = new BuildStream(); psarUtil = new StreamUtil(Psar); } public NpDrmInfo DrmInfo; - public MemoryStream Psar; + public BuildStream Psar; internal StreamUtil psarUtil; public abstract void CreatePsar(); public abstract byte[] GenerateDataPsp(); public static byte[] CreateStartDat(byte[] image) { - using(MemoryStream startDatStream = new MemoryStream()) + using(BuildStream startDatStream = new BuildStream()) { StreamUtil startDatUtil = new StreamUtil(startDatStream); diff --git a/GameBuilder/Psp/NpUmdImg.cs b/GameBuilder/Psp/NpUmdImg.cs index 1d78315..f248275 100644 --- a/GameBuilder/Psp/NpUmdImg.cs +++ b/GameBuilder/Psp/NpUmdImg.cs @@ -21,16 +21,16 @@ namespace GameBuilder.Psp { this.compress = compress; - this.npHdr = new MemoryStream(); + this.npHdr = new BuildStream(); this.npHdrUtil = new StreamUtil(npHdr); - this.npHdrBody = new MemoryStream(); + this.npHdrBody = new BuildStream(); this.npHdrBodyUtil = new StreamUtil(npHdrBody); - this.npTbl = new MemoryStream(); + this.npTbl = new BuildStream(); this.npTblUtil = new StreamUtil(npTbl); - this.isoData = new MemoryStream(); + this.isoData = new BuildStream(); this.isoDataUtil = new StreamUtil(isoData); this.headerKey = Rng.RandomBytes(0x10); @@ -101,7 +101,7 @@ namespace GameBuilder.Psp public override byte[] GenerateDataPsp() { byte[] startDat = CreateStartDat(umdImage.Minis ? Resources.STARTDATMINIS : Resources.STARTDATPSP); - using (MemoryStream dataPsp = new MemoryStream()) + using (BuildStream dataPsp = new BuildStream()) { StreamUtil dataPspUtil = new StreamUtil(dataPsp); byte[] signature = signParamSfo(umdImage.DataFiles["PARAM.SFO"]); @@ -288,16 +288,16 @@ namespace GameBuilder.Psp private byte[] dataKey; - private MemoryStream npHdr; + private BuildStream npHdr; private StreamUtil npHdrUtil; - private MemoryStream npHdrBody; + private BuildStream npHdrBody; private StreamUtil npHdrBodyUtil; - private MemoryStream isoData; + private BuildStream isoData; private StreamUtil isoDataUtil; - private MemoryStream npTbl; + private BuildStream npTbl; private StreamUtil npTblUtil; } } diff --git a/GameBuilder/Psp/PbpBuilder.cs b/GameBuilder/Psp/PbpBuilder.cs index 17aacc2..b2ca113 100644 --- a/GameBuilder/Psp/PbpBuilder.cs +++ b/GameBuilder/Psp/PbpBuilder.cs @@ -18,7 +18,7 @@ namespace GameBuilder.Psp private byte[]? snd0At3; private NpDrmPsar psar; private short pbpVersion; - private MemoryStream pbpStream; + private BuildStream pbpStream; public PbpBuilder(byte[] paramSfo, byte[] icon0Png, byte[]? icon1Pmf, byte[]? pic0Png, byte[]? pic1Png, byte[]? snd0At3, @@ -33,11 +33,11 @@ namespace GameBuilder.Psp this.psar = dataPsar; this.pbpVersion = version; - pbpStream = new MemoryStream(); + pbpStream = new BuildStream(); psar.RegisterCallback(onProgress); } - public MemoryStream PbpStream + public BuildStream PbpStream { get { diff --git a/GameBuilder/StreamType.cs b/GameBuilder/StreamType.cs new file mode 100644 index 0000000..a2c5acf --- /dev/null +++ b/GameBuilder/StreamType.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GameBuilder +{ + public enum StreamType : uint + { + TYPE_MEMORY_STREAM, + TYPE_FILE_STREAM + } +} diff --git a/LibChovy/ChovySign.cs b/LibChovy/ChovySign.cs index 2e09249..30c9f9b 100644 --- a/LibChovy/ChovySign.cs +++ b/LibChovy/ChovySign.cs @@ -1,4 +1,5 @@ -using GameBuilder.Pops; +using GameBuilder; +using GameBuilder.Pops; using GameBuilder.Psp; using Li.Progress; using PspCrypto; @@ -149,6 +150,8 @@ namespace LibChovy SceNpDrm.Aid = parameters.DrmRif.AccountId; + BuildStream.BuildUsingStreamType = parameters.BuildStreamType; + if (!Directory.Exists(parameters.OutputFolder)) Directory.CreateDirectory(parameters.OutputFolder); diff --git a/LibChovy/ChovySignParameters.cs b/LibChovy/ChovySignParameters.cs index 798bdc1..952f9df 100644 --- a/LibChovy/ChovySignParameters.cs +++ b/LibChovy/ChovySignParameters.cs @@ -1,4 +1,5 @@ -using GameBuilder.Psp; +using GameBuilder; +using GameBuilder.Psp; using LibChovy.Config; using System; using System.Collections.Generic; @@ -19,6 +20,7 @@ namespace LibChovy this.Account = new Account(DrmRif.AccountId); this.CreatePsvImg = true; this.FirmwareVersion = 0x3600000; + this.BuildStreamType = StreamType.TYPE_MEMORY_STREAM; } public int FirmwareVersion; @@ -27,7 +29,8 @@ namespace LibChovy public NpDrmRif DrmRif; public Account Account; public ChovyTypes Type; - + + public StreamType BuildStreamType; protected string? outputFolderOverride;