Example #1
0
        public void PatchDirArchive(ModData mod, string archivepath)
        {
            string archive_dir = mod.Path + archivepath;

            // Check if the mod has a directory for wad resources
            if (Directory.Exists(archive_dir))
            {
                Archive archive = new Archive(TempPath + archivepath + ".wad");
                archive.Load();

                int i, j;
                int count = 0;

                // Go through the groups in the archive file.
                for (i = 0; i < archive.Groups.Count; i++)
                {
                    var group = archive.Groups[i];

                    //Check for matching subdirectory and archive group.
                    if (Directory.Exists(archive_dir + "/" + group.Name))
                    {
                        //Go through the entries in the archive file
                        for (j = 0; j < archive.Groups[i].Entries.Count; j++)
                        {
                            var entry = archive.Groups[i].Entries[j];

                            //Check for matching file and archive entry.
                            string filepath = archive_dir + "/" + group.Name + "/" + entry.Name;
                            if (File.Exists(filepath))
                            {
                                Byte[] data = File.ReadAllBytes(filepath);
                                var new_entry = new Entry(entry.Name, data);

                                //Replace entry in the archive.wad with file in mod archive folder.
                                archive.Groups[i].Entries[j] = new_entry;

                                //Msg.Log("Patching '" + group.Name + "/" + entry.Name + "' from " + mod.Name);
                                count++;
                            }
                        }
                    }
                }

                archive.Save();

                if (count > 0) Msg.Log("Patched " + count + " " + archivepath + " resources for " + mod.Name);
            }
        }
Example #2
0
        public void PatchZipArchive(ModData mod, string archivepath)
        {
            ZipFile zip = new ZipFile(mod.Path);

            // Check if the mod has a directory for wad resources
            if (zip.ContainsEntry(archivepath + "/"))
            {
                Archive archive = new Archive(TempPath + archivepath + ".wad");
                archive.Load();

                int i, j;
                int count = 0;

                // Go through the groups in the archive file.
                for (i = 0; i < archive.Groups.Count; i++)
                {
                    var group = archive.Groups[i];

                    //Check for matching subdirectory and archive group.
                    string grouppath = archivepath + "/" + group.Name + "/";
                    if (zip.ContainsEntry(grouppath))
                    {
                        //Go through the entries in the archive file
                        for (j = 0; j < archive.Groups[i].Entries.Count; j++)
                        {
                            var entry = archive.Groups[i].Entries[j];

                            //Check for matching file and archive entry.
                            string entrypath = grouppath + entry.Name;
                            if (zip.ContainsEntry(entrypath))
                            {
                                //Msg.Log("zip: " + mod.Name + ", matching res-entry: " + entrypath);

                                MemoryStream stream = new MemoryStream();
                                zip[entrypath].Extract(stream);

                                Byte[] data = stream.GetBuffer();
                                var new_entry = new Entry(entry.Name, data);

                                //Replace entry in the archive.wad with file in mod archive folder.
                                archive.Groups[i].Entries[j] = new_entry;
                                //Msg.Log("Patching '" + group.Name + "/" + entry.Name + "' from zip " + mod.Name);
                                count++;
                            }
                        }
                    }
                }
                archive.Save();

                if (count > 0) Msg.Log("Patched " + count + " " + archivepath + " resources for " + mod.Name);
            }            
        }
Example #3
0
        //Extracts textures and sounds to a directory (for modders)
        private void btnExtractArchives_Click(object sender, EventArgs e)
        {
            if (Setup.CheckBackups() == false)
            {
                Msg.Log("Failed to extract the game archives.");
                string message = "Patchlunky is missing Spelunky backups!" +
                    Environment.NewLine + Environment.NewLine +
                "Patchlunky cannot extract the game archives without backups.";
                Msg.MsgBox(message, "Patchlunky");
                return; //Backups are missing, can't extract.
            }

            Archive alltex = new Archive(Setup.BackupPath + "Textures/alltex.wad");
            alltex.Load();

            foreach (var group in alltex.Groups)
            {
                string dirpath = Path.Combine(Setup.TempPath + "alltex/", group.Name);
                Directory.CreateDirectory(dirpath);

                foreach (var entry in group.Entries)
                {
                    string filepath = Path.Combine(dirpath, entry.Name);
                    File.WriteAllBytes(filepath, entry.Data);
                }
            }
            Msg.Log("Extracted alltex.wad to ./Patchlunky_Temp/alltex/");


            Archive allsounds = new Archive(Setup.BackupPath + "Sounds/allsounds.wad");
            allsounds.Load();

            foreach (var group in allsounds.Groups)
            {
                string dirpath = Path.Combine(Setup.TempPath + "allsounds/", group.Name);
                Directory.CreateDirectory(dirpath);

                foreach (var entry in group.Entries)
                {
                    string filepath = Path.Combine(dirpath, entry.Name);
                    File.WriteAllBytes(filepath, entry.Data);
                }
            }
            Msg.Log("Extracted allsounds.wad to ./Patchlunky_Temp/allsounds/");
        }
