コード例 #1
0
 public static void AutoThemeFileUploaded(Uint8Array arr)
 {
     if (!ValidAutoThemeParts.ContainsStr(AutoThemePartName))
     {
         Window.Alert("An invalid part name has been selected");
         return;
     }
     DoActionWithloading(() =>
     {
         byte[] szs   = arr.ToArray();
         byte[] sarc  = ManagedYaz0.Decompress(szs);
         var szsData  = SARCExt.SARC.UnpackRamN(sarc);
         sarc         = null;
         var detected = SwitchThemesCommon.DetectSarc(szsData, DefaultTemplates.templates);
         if (detected == null)
         {
             Window.Alert("This is not a valid theme file, if it's from a newer firmware it's not compatible with this tool yet");
             return;
         }
         if (!detected.TemplateName.Contains(AutoThemePartName))
         {
             Window.Alert("This szs is valid but it doesn't look like the right one, you can keep it but it might generate themes that affect the wrong parts of the menu");
         }
         Window.LocalStorage.SetItem(AutoThemePartName, Convert.ToBase64String(szs));
         Window.LocalStorage.SetItem(AutoThemePartName + "Name", detected.TemplateName + " " + detected.FirmName);
         LoadAutoThemeState();
     });
 }
コード例 #2
0
ファイル: App.cs プロジェクト: kvm1st/SwitchThemeInjector
 public static void UploadSZS(Uint8Array arr)         //called from js
 {
     DoActionWithloading(() =>
     {
         byte[] sarc = ManagedYaz0.Decompress(arr.ToArray());
         CommonSzs   = SARCExt.SARC.UnpackRamN(sarc);
         sarc        = null;
         while (LayoutsComboBox.LastChild.TextContent != "Don't patch")
         {
             LayoutsComboBox.RemoveChild(LayoutsComboBox.LastChild);
         }
         targetPatch = SwitchThemesCommon.DetectSarc(CommonSzs, DefaultTemplates.templates);
         if (targetPatch == null)
         {
             Window.Alert("This is not a valid theme file, if it's from a newer firmware it's not compatible with this tool yet");
             CommonSzs               = null;
             targetPatch             = null;
             lblDetected.TextContent = "";
             return;
         }
         lblDetected.TextContent = "Detected " + targetPatch.TemplateName + " " + targetPatch.FirmName;
         for (int i = 0; i < layoutPatches.Length; i++)
         {
             if (layoutPatches[i] != null && layoutPatches[i].IsCompatible(CommonSzs))
             {
                 LayoutsComboBox.Add(new HTMLOptionElement()
                 {
                     TextContent = layoutPatches[i].ToString(), Value = i.ToString()
                 });
             }
         }
     });
 }
コード例 #3
0
        public Form1()
        {
            InitializeComponent();

            //LayoutPatch.CreateTestTemplates();
            //PatchTemplate.BuildTemplateFile();
            Templates.AddRange(DefaultTemplates.templates);
            if (File.Exists("ExtraTemplates.json"))
            {
                Templates.AddRange(PatchTemplate.LoadTemplates());
            }
            if (Directory.Exists("Layouts"))
            {
                foreach (var f in Directory.GetFiles("Layouts").Where(x => x.EndsWith(".json")))
                {
                    Layouts.Add(f, LayoutPatch.LoadTemplate(File.ReadAllText(f)));
                }
            }

            HomeMenuPartBox.Items.AddRange(HomeMenuParts.Keys.ToArray());
            HomeMenuPartBox.SelectedIndex = 0;
            HomeMenuPartBox_SelectedIndexChanged(null, null);

            LoadFileText   = SwitchThemesCommon.GeneratePatchListString(Templates);
            tbPatches.Text = "(To dump the following files check the guide at https://git.io/fxdyF )\r\n" + LoadFileText;
        }
コード例 #4
0
        public Form1()
        {
            InitializeComponent();
            PatchLabelText = materialLabel3.Text;

            //LayoutPatch.CreateTestTemplates();
            //PatchTemplate.BuildTemplateFile();
            Templates.AddRange(DefaultTemplates.templates);
            if (File.Exists("ExtraTemplates.json"))
            {
                Templates.AddRange(PatchTemplate.LoadTemplates());
            }
            if (Directory.Exists("Layouts"))
            {
                foreach (var f in Directory.GetFiles("Layouts").Where(x => x.EndsWith(".json")))
                {
                    Layouts.Add(f, LayoutPatch.LoadTemplate(File.ReadAllText(f)));
                }
            }

            LoadFileText   = SwitchThemesCommon.GeneratePatchListString(Templates);
            tbPatches.Text = "(To dump the following files check the guide at https://git.io/fxdyF )\r\n" + LoadFileText;

            if (!File.Exists("hactool\\hactool.exe") || !File.Exists("hactool\\keys.dat"))
            {
                materialTabControl1.TabPages.Remove(NCADumpPage);
            }
        }
コード例 #5
0
        public Form1()
        {
            MaterialSkin.MaterialSkinManager.Instance.Theme = MaterialSkin.MaterialSkinManager.Themes.DARK;
            InitializeComponent();

            //LayoutPatch.CreateTestTemplates();
            //PatchTemplate.BuildTemplateFile();
            Templates.AddRange(DefaultTemplates.templates);
            if (File.Exists("ExtraTemplates.json"))
            {
                Templates.AddRange(PatchTemplate.LoadTemplates());
            }
            if (Directory.Exists("Layouts"))
            {
                foreach (var f in Directory.GetFiles("Layouts").Where(x => x.EndsWith(".json")))
                {
                    Layouts.Add(f, LayoutPatch.LoadTemplate(File.ReadAllText(f)));
                }
            }

            HomeMenuPartBox.Items.AddRange(HomeMenuParts.Keys.ToArray());
            HomeMenuPartBox.SelectedIndex = 0;
            HomeMenuPartBox_SelectedIndexChanged(null, null);

            LoadFileText    = SwitchThemesCommon.GeneratePatchListString(Templates);
            tbPatches.Text += LoadFileText;
        }
