예제 #1
0
        private void OKButton_Click(object sender, EventArgs e)
        {
            if (OKButton.Text == "OK")
            {
                Close();
            }
            else
            {
                textBox1.AppendText(Environment.NewLine + "Start!");
                checkboxAngelscriptFunctions.Enabled = checkboxExcludeDefault.Enabled = checkboxIncludeMusic.Enabled = checkboxMissing.Enabled = checkboxMultipleLevels.Enabled = OKButton.Enabled = false;
                Directory.SetCurrentDirectory(Path.GetDirectoryName(initialLevelFilepath));

                string angelscriptPragmaPattern = "(#pragma\\s+require|#pragma\\s+offer";
                if (checkboxAngelscriptFunctions.Checked)
                {
                    angelscriptPragmaPattern += "|jjNxt\\s*\\(|jjMusicLoad\\s*\\(|jjLayersFromLevel\\s*\\(|jjTilesFromTileset\\s*\\(|jjSampleLoad\\s*\\(\\s*SOUND\\s*::\\s*[a-z0-9_]+\\s*,";
                }
                angelscriptPragmaPattern += ")\\s*(['\"])(.+?)\\2";

                var levelFilepaths = new List <string>();
                levelFilepaths.Add(initialLevelFilepath);

                for (int levelID = 0; levelID < levelFilepaths.Count; ++levelID)
                {
                    string levelFilepath = levelFilepaths[levelID];
                    textBox1.AppendText(Environment.NewLine + "Inspecting level \"" + levelFilepath + '"');
                    switch (extendedAddFilepath(ref levelFilepath))
                    {
                    case DialogResult.Yes:
                        break;

                    case DialogResult.No:     //e.g. file not found
                        continue;

                    case DialogResult.Cancel:
                        return;
                    }
                    J2LFile j2l         = new J2LFile();
                    var     Data5       = new byte[0];
                    var     openResults = j2l.OpenLevel(levelFilepath, ref Data5, onlyInterestedInData1: true);
                    if (!(openResults == OpeningResults.Success || openResults == OpeningResults.SuccessfulButAmbiguous))
                    {
                        textBox1.AppendText(Environment.NewLine + "Unexpected error while opening level." + Environment.NewLine + "Packaging cancelled.");
                        return;
                    }
                    if (tilesetExtension != String.Empty) //not GorH
                    {
                        var tilesetFilename = Path.ChangeExtension(j2l.MainTilesetFilename, tilesetExtension);
                        if (addFilepath(ref tilesetFilename) == DialogResult.Cancel)
                        {
                            return;
                        }
                    }
                    if (checkboxIncludeMusic.Checked)
                    {
                        var musicFilename = j2l.Music;
                        if (musicFilename.Trim() != String.Empty)
                        {
                            if (!Path.HasExtension(musicFilename))
                            {
                                musicFilename = Path.ChangeExtension(musicFilename, "j2b");
                            }
                            if (addFilepath(ref musicFilename) == DialogResult.Cancel)
                            {
                                return;
                            }
                        }
                    }
                    if (checkboxMultipleLevels.Checked)
                    {
                        foreach (var additionalLevelFilename in new string[] { j2l.NextLevel, j2l.SecretLevel })
                        {
                            if (additionalLevelFilename != String.Empty && !(additionalLevelFilename.Length >= 3 && StringComparer.InvariantCultureIgnoreCase.Compare(additionalLevelFilename.Substring(0, 3), "end") == 0)) //any level filename starting with END is invalid (to JJ2, at least)
                            {
                                levelFilepaths.Add(Path.ChangeExtension(additionalLevelFilename, levelExtension));                                                                                                           //come back to this level later in the loop
                            }
                        }
                    }
                    if (checkScripts)
                    {
                        string mainScriptFilename = Path.ChangeExtension(levelFilepath, "j2as");
                        if (File.Exists(mainScriptFilename)) //not all levels have them, and we don't want to go down this path otherwise
                        {
                            var scriptFilepaths = new List <string>();
                            scriptFilepaths.Add(mainScriptFilename);

                            for (int scriptID = 0; scriptID < scriptFilepaths.Count; ++scriptID)
                            {
                                string scriptFilepath = scriptFilepaths[scriptID];
                                switch (extendedAddFilepath(ref scriptFilepath))
                                {
                                case DialogResult.Yes:
                                    break;

                                case DialogResult.No:     //e.g. file not found
                                    continue;

                                case DialogResult.Cancel:
                                    return;
                                }
                                var fileContents = System.IO.File.ReadAllText(scriptFilepath, J2LFile.FileEncoding);
                                foreach (System.Text.RegularExpressions.Match match in System.Text.RegularExpressions.Regex.Matches(fileContents, "#include\\s+(['\"])(.+?)\\1", System.Text.RegularExpressions.RegexOptions.IgnoreCase)) //actually I don't even know whether #include is case-insensitive   jjSampleLoad(SOUND::ORANGE_BOEMR, "expmine.wav");
                                {
                                    scriptFilepaths.Add(match.Groups[2].Value);                                                                                                                                                           //come back to this script later in the loop
                                }
                                foreach (System.Text.RegularExpressions.Match match in System.Text.RegularExpressions.Regex.Matches(fileContents, angelscriptPragmaPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                                {
                                    string foundFilepath = match.Groups[3].Value;
                                    if (match.Groups[1].Value.Contains("jjN")) //don't need to worry about case here, because it's a function.
                                    {
                                        levelFilepaths.Add(foundFilepath);
                                    }
                                    else if (addFilepath(ref foundFilepath) == DialogResult.Cancel)
                                    {
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }

                textBox1.AppendText(Environment.NewLine + "Beginning ZIP...");
                if (File.Exists(finalZipFilepath))
                {
                    File.Delete(finalZipFilepath);
                }
                using (var zip = ZipFile.Open(finalZipFilepath, ZipArchiveMode.Create))
                {
                    foreach (string filepath in filePathsToInclude)
                    {
                        textBox1.AppendText(Environment.NewLine + "Compressing " + filepath);
                        zip.CreateEntryFromFile(filepath, Path.GetFileName(filepath));
                    }
                }

                textBox1.AppendText(Environment.NewLine + "Done! Packaged " + filePathsToInclude.Count.ToString() + " files (" + (new System.IO.FileInfo(finalZipFilepath).Length / 1024).ToString() + " kb)");
                textBox1.AppendText(Environment.NewLine + "Click OK to finish.");
                OKButton.Enabled     = true;
                CancelButton.Enabled = false;
                OKButton.Text        = "OK";
            }
        }
예제 #2
0
        internal bool LevelIsReadable(byte[] Data5, List <J2TFile> Tilesets, List <Layer> Layers, string Filepath)
        {
            if (Data5 == null || Data5.Length < 20) //level stops at the end of data4, as is good and proper
            {
                this = new PlusPropertyList(null);
                return(true);
            }
            using (BinaryReader data5reader = new BinaryReader(new MemoryStream(Data5), J2LFile.FileEncoding))
            {
                if (new string(data5reader.ReadChars(4)) != MLLEData5MagicString)
                {
                    return(false);
                }
                uint data5Version = data5reader.ReadUInt32();
                if (data5Version > CurrentMLLEData5Version)
                {
                    return(false);
                }
                //should be okay to read at this point

                this = new PlusPropertyList(null);

                uint csize = data5reader.ReadUInt32();
                uint usize = data5reader.ReadUInt32();
                using (BinaryReader data5bodyreader = new BinaryReader(new MemoryStream(ZlibStream.UncompressBuffer(data5reader.ReadBytes((int)csize)))))
                {
                    IsSnowing                  = data5bodyreader.ReadBoolean();
                    IsSnowingOutdoorsOnly      = data5bodyreader.ReadBoolean();
                    SnowingIntensity           = data5bodyreader.ReadByte();
                    SnowingType                = (SnowTypeEnum)data5bodyreader.ReadByte();
                    WarpsTransmuteCoins        = data5bodyreader.ReadBoolean();
                    DelayGeneratedCrateOrigins = data5bodyreader.ReadBoolean();
                    Echo               = data5bodyreader.ReadInt32();
                    DarknessColor      = Color.FromArgb(data5bodyreader.ReadInt32());
                    WaterChangeSpeed   = data5bodyreader.ReadSingle();
                    WaterInteraction   = (WaterInteractionEnum)data5bodyreader.ReadByte();
                    WaterLayer         = data5bodyreader.ReadInt32();
                    WaterLighting      = (WaterLightingEnum)data5bodyreader.ReadByte();
                    WaterLevel         = data5bodyreader.ReadSingle();
                    WaterGradientStart = Color.FromArgb(data5bodyreader.ReadInt32());
                    WaterGradientStop  = Color.FromArgb(data5bodyreader.ReadInt32());

                    if (data5bodyreader.ReadBoolean())
                    {
                        Palette = new Palette(data5bodyreader, true);
                    }

                    for (int i = 0; i < Mainframe.RecolorableSpriteNames.Length; ++i)
                    {
                        if ((i < 11 || data5Version >= 0x105) && data5bodyreader.ReadBoolean()) //the recolorable sprite list was expanded in MLLE-Include-1.5
                        {
                            ColorRemappings[i] = new byte[Palette.PaletteSize];
                            for (uint j = 0; j < Palette.PaletteSize; ++j)
                            {
                                ColorRemappings[i][j] = data5bodyreader.ReadByte();
                            }
                        }
                        else
                        {
                            ColorRemappings[i] = null;
                        }
                    }

                    var extraTilesetCount = data5bodyreader.ReadByte();
                    for (uint tilesetID = 0; tilesetID < extraTilesetCount; ++tilesetID)
                    {
                        var tilesetFilepath = Path.Combine(Path.GetDirectoryName(Filepath), data5bodyreader.ReadString());
                        if (File.Exists(tilesetFilepath))
                        {
                            var tileset = new J2TFile(tilesetFilepath);
                            tileset.FirstTile = data5bodyreader.ReadUInt16();
                            tileset.TileCount = data5bodyreader.ReadUInt16();
                            if (data5bodyreader.ReadBoolean())
                            {
                                tileset.ColorRemapping = new byte[Palette.PaletteSize];
                                for (uint i = 0; i < Palette.PaletteSize; ++i)
                                {
                                    tileset.ColorRemapping[i] = data5bodyreader.ReadByte();
                                }
                            }
                            Tilesets.Add(tileset);
                        }
                        else
                        {
                            this = new PlusPropertyList(null);
                            MessageBox.Show("Additional tileset \"" + tilesetFilepath + "\" not found; MLLE will stop trying to read this Data5 section.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                            return(false);
                        }
                    }

                    if (data5Version >= 0x102) //layers were added in MLLE-Include-1.2
                    {
                        var defaultLayers = Layers.ToArray();
                        Layers.Clear();
                        int          layerCount       = (int)data5bodyreader.ReadUInt32();
                        List <Layer> nonDefaultLayers = new List <Layer>();
                        for (int i = 8; i < layerCount; i += 8)
                        {
                            J2LFile extraLevel    = new J2LFile();
                            string  levelFilePath = GetExtraDataLevelFilepath(Filepath, i / 8 - 1);
                            if (File.Exists(levelFilePath))
                            {
                                extraLevel.OpenLevel(levelFilePath, ref Data5, SecurityStringOverride: J2LFile.SecurityStringExtraDataNotForDirectEditing);
                                nonDefaultLayers.AddRange(extraLevel.DefaultLayers);
                            }
                            else
                            {
                                this = new PlusPropertyList(null);
                                MessageBox.Show("Additional file \"" + levelFilePath + "\" not found; MLLE will stop trying to read this Data5 section.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                                return(false);
                            }
                        }
                        int nextNonDefaultLayerID = 0;
                        for (uint i = 0; i < layerCount; ++i)
                        {
                            sbyte layerID = data5bodyreader.ReadSByte();
                            Layer layer;
                            if (layerID >= 0)
                            {
                                layer = defaultLayers[layerID];
                            }
                            else
                            {
                                layer    = nonDefaultLayers[nextNonDefaultLayerID++];
                                layer.id = -1;
                            }
                            layer.Name                     = data5bodyreader.ReadString();
                            layer.Hidden                   = data5bodyreader.ReadBoolean();
                            layer.SpriteMode               = data5bodyreader.ReadByte();
                            layer.SpriteParam              = data5bodyreader.ReadByte();
                            layer.RotationAngle            = data5bodyreader.ReadInt32();
                            layer.RotationRadiusMultiplier = data5bodyreader.ReadInt32();
                            Layers.Add(layer);
                        }

                        if (data5Version >= 0x103) //edited tiles were added in MLLE-Include-1.3
                        {
                            int levelTileCount = Tilesets.Sum(ts => (int)ts.TileCount);
                            foreach (byte[][] images in new byte[][][] { TileImages, TileMasks })
                            {
                                int numberOfImages = data5bodyreader.ReadUInt16();
                                for (int i = 0; i < numberOfImages; ++i)
                                {
                                    int tileID = data5bodyreader.ReadUInt16();
                                    images[tileID] = data5bodyreader.ReadBytes(32 * 32);
                                }
                            }

                            if (data5Version >= 0x105) //weapons were added in MLLE-Include-1.5(w)
                            {
                                for (int weaponID = 0; weaponID < 9; ++weaponID)
                                {
                                    bool   customWeapon = data5bodyreader.ReadBoolean();
                                    Weapon weapon       = Weapons[weaponID];
                                    weapon.Options[0] = data5bodyreader.ReadInt32(); //maximum
                                    for (int optionID = 1; optionID < Weapon.NumberOfCommonOptions; ++optionID)
                                    {
                                        weapon.Options[optionID] = data5bodyreader.ReadByte(); //birds and crates and gems and replenishment
                                    }
                                    if (weaponID == 6)
                                    {
                                        Gun7Crate = data5bodyreader.ReadByte();
                                    }
                                    else if (weaponID == 7)
                                    {
                                        Gun8Crate = data5bodyreader.ReadByte();
                                    }
                                    else if (weaponID == 8)
                                    {
                                        Gun9Crate = data5bodyreader.ReadByte();
                                    }
                                    if (customWeapon)
                                    {
                                        string name           = data5bodyreader.ReadString();
                                        var    extendedWeapon = WeaponsForm.GetAllAvailableWeapons().Find(w => w.Name == name);
                                        if (extendedWeapon == null)
                                        {
                                            MessageBox.Show(String.Format("Sorry, the MLLE \"Weapons\" folder did not include any .ini file defining a weapon with the name \"{0}.\"", name), "Weapon not found", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                            return(false);
                                        }

                                        Weapons[weaponID].Name = name;
                                        Array.Resize(ref Weapons[weaponID].Options, extendedWeapon.Options.Length);
                                        data5bodyreader.ReadInt32(); //length of jjSTREAM
                                        for (int optionID = Weapon.NumberOfCommonOptions; optionID < weapon.Options.Length; ++optionID)
                                        {
                                            switch (extendedWeapon.OptionTypes[optionID])
                                            {
                                            case WeaponsForm.ExtendedWeapon.oTypes.Bool:
                                            case WeaponsForm.ExtendedWeapon.oTypes.Dropdown:
                                                weapon.Options[optionID] = data5bodyreader.ReadByte();
                                                break;

                                            case WeaponsForm.ExtendedWeapon.oTypes.Int:
                                                weapon.Options[optionID] = data5bodyreader.ReadInt32();
                                                break;
                                            }
                                        }
                                    }
                                    else if (weaponID == 7)
                                    {
                                        weapon.Options[Weapon.NumberOfCommonOptions] = data5bodyreader.ReadByte(); //Gun8 style
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(true);
        }