Example #4
0
        // Patch the game files
        public bool PatchGame(bool reset_only)
        {
            Settings settings = Program.mainForm.Settings;
            ModManager modMan = Program.mainForm.ModMan;
            SkinManager skinMan = Program.mainForm.SkinMan;
            
            string message;

            if (CheckGameDir() == false)
            {
                message = "The Spelunky directory is not set!" +
                    Environment.NewLine + Environment.NewLine +
                "Patchlunky cannot patch the game until the directory is set.";
                Msg.MsgBox(message, "Patchlunky Setup");
                return false; //Path to game has not been set, can't patch.
            }

            if (CheckBackups() == false)
            {
                message = "Patchlunky is missing Spelunky backups!" +
                    Environment.NewLine + Environment.NewLine +
                "Patchlunky cannot patch the game without backups.";
                Msg.MsgBox(message, "Patchlunky Setup");
                return false; //Backups are missing, can't patch.
            }

            Program.mainForm.SetProgress(0);

            // STEP 1 OF 4 - Copy default data files to temp folder
            foreach (GameFile gmfile in DefaultFiles)
            {
                try
                {
                    string srcfile = this.BackupPath + gmfile.FilePath;
                    string dstfile = this.TempPath + gmfile.FilePath;
                    Directory.CreateDirectory(Path.GetDirectoryName(dstfile));
                    File.Copy(srcfile, dstfile, true);
                }
                catch (Exception ex)
                {
                    Msg.MsgBox("Error trying to copy file: " + ex.Message, "Patchlunky Setup");
                    return false; //Stop patching
                }
            }

            Program.mainForm.SetProgress(33);

            // STEP 2 OF 4 - Copy mod files to temp folder
            if ((reset_only == false) && (modMan.Mods.Count > 0))
            {
                foreach (ModData mod in modMan.Mods)
                {
                    if (mod.Enabled == false)
                        continue;

                    //Patch game files in the mod.
                    if (PatchFiles(mod) == false)
                        return false; //Stop patching

                    //Patch wad resources in the mod.
                    PatchArchive(mod, "Textures/alltex");
                    PatchArchive(mod, "Sounds/allsounds");
                }
            }

            // STEP 3 OF 4 - Patch alltex.wad in temp folder with skin files
            if ((reset_only == false) && (skinMan.SkinConfig.Count > 0))
            {
                Archive archive = new Archive(TempPath + "Textures/alltex" + ".wad");
                archive.Load();

                int i = archive.Groups.FindIndex(o => o.Name.Equals("PLAYERS", StringComparison.OrdinalIgnoreCase));
                if (i == -1)
                    return false; //Missing "PLAYERS" group in archive, stop patching                

                int count = 0;

                foreach(KeyValuePair<string, string> kvp in skinMan.SkinConfig)
                {
                    SkinData oldSkin = skinMan.GetSkin(kvp.Key);
                    SkinData newSkin = skinMan.GetSkin(kvp.Value);

                    bool skinsMatch = kvp.Key.Equals(kvp.Value);

                    if (skinsMatch && settings.Check("ModsReplaceDefaultSkins", "True"))
                        continue; //Skip default skins

                    int j = archive.Groups[i].Entries.FindIndex(o => o.Name.Equals(oldSkin.Name + ".png", StringComparison.OrdinalIgnoreCase));
                    if (j == -1)
                        continue; //Skip missing character entry

                    Byte[] data = File.ReadAllBytes(newSkin.Path);
                    var new_entry = new Entry(oldSkin.Name + ".png", data);

                    //Replace entry in the archive.wad
                    archive.Groups[i].Entries[j] = new_entry;
                    //Msg.Log("Patching skin '" + oldSkin.Name + " to '" + newSkin.Name + "'.");

                    if (skinsMatch == false)
                        count++;
                }

                if (count > 0) Msg.Log("Patched " + count + " character skins");

                archive.Save();
            }

            Program.mainForm.SetProgress(66);

            // STEP 4 OF 4 - Copy files to Spelunky data folders.
            foreach (GameFile gmfile in DefaultFiles)
            {
                try
                {
                    string srcfile = this.TempPath + gmfile.FilePath;
                    string dstfile = this.GamePath + "Data/" + gmfile.FilePath;
                    File.Copy(srcfile, dstfile, true);
                }
                catch (Exception ex)
                {
                    Msg.MsgBox("Error patching file: " + ex.Message, "Patchlunky Setup");
                    return false; //Stop patching
                }
            }

            Program.mainForm.SetProgress(100);

            return true;
        }
Example #5
0
        //Extracts the original skins from the backups
        private void ExtractDefaultSkins()
        {
            Setup setup = Program.mainForm.Setup;

            if (setup.CheckBackups() == false)
            {
                Msg.Log("Failed to extract default skins.");
                string message = "Patchlunky is missing Spelunky backups!" +
                    Environment.NewLine + Environment.NewLine +
                "Patchlunky character skins will not work without backups.";
                Msg.MsgBox(message, "Patchlunky");
                return; //Backups are missing, can't extract.
            }

            Archive alltex = new Archive(setup.BackupPath + "Textures/alltex.wad");
            alltex.Load();

            var group = alltex.Groups.Find(o => o.Name.Equals("PLAYERS"));
            if (group.Equals(default(SpelunkyWad.Group)))
                return; //Group not found

            string dirpath = setup.BackupPath + "Characters/";
            Directory.CreateDirectory(dirpath);

            foreach (var entry in group.Entries)
            {
                string filepath = Path.Combine(dirpath, entry.Name);
                File.WriteAllBytes(filepath, entry.Data);
            }
        }