コード例 #6
0
        private void NnBuilderBuild_Click(object sender, EventArgs e)
        {
            if (tbBntxFile.Text.Trim() == "")
            {
                MessageBox.Show("Select an image first");
                return;
            }
            if (!tbBntxFile.Text.EndsWith(".dds") && !ImageToDDS())
            {
                return;
            }
            var info = ThemeInputInfo.Ask();

            if (info == null)
            {
                return;
            }

            byte[] preview = null;
            if (info.Item3)
            {
                preview = GenerateDDSPreview(tbBntxFile.Text);
            }

            LayoutPatch layout = null;

            if (AllLayoutsBox.SelectedIndex != 0)
            {
                layout = AllLayoutsBox.SelectedItem as LayoutPatch;
            }
            var res = SwitchThemesCommon.GenerateNXTheme(
                new ThemeFileManifest()
            {
                Version    = 3,
                ThemeName  = info.Item1,
                Author     = info.Item2,
                Target     = HomeMenuParts[HomeMenuPartBox.Text],
                LayoutInfo = layout == null ? "" : layout.PatchName + " by " + layout.AuthorName,
            },
                File.ReadAllBytes(tbBntxFile.Text),
                layout?.AsByteArray(),
                new Tuple <string, byte[]> ("preview.png", preview),
                HomeMenuParts[HomeMenuPartBox.Text] == "home" ? new Tuple <string, byte[]>("common.json", ExtraCommonLyt?.AsByteArray()) : null);

            SaveFileDialog sav = new SaveFileDialog()
            {
                Filter = "theme pack (*.nxtheme)|*.nxtheme"
            };

            if (sav.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            File.WriteAllBytes(sav.FileName, res);
            MessageBox.Show("Done");
        }
コード例 #7
0
        private void OpenSzsButton(object sender, EventArgs e)
        {
            OpenFileDialog opn = new OpenFileDialog()
            {
                Title  = "open szs",
                Filter = "szs file|*.szs|all files|*.*",
            };

            if (opn.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            if (!File.Exists(opn.FileName))
            {
                MessageBox.Show("Could not open file");
                return;
            }

            targetPatch = null;
            LayoutPatchList.Items.Clear();
            LayoutPatchList.Items.Add("Don't patch");

            CommonSzs   = SARCExt.SARC.UnpackRamN(ManagedYaz0.Decompress(File.ReadAllBytes(opn.FileName)));
            targetPatch = SwitchThemesCommon.DetectSarc(CommonSzs, Templates);

            if (targetPatch == null)
            {
                if (Advanced)
                {
                    AdvancedUpdate();
                    lblDetected.Text = "Unknown szs file";
                    return;
                }

                MessageBox.Show("This is not a valid theme file, if it's from a newer firmware it's not compatible with this tool yet");
                CommonSzs        = null;
                targetPatch      = null;
                lblDetected.Text = "";
                return;
            }

            AdvancedUpdate();
            lblDetected.Text = "Detected " + targetPatch.TemplateName + " " + targetPatch.FirmName;

            foreach (var l in Layouts.Values)
            {
                if (l.IsCompatible(CommonSzs))
                {
                    LayoutPatchList.Items.Add(l);
                }
            }
            LayoutPatchList.Items.Add("Open from file...");
            LayoutPatchList.SelectedIndex = 0;
        }
コード例 #8
0
ファイル: App.cs プロジェクト: kvm1st/SwitchThemeInjector
        public static byte[] Make(SarcData input, DDSLoadResult dds, PatchTemplate targetPatch, LayoutPatch layout)
        {
            if (layout != null)
            {
                var layoutres = SwitchThemesCommon.PatchLayouts(input, layout.Files);
                if (layoutres == BflytFile.PatchResult.Fail)
                {
                    Window.Alert("One of the target files for the selected layout patch is missing in the SZS, you are probably using an already patched SZS or the wrong layout");
                    return(null);
                }
                else if (layoutres == BflytFile.PatchResult.CorruptedFile)
                {
                    Window.Alert("A layout in this SZS is missing a pane required for the selected layout patch, you are probably using an already patched SZS or the wrong layout");
                    return(null);
                }
            }

            if (SwitchThemesCommon.PatchBntx(input, dds, targetPatch) == BflytFile.PatchResult.Fail)
            {
                Window.Alert(
                    "Can't build this theme: the szs you opened doesn't contain some information needed to patch the bntx," +
                    "without this information it is not possible to rebuild the bntx." +
                    "You should use an original or at least working szs");
                return(null);
            }
            var res = SwitchThemesCommon.PatchBgLayouts(input, targetPatch);

            if (res == BflytFile.PatchResult.Fail)
            {
                Window.Alert("Couldn't patch this file, it might have been already modified or it's from an unsupported system version.");
                return(null);
            }
            else if (res == BflytFile.PatchResult.CorruptedFile)
            {
                Window.Alert("This file has been already patched with another tool and is not compatible, you should get an unmodified layout.");
                return(null);
            }
            var sarc = SARC.PackN(input);

            return(ManagedYaz0.Compress(sarc.Item2, 1, (int)sarc.Item1));
        }
コード例 #9
0
ファイル: App.cs プロジェクト: kvm1st/SwitchThemeInjector
        static void MakeNxTheme(string partName, string name, string author, LayoutPatch targetLayout)
        {
            if (LoadedDDS == null)
            {
                Window.Alert("Open a DDS first !");
                return;
            }
            if (!ValidAutoThemeParts.Contains(partName))
            {
                Window.Alert("select a valid Home menu part");
                return;
            }
            if (name.Trim() == "")
            {
                Window.Alert("Enter a valid name");
                return;
            }
            DoActionWithloading(() =>
            {
                var dds = DDSEncoder.LoadDDS(LoadedDDS);                 //this will crash if the dds type is wrong

                var meta = new ThemeFileManifest()
                {
                    Version    = 1,
                    Author     = author,
                    LayoutInfo = targetLayout != null ? targetLayout.ToString() : "",
                    ThemeName  = name,
                    Target     = partName,
                };

                var res              = SwitchThemesCommon.GenerateNXTheme(meta, LoadedDDS, targetLayout == null ? null : System.Text.Encoding.UTF8.GetBytes(targetLayout.AsJson()));
                Uint8Array dwn       = new Uint8Array(res);
                string DownloadFname = name + ".nxtheme";
                Script.Write("downloadBlob(dwn,DownloadFname,'application/octet-stream');");
            });
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: kvm1st/SwitchThemeInjector
        static bool SZSFromArgs(string[] args)
        {
            string GetArg(string start)
            {
                var a = args.Where(x => x.StartsWith(start + "=")).FirstOrDefault();

                if (a == null)
                {
                    return(null);
                }
                else
                {
                    return(a.Split('=')[1]);
                }
            }

            if (args.Length < 2)
            {
                return(false);
            }

            string Target      = args[1];
            var    CommonSzs   = SARCExt.SARC.UnpackRamN(ManagedYaz0.Decompress(File.ReadAllBytes(Target)));
            var    targetPatch = SwitchThemesCommon.DetectSarc(CommonSzs, DefaultTemplates.templates);

            if (targetPatch == null)
            {
                Console.WriteLine("Unknown szs file");
                return(false);
            }

            string Image = args.Where(x => x.EndsWith(".dds") || x.EndsWith(".jpg") || x.EndsWith(".png") || x.EndsWith("jpeg")).FirstOrDefault();

            if (Image == null || !File.Exists(Image))
            {
                Console.WriteLine("No image file !");
                return(false);
            }
            string Layout = args.Where(x => x.EndsWith(".json")).FirstOrDefault();

            string Output = GetArg("out");

            if (Output == null || Output == "")
            {
                return(false);
            }

            if (!Image.EndsWith(".dds"))
            {
                if (Form1.ImageToDDS(Image, Path.GetTempPath()))
                {
                    Image = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(Image) + ".dds");
                }
                else
                {
                    return(false);
                }
            }

            string album = GetArg("ablum");

            if (album != null && !album.EndsWith(".dds"))
            {
                if (Form1.ImageToDDS(album, Path.GetTempPath(), "DXT5", true))
                {
                    album = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(album) + ".dds");
                }
                else
                {
                    return(false);
                }
            }

            try
            {
                var res = BflytFile.PatchResult.OK;

                if (Image != null)
                {
                    if (SwitchThemesCommon.PatchBntx(CommonSzs, File.ReadAllBytes(Image), targetPatch) == BflytFile.PatchResult.Fail)
                    {
                        Console.WriteLine(
                            "Can't build this theme: the szs you opened doesn't contain some information needed to patch the bntx," +
                            "without this information it is not possible to rebuild the bntx." +
                            "You should use an original or at least working szs", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return(false);
                    }
                }

                if (album != null && targetPatch.szsName == "ResidentMenu.szs")
                {
                    SwitchThemesCommon.PatchBntxTexture(CommonSzs, File.ReadAllBytes(album), "RdtIcoPvr_00^s", 0x02000000);
                }

                res = SwitchThemesCommon.PatchBgLayouts(CommonSzs, targetPatch);

                if (res == BflytFile.PatchResult.Fail)
                {
                    Console.WriteLine("Couldn't patch this file, it might have been already modified or it's from an unsupported system version.");
                    return(false);
                }
                else if (res == BflytFile.PatchResult.CorruptedFile)
                {
                    Console.WriteLine("This file has been already patched with another tool and is not compatible, you should get an unmodified layout.");
                    return(false);
                }

                if (Layout != null)
                {
                    var layoutres = SwitchThemesCommon.PatchLayouts(CommonSzs, LayoutPatch.LoadTemplate(File.ReadAllText(Layout)), targetPatch.NXThemeName == "home", true);
                    if (layoutres == BflytFile.PatchResult.Fail)
                    {
                        Console.WriteLine("One of the target files for the selected layout patch is missing in the SZS, you are probably using an already patched SZS");
                        return(false);
                    }
                    else if (layoutres == BflytFile.PatchResult.CorruptedFile)
                    {
                        Console.WriteLine("A layout in this SZS is missing a pane required for the selected layout patch, you are probably using an already patched SZS");
                        return(false);
                    }
                }

                var sarc = SARC.PackN(CommonSzs);

                File.WriteAllBytes(Output, ManagedYaz0.Compress(sarc.Item2, 3, (int)sarc.Item1));
                GC.Collect();

                if (res == BflytFile.PatchResult.AlreadyPatched)
                {
                    Console.WriteLine("Done, This file has already been patched before.\r\nIf you have issues try with an unmodified file");
                }
                else
                {
                    Console.WriteLine("Done");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: " + ex.Message);
            }

            return(true);
        }
コード例 #11
0
        private void NnBuilderBuild_Click(object sender, EventArgs e)
        {
            if (tbBntxFile.Text.Trim() == "")
            {
                if (AllLayoutsBox.SelectedIndex == 0)
                {
                    MessageBox.Show("You need at least a custom image or layout to make a theme.");
                    return;
                }

                if (MessageBox.Show("This will create a theme without any background image, the console default one will be used. Do you want to continue ?", "", MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    return;
                }
            }

            if (!BgImageCheck(false))
            {
                return;
            }

            var info = ThemeInputInfo.Ask();

            if (info == null)
            {
                return;
            }

            byte[] preview = null;
            if (info.Item3 && tbBntxFile.Text.Trim() != "")
            {
                preview = GenerateDDSPreview(tbBntxFile.Text);
            }

            if (AlbumIcon != null && !AlbumIcon.EndsWith(".dds") && !AlbumIcontoDDS())
            {
                return;
            }

            LayoutPatch layout = null;

            if (AllLayoutsBox.SelectedIndex != 0)
            {
                layout = AllLayoutsBox.SelectedItem as LayoutPatch;
            }
            try
            {
                var res = SwitchThemesCommon.GenerateNXTheme(
                    new ThemeFileManifest()
                {
                    Version    = 6,
                    ThemeName  = info.Item1,
                    Author     = info.Item2,
                    Target     = HomeMenuParts[HomeMenuPartBox.Text],
                    LayoutInfo = layout == null ? "" : layout.PatchName + " by " + layout.AuthorName,
                },
                    tbBntxFile.Text != "" ? File.ReadAllBytes(tbBntxFile.Text) : null,
                    layout?.AsByteArray(),
                    new Tuple <string, byte[]>("preview.png", preview),
                    new Tuple <string, byte[]>("common.json", ExtraCommonLyt?.AsByteArray()),
                    new Tuple <string, byte[]>("album.dds", AlbumIcon != null ? File.ReadAllBytes(AlbumIcon) : null));

                SaveFileDialog sav = new SaveFileDialog()
                {
                    Filter = "theme pack (*.nxtheme)|*.nxtheme"
                };
                if (sav.ShowDialog() != DialogResult.OK)
                {
                    return;
                }
                File.WriteAllBytes(sav.FileName, res);
                MessageBox.Show("Done");
            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR: " + ex.Message);
            }
        }
コード例 #12
0
        static void DoAutoTheme(string type, string url, string layout)
        {
            cardLoad = Document.GetElementById <HTMLDivElement>("CardLoad");
            Document.GetElementById <HTMLDivElement>("CardTutorial").Hidden = true;
            string themeTarget = "<br/><br/>This theme is an nxtheme, download NXThemes Installer to install it on your switch.";

            cardLoad.InnerHTML = "Wait while your theme is being generated.... " + themeTarget;
            cardLoad.Hidden    = false;
            StartLoading();

            byte[]      DDS;
            LayoutPatch targetLayout = null;

            void BuildTheme()
            {
                var urlSplit = url.Split("/");
                var meta     = new ThemeFileManifest()
                {
                    Version    = 1,
                    Author     = "Auto-Theme",
                    LayoutInfo = targetLayout != null?targetLayout.ToString() : "",
                                     ThemeName = urlSplit[urlSplit.Length - 1],
                                     Target    = type
                };

                var res = SwitchThemesCommon.GenerateNXTheme(meta, DDS, targetLayout == null ? null : targetLayout.AsJson());

                if (res == null)
                {
                    endWithError("GenerateNXTheme() failed :(");
                    return;
                }
                Uint8Array dwn           = new Uint8Array(res);
                string     DownloadFname = urlSplit[urlSplit.Length - 1] + ".nxtheme";

                Script.Write("downloadBlob(dwn,DownloadFname,'application/octet-stream');");
                Document.GetElementById <HTMLDivElement>("CardLoad").InnerHTML = "Your theme has been generated !" + themeTarget;
                EndLoading();
            }

            void DDSDownloaded(Uint8Array arr)
            {
                DDS = arr.ToArray();

                if (layout == null)
                {
                    BuildTheme();
                }
                else
                {
                    HttpRequest(layout, LayoutDownloaded, "Layout");
                }
            }

            void LayoutDownloaded(string req)
            {
                targetLayout = LayoutPatch.LoadTemplate(req);
                BuildTheme();
            }

            HttpRequest(url, DDSDownloaded, "DDS");
        }
コード例 #13
0
        private void materialRaisedButton8_Click(object sender, EventArgs e)
        {
            if (CommonSzs == null || targetPatch == null)
            {
                MessageBox.Show("Open a valid theme first !");
                return;
            }
            if (tbBntxFile.Text.Trim() == "")
            {
                MessageBox.Show("Select an image first");
                return;
            }

            if (!BgImageCheck(false))
            {
                return;
            }

            var info = ThemeInputInfo.Ask();

            if (info == null)
            {
                return;
            }

            byte[] preview = null;
            if (info.Item3)
            {
                preview = GenerateDDSPreview(tbBntxFile.Text);
            }

            LayoutPatch layout = null;

            if (LayoutPatchList.SelectedIndex != 0)
            {
                layout = LayoutPatchList.SelectedItem as LayoutPatch;
            }
            try
            {
                var res = SwitchThemesCommon.GenerateNXTheme(
                    new ThemeFileManifest()
                {
                    Version    = 6,
                    ThemeName  = info.Item1,
                    Author     = info.Item2,
                    Target     = targetPatch.NXThemeName,
                    LayoutInfo = layout == null ? "" : layout.PatchName + " by " + layout.AuthorName,
                },
                    File.ReadAllBytes(tbBntxFile.Text),
                    layout?.AsByteArray(),
                    new Tuple <string, byte[]>("preview.png", preview));

                SaveFileDialog sav = new SaveFileDialog()
                {
                    Filter = "theme pack (*.nxtheme)|*.nxtheme"
                };
                if (sav.ShowDialog() != DialogResult.OK)
                {
                    return;
                }
                File.WriteAllBytes(sav.FileName, res);
                MessageBox.Show("Done");
            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR: " + ex.Message);
            }
        }
コード例 #14
0
        private void PatchButtonClick(object sender, EventArgs e)
        {
            if (CommonSzs == null || targetPatch == null)
            {
                MessageBox.Show("Open a valid theme first !");
                return;
            }
            if (tbBntxFile.Text.Trim() == "")
            {
                if (LayoutPatchList.SelectedIndex <= 0)
                {
                    MessageBox.Show("There is nothing to patch");
                    return;
                }
                if (MessageBox.Show("Are you sure you want to continue without selecting a bntx ?", "", MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    return;
                }
            }
            else if (!File.Exists(tbBntxFile.Text))
            {
                MessageBox.Show($"{tbBntxFile.Text} not found !");
                return;
            }

            SaveFileDialog sav = new SaveFileDialog()
            {
                Filter   = "szs file|*.szs",
                FileName = targetPatch.szsName
            };

            if (sav.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            var res = BflytFile.PatchResult.OK;

            if (tbBntxFile.Text.Trim() != "")
            {
                if (!BgImageCheck(true))
                {
                    return;
                }

                if (SwitchThemesCommon.PatchBntx(CommonSzs, File.ReadAllBytes(tbBntxFile.Text), targetPatch) == BflytFile.PatchResult.Fail)
                {
                    MessageBox.Show(
                        "Can't build this theme: the szs you opened doesn't contain some information needed to patch the bntx," +
                        "without this information it is not possible to rebuild the bntx." +
                        "You should use an original or at least working szs", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (targetPatch.NXThemeName == "home" && AlbumIcon != null)
                {
                    if (!AlbumIcon.EndsWith(".dds") && !AlbumIcontoDDS())
                    {
                        return;
                    }
                    SwitchThemesCommon.PatchBntxTexture(CommonSzs, File.ReadAllBytes(AlbumIcon), "RdtIcoPvr_00^s", 0x02000000);
                }

                res = SwitchThemesCommon.PatchBgLayouts(CommonSzs, targetPatch);

                if (res == BflytFile.PatchResult.Fail)
                {
                    MessageBox.Show("Couldn't patch this file, it might have been already modified or it's from an unsupported system version.");
                    return;
                }
                else if (res == BflytFile.PatchResult.CorruptedFile)
                {
                    MessageBox.Show("This file has been already patched with another tool and is not compatible, you should get an unmodified layout.");
                    return;
                }
            }

            if (LayoutPatchList.SelectedIndex != 0)
            {
                var layoutres = SwitchThemesCommon.PatchLayouts(CommonSzs, LayoutPatchList.SelectedItem as LayoutPatch, targetPatch.NXThemeName == "home", !UseAnim.Checked);
                if (layoutres == BflytFile.PatchResult.Fail)
                {
                    MessageBox.Show("One of the target files for the selected layout patch is missing in the SZS, you are probably using an already patched SZS");
                    return;
                }
                else if (layoutres == BflytFile.PatchResult.CorruptedFile)
                {
                    MessageBox.Show("A layout in this SZS is missing a pane required for the selected layout patch, you are probably using an already patched SZS");
                    return;
                }
                layoutres = SwitchThemesCommon.PatchAnimations(CommonSzs, (LayoutPatchList.SelectedItem as LayoutPatch).Anims);
                if (layoutres != BflytFile.PatchResult.OK)
                {
                    MessageBox.Show("Error while patching the animations !");
                    return;
                }
            }

            var sarc = SARC.PackN(CommonSzs);

            File.WriteAllBytes(sav.FileName, ManagedYaz0.Compress(sarc.Item2, 3, (int)sarc.Item1));
            GC.Collect();

            if (res == BflytFile.PatchResult.AlreadyPatched)
            {
                MessageBox.Show("Done, This file has already been patched before.\r\nIf you have issues try with an unmodified file");
            }
            else
            {
                MessageBox.Show("Done");
            }
        }
コード例 #15
0
        static void DoAutoTheme(string type, string url, string layout)
        {
            cardLoad = Document.GetElementById <HTMLDivElement>("CardLoad");
            Document.GetElementById <HTMLDivElement>("CardTutorial").Hidden = true;
            string themeTarget = "<br/><br/>This theme is for " + Window.LocalStorage.GetItem(type + "Name") as string + "<br/>To change the target version upload another szs for Auto-Theme on the <a href=\"index.html\">Home page</a>";

            cardLoad.InnerHTML = "Wait while your theme is being generated.... " + themeTarget;
            cardLoad.Hidden    = false;
            StartLoading();

            DDSEncoder.DDSLoadResult LoadedDDS;
            SarcData      CommonSzs;
            PatchTemplate targetPatch;
            LayoutPatch   targetLayout = null;

            void BuildTheme()
            {
                var yaz0 = Theme.Make(CommonSzs, LoadedDDS, targetPatch, targetLayout);

                if (yaz0 == null)
                {
                    endWithError("Theme.Make() failed :(");
                    return;
                }
                Uint8Array dwn           = new Uint8Array(yaz0);
                string     DownloadFname = targetPatch.szsName;

                Script.Write("downloadBlob(dwn,DownloadFname,'application/octet-stream');");
                Document.GetElementById <HTMLDivElement>("CardLoad").InnerHTML = "Your theme has been generated !" + themeTarget;
                EndLoading();
            }

            void DDSDownloaded(Uint8Array arr)
            {
                LoadedDDS = DDSEncoder.LoadDDS(arr.ToArray());
                arr       = null;
                CommonSzs = SARC.UnpackRamN(
                    ManagedYaz0.Decompress(
                        Convert.FromBase64String(
                            Window.LocalStorage.GetItem(type) as string)));

                targetPatch = SwitchThemesCommon.DetectSarc(CommonSzs, DefaultTemplates.templates);

                if (layout == null)
                {
                    BuildTheme();
                }
                else
                {
                    HttpRequest(layout, LayoutDownloaded, "Layout");
                }
            }

            void LayoutDownloaded(string req)
            {
                targetLayout = LayoutPatch.LoadTemplate(req);
                BuildTheme();
            }

            HttpRequest(url, DDSDownloaded, "DDS");
        }
コード例 #16
0
ファイル: App.cs プロジェクト: kvm1st/SwitchThemeInjector
        public static void OnLoad()
        {
#if DEBUG
            Document.GetElementById <HTMLDivElement>("DebugFlag").Hidden = false;
#endif
            topError        = Document.GetElementById <HTMLDivElement>("D_JsWarn");
            topError.Hidden = true;
            Document.GetElementById <HTMLParagraphElement>("P_Version").TextContent = "Switch theme injector online - Version : " + AppVersion + " - Core version : " + SwitchThemesCommon.CoreVer;
            string useragent = Window.Navigator.UserAgent.ToLower();
            if (useragent.Contains("msie") || useragent.Contains("trident"))
            {
                Document.GetElementById <HTMLDivElement>("D_IeWarn").Hidden = false;
            }

            loader          = Document.GetElementById <HTMLDivElement>("loaderDiv");
            LoaderText      = Document.GetElementById <HTMLParagraphElement>("LoadingText");
            lblDetected     = Document.GetElementById <HTMLParagraphElement>("P_DetectedSZS");
            lblDDSPath      = Document.GetElementById <HTMLParagraphElement>("P_DDSPath");
            lblDDSPath_NX   = Document.GetElementById <HTMLParagraphElement>("P_DDSPath2");
            LayoutsComboBox = Document.GetElementById <HTMLSelectElement>("LayoutsBox");
            LayoutPrevDiv   = Document.GetElementById <HTMLDivElement>("PreviewDiv");
            LayoutPrevImg   = Document.GetElementById <HTMLImageElement>("PreviewImg");

            HomePartBox_NX     = Document.GetElementById <HTMLSelectElement>("HomePartBox");
            LayoutsComboBox_NX = Document.GetElementById <HTMLSelectElement>("LayoutsBox2");
            LayoutPrevDiv_NX   = Document.GetElementById <HTMLDivElement>("PreviewDiv2");
            LayoutPrevImg_NX   = Document.GetElementById <HTMLImageElement>("PreviewImg2");

            Document.GetElementById <HTMLParagraphElement>("P_PatchList").InnerHTML = SwitchThemesCommon.GeneratePatchListString(DefaultTemplates.templates).Replace("\r\n", "<br />");

            LoadCustomLayouts();
        }
コード例 #17
0
        static bool NXThemeFromArgs(string[] args)
        {
            if (args.Length < 4)
            {
                return(false);
            }
            string Target = args[1];

            if (!Form1.HomeMenuParts.Values.Contains(Target))
            {
                return(false);
            }

            string Image = args.Where(x => x.EndsWith(".dds") || x.EndsWith(".jpg") || x.EndsWith(".png") || x.EndsWith("jpeg")).FirstOrDefault();

            if (Image == null || !File.Exists(Image))
            {
                Console.WriteLine("No image file !");
                return(false);
            }
            string Layout = args.Where(x => x.EndsWith(".json")).FirstOrDefault();

            string GetArg(string start)
            {
                var a = args.Where(x => x.StartsWith(start + "=")).FirstOrDefault();

                if (a == null)
                {
                    return(null);
                }
                else
                {
                    return(a.Split('=')[1]);
                }
            }

            bool?GetArgBool(string start)
            {
                var a = GetArg(start);

                if (a == null)
                {
                    return(null);
                }
                else
                {
                    return(bool.Parse(a));
                }
            }

            string Name        = GetArg("name");
            string Author      = GetArg("author");
            string Output      = GetArg("out");
            string ExtraCommon = GetArg("commonlyt");

            if (Output == null || Output == "")
            {
                return(false);
            }

            bool preview = GetArgBool("preview") ?? true;

            if (Name == null || Name.Trim() == "")
            {
                var info = ThemeInputInfo.Ask();
                Name    = info.Item1;
                Author  = info.Item2;
                preview = info.Item3;
            }

            LayoutPatch layout = null;

            if (Layout != null && File.Exists(Layout))
            {
                layout = LayoutPatch.LoadTemplate(File.ReadAllText(Layout));
            }

            if (!Image.EndsWith(".dds"))
            {
                if (Form1.ImageToDDS(Image, Path.GetTempPath()))
                {
                    Image = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(Image) + ".dds");
                }
                else
                {
                    return(false);
                }
            }

            var res = SwitchThemesCommon.GenerateNXTheme(
                new ThemeFileManifest()
            {
                Version    = 3,
                ThemeName  = Name,
                Author     = Author,
                Target     = Target,
                LayoutInfo = layout == null ? "" : layout.PatchName + " by " + layout.AuthorName,
            },
                File.ReadAllBytes(Image),
                layout?.AsByteArray(),
                new Tuple <string, byte[]>("preview.png", preview ? Form1.GenerateDDSPreview(Image) : null));

            File.WriteAllBytes(Output, res);

            return(true);
        }
コード例 #18
0
        public static LayoutPatch Diff(SarcData original, SarcData edited)
        {
            List <LayoutFilePatch> Patches = new List <LayoutFilePatch>();

            if (!ScrambledEquals <string>(original.Files.Keys, edited.Files.Keys))
            {
                MessageBox.Show("The provided archives don't have the same files");
                return(null);
            }
            var    targetPatch    = SwitchThemesCommon.DetectSarc(original, DefaultTemplates.templates);
            string skipLayoutName = targetPatch != null ? targetPatch.MainLayoutName : "";

            foreach (var f in original.Files.Keys.Where(x => x.EndsWith(".bflyt")))
            {
                if (original.Files[f].SequenceEqual(edited.Files[f]))
                {
                    continue;
                }
                BflytFile        or          = new BflytFile(original.Files[f]);
                BflytFile        ed          = new BflytFile(edited.Files[f]);
                string[]         orPaneNames = or.GetPaneNames();
                string[]         edPaneNames = ed.GetPaneNames();
                List <PanePatch> curFile     = new List <PanePatch>();
                for (int i = 0; i < edPaneNames.Length; i++)
                {
                    if (ed[i].data.Length < 0x4C || IgnorePaneList.Contains(ed[i].name))
                    {
                        continue;
                    }
                    if (f == skipLayoutName && (targetPatch?.targetPanels?.Contains(edPaneNames[i]) ?? false))
                    {
                        continue;
                    }
                    var j = Array.IndexOf(orPaneNames, edPaneNames[i]);
                    if (j == -1)
                    {
                        continue;
                    }
                    if (ed[i].data.SequenceEqual(or[j].data))
                    {
                        continue;
                    }
                    PanePatch curPatch = new PanePatch()
                    {
                        PaneName = edPaneNames[i]
                    };
                    var orPan = new BflytFile.PropertyEditablePanel(or[j]);
                    var edPan = new BflytFile.PropertyEditablePanel(ed[i]);
                    if (!VecEqual(edPan.Position, orPan.Position))
                    {
                        curPatch.Position = ToNullVec(edPan.Position);
                    }
                    if (!VecEqual(edPan.Rotation, orPan.Rotation))
                    {
                        curPatch.Rotation = ToNullVec(edPan.Rotation);
                    }
                    if (!VecEqual(edPan.Scale, orPan.Scale))
                    {
                        curPatch.Scale = ToNullVec(edPan.Scale);
                    }
                    if (!VecEqual(edPan.Size, orPan.Size))
                    {
                        curPatch.Size = ToNullVec(edPan.Size);
                    }
                    if (edPan.Visible != orPan.Visible)
                    {
                        curPatch.Visible = edPan.Visible;
                    }
                    if (edPan.name == "pic1")
                    {
                        if (edPan.ColorData[0] != orPan.ColorData[0])
                        {
                            curPatch.ColorTL = edPan.ColorData[0].ToString("X");
                        }
                        if (edPan.ColorData[1] != orPan.ColorData[1])
                        {
                            curPatch.ColorTR = edPan.ColorData[1].ToString("X");
                        }
                        if (edPan.ColorData[2] != orPan.ColorData[2])
                        {
                            curPatch.ColorBL = edPan.ColorData[2].ToString("X");
                        }
                        if (edPan.ColorData[3] != orPan.ColorData[3])
                        {
                            curPatch.ColorBR = edPan.ColorData[3].ToString("X");
                        }
                    }
                    curFile.Add(curPatch);
                }
                if (curFile.Count > 0)
                {
                    Patches.Add(new LayoutFilePatch()
                    {
                        FileName = f, Patches = curFile.ToArray()
                    });
                }
            }
            if (Patches.Count == 0)
            {
                MessageBox.Show("Couldn't find any difference");
                return(null);
            }
            return(new LayoutPatch()
            {
                PatchName = "diffPatch" + (targetPatch == null ? "" : "for " + targetPatch.TemplateName),
                AuthorName = "autoDiff",
                Files = Patches.ToArray()
            });
        }
コード例 #19
0
        public static LayoutPatch Diff(SarcData original, SarcData edited)
        {
            List <LayoutFilePatch> Patches = new List <LayoutFilePatch>();

            if (!ScrambledEquals <string>(original.Files.Keys, edited.Files.Keys))
            {
                MessageBox.Show("The provided archives don't have the same files");
                return(null);
            }
            var    targetPatch    = SwitchThemesCommon.DetectSarc(original, DefaultTemplates.templates);
            string skipLayoutName = targetPatch != null ? targetPatch.MainLayoutName : "";

            bool hasAtLeastAnExtraGroup = false;             //Used to detect if animations are properly implemented

            foreach (var f in original.Files.Keys.Where(x => x.EndsWith(".bflyt")))
            {
                if (original.Files[f].SequenceEqual(edited.Files[f]))
                {
                    continue;
                }
                BflytFile        or          = new BflytFile(original.Files[f]);
                BflytFile        ed          = new BflytFile(edited.Files[f]);
                string[]         orPaneNames = or.GetPaneNames();
                string[]         edPaneNames = ed.GetPaneNames();
                List <PanePatch> curFile     = new List <PanePatch>();
                for (int i = 0; i < edPaneNames.Length; i++)
                {
                    if (ed[i].data.Length < 0x4C || IgnorePaneList.Contains(ed[i].name))
                    {
                        continue;
                    }
                    if (f == skipLayoutName && (targetPatch?.targetPanels?.Contains(edPaneNames[i]) ?? false))
                    {
                        continue;
                    }
                    var j = Array.IndexOf(orPaneNames, edPaneNames[i]);
                    if (j == -1)
                    {
                        continue;
                    }

                    PanePatch curPatch = new PanePatch()
                    {
                        PaneName = edPaneNames[i]
                    };

                    curPatch.UsdPatches = MakeUsdPatch(or, i, ed, j);
                    if (ed[i].data.SequenceEqual(or[j].data))
                    {
                        if (curPatch.UsdPatches == null)
                        {
                            continue;
                        }
                        curFile.Add(curPatch);
                        continue;
                    }

                    var orPan = new BflytFile.PropertyEditablePanel(or[j]);
                    var edPan = new BflytFile.PropertyEditablePanel(ed[i]);
                    if (!VecEqual(edPan.Position, orPan.Position))
                    {
                        curPatch.Position = ToNullVec(edPan.Position);
                    }
                    if (!VecEqual(edPan.Rotation, orPan.Rotation))
                    {
                        curPatch.Rotation = ToNullVec(edPan.Rotation);
                    }
                    if (!VecEqual(edPan.Scale, orPan.Scale))
                    {
                        curPatch.Scale = ToNullVec(edPan.Scale);
                    }
                    if (!VecEqual(edPan.Size, orPan.Size))
                    {
                        curPatch.Size = ToNullVec(edPan.Size);
                    }
                    if (edPan.Visible != orPan.Visible)
                    {
                        curPatch.Visible = edPan.Visible;
                    }
                    if (edPan.name == "pic1")
                    {
                        if (edPan.ColorData[0] != orPan.ColorData[0])
                        {
                            curPatch.ColorTL = edPan.ColorData[0].ToString("X");
                        }
                        if (edPan.ColorData[1] != orPan.ColorData[1])
                        {
                            curPatch.ColorTR = edPan.ColorData[1].ToString("X");
                        }
                        if (edPan.ColorData[2] != orPan.ColorData[2])
                        {
                            curPatch.ColorBL = edPan.ColorData[2].ToString("X");
                        }
                        if (edPan.ColorData[3] != orPan.ColorData[3])
                        {
                            curPatch.ColorBR = edPan.ColorData[3].ToString("X");
                        }
                    }
                    curFile.Add(curPatch);
                }

                List <ExtraGroup> extraGroups = new List <ExtraGroup>();
                string[]          ogPanes     = or.GetGroupNames();
                foreach (var p_ in ed.Panels.Where(x => x is Grp1Pane))
                {
                    var p = ((Grp1Pane)p_);
                    if (ogPanes.Contains(p.GroupName))
                    {
                        continue;
                    }
                    extraGroups.Add(new ExtraGroup()
                    {
                        GroupName = p.GroupName, Panes = p.Panes.ToArray()
                    });
                    hasAtLeastAnExtraGroup = true;
                }
                if (extraGroups.Count == 0)
                {
                    extraGroups = null;
                }

                if (curFile.Count > 0 || extraGroups?.Count > 0)
                {
                    Patches.Add(new LayoutFilePatch()
                    {
                        FileName = f, Patches = curFile.ToArray(), AddGroups = extraGroups?.ToArray()
                    });
                }
            }
            if (Patches.Count == 0)             //animation edits depend on bflyt changes so this is relevant
            {
                MessageBox.Show("Couldn't find any difference");
                return(null);
            }

            List <AnimFilePatch> AnimPatches = new List <AnimFilePatch>();

            foreach (var f in original.Files.Keys.Where(x => x.EndsWith(".bflan")))
            {
                if (original.Files[f].SequenceEqual(edited.Files[f]))
                {
                    continue;
                }
                Bflan anim = new Bflan(edited.Files[f]);
                AnimPatches.Add(new AnimFilePatch()
                {
                    FileName = f, AnimJson = BflanSerializer.ToJson(anim)
                });
            }
            if (AnimPatches.Count == 0)
            {
                AnimPatches = null;
            }
            else if (!hasAtLeastAnExtraGroup)
            {
                MessageBox.Show("This theme uses custom animations but doesn't have custom group in the layouts, this means that the nxtheme will work on the firmware it has been developed on but it may break on older or newer ones. It's *highly recommended* to create custom groups to handle animations");
            }

            return(new LayoutPatch()
            {
                PatchName = "diffPatch" + (targetPatch == null ? "" : "for " + targetPatch.TemplateName),
                AuthorName = "autoDiff",
                Files = Patches.ToArray(),
                Anims = AnimPatches?.ToArray(),
                Ready8X = true                 //Aka tell the patcher to not fix this layout
            });
        }