コード例 #1
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()
                 });
             }
         }
     });
 }
コード例 #2
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();
     });
 }
コード例 #3
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;
        }
コード例 #4
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()
            });
        }
コード例 #5
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");
        }
コード例 #6
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);
        }
コード例 #7
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
            });
        }