Пример #1
0
        public virtual clsResult Load(string path)
        {
            var returnResult = new clsResult(string.Format("Loading WZ from '{0}'.", path), false);
            logger.Info("Loading WZ from '{0}'.", path);
            var subResult = new sResult();

            ZipSplitPath splitPath;
            var mapLoadName = "";

            using ( var zip = ZipFile.Read(path) )
            {
                foreach ( var e in zip )
                {
                    if ( e.IsDirectory )
                    {
                        continue;
                    }

                    splitPath = new ZipSplitPath(e.FileName);
                    logger.Debug("Found file \"{0}\".", e.FileName);
                    // Find the maps .lev
                    if ( splitPath.FileExtension != "lev" || splitPath.PartCount != 1 )
                    {
                        continue;
                    }

                    // Buggy file > 1MB
                    if ( e.UncompressedSize > 1 * 1024 * 1024 )
                    {
                        returnResult.ProblemAdd("lev file is too large.");
                        return returnResult;
                    }

                    using ( var s = e.OpenReader() )
                    {
                        var myresult = new clsResult(string.Format("Parsing file \"{0}\"", e.FileName), false);
                        logger.Info("Parsing file \"{0}\"", e.FileName);

                        try
                        {
                            var r = new StreamReader(s);
                            var text = r.ReadToEnd();
                            var levFile = LevGrammar.Lev.Parse(text);

                            if ( levFile.Levels.Count < 1 )
                            {
                                myresult.ProblemAdd("No maps found in file.");
                                returnResult.Add(myresult);
                                return returnResult;
                            }

                            // Group games by the Game key.
                            var groupGames = levFile.Levels.GroupBy(level => level.Game);

                            // Load default map if only one Game file is found.
                            if ( groupGames.Count() == 1 )
                            {
                                var level = groupGames.First().First(); //first group, first level

                                mapLoadName = level.Game;

                                switch ( level.Dataset.Substring(level.Dataset.Length - 1, 1) )
                                {
                                    case "1":
                                        map.Tileset = App.Tileset_Arizona;
                                        break;
                                    case "2":
                                        map.Tileset = App.Tileset_Urban;
                                        break;
                                    case "3":
                                        map.Tileset = App.Tileset_Urban;
                                        break;
                                    default:
                                        myresult.ProblemAdd("Unknown tileset.");
                                        returnResult.Add(myresult);
                                        return returnResult;
                                }
                            }
                            else
                            {
                                //prompt user for which of the entries to load
                                var selectToLoadResult = new frmWZLoad.clsOutput();

                                var names = groupGames
                                    .Select(gameGroup => gameGroup.First().Name)
                                    .ToArray();

                                var selectToLoadForm = new frmWZLoad(names, selectToLoadResult,
                                    "Select a map from " + new sSplitPath(path).FileTitle);
                                selectToLoadForm.ShowDialog();
                                if ( selectToLoadResult.Result < 0 )
                                {
                                    returnResult.ProblemAdd("No map selected.");
                                    return returnResult;
                                }

                                var level = groupGames.ElementAt(selectToLoadResult.Result).First();

                                mapLoadName = level.Game;

                                switch ( level.Dataset.Substring(level.Dataset.Length - 1, 1) )
                                {
                                    case "1":
                                        map.Tileset = App.Tileset_Arizona;
                                        break;
                                    case "2":
                                        map.Tileset = App.Tileset_Urban;
                                        break;
                                    case "3":
                                        map.Tileset = App.Tileset_Urban;
                                        break;
                                    default:
                                        myresult.ProblemAdd("Unknown tileset.");
                                        returnResult.Add(myresult);
                                        return returnResult;
                                }
                            }
                        }
                        catch ( Exception ex )
                        {
                            myresult.ProblemAdd(string.Format("Got an exception while parsing the .lev file: {0}", ex), false);
                            returnResult.Add(myresult);
                            logger.ErrorException("Got an exception while parsing the .lev file", ex);
                            Debugger.Break();
                        }
                    }
                }

                map.TileType_Reset();
                map.SetPainterToDefaults();

                // mapLoadName is now multiplay/maps/<mapname>.gam (thats "game" from the .lev file
                var gameSplitPath = new ZipSplitPath(mapLoadName);
                var gameFilesPath = gameSplitPath.FilePath + gameSplitPath.FileTitleWithoutExtension + "/";

                var gameZipEntry = zip[mapLoadName];
                if ( gameZipEntry == null )
                {
                    returnResult.ProblemAdd(string.Format("Game file \"{0}\" not found.", mapLoadName), false);
                    logger.Error("Game file \"{0}\" not found.", mapLoadName);
                    return returnResult;
                }
                using ( Stream s = gameZipEntry.OpenReader() )
                {
                    var reader = new BinaryReader(s);
                    subResult = read_WZ_gam(reader);
                    reader.Close();
                    if ( !subResult.Success )
                    {
                        returnResult.ProblemAdd(subResult.Problem);
                        return returnResult;
                    }
                }

                var gameMapZipEntry = zip[gameFilesPath + "game.map"];
                if ( gameMapZipEntry == null )
                {
                    returnResult.ProblemAdd(string.Format("{0}game.map file not found", gameFilesPath));
                    return returnResult;
                }
                using ( Stream s = gameMapZipEntry.OpenReader() )
                {
                    var reader = new BinaryReader(s);
                    subResult = read_WZ_map(reader);
                    reader.Close();
                    if ( !subResult.Success )
                    {
                        returnResult.ProblemAdd(subResult.Problem);
                        return returnResult;
                    }
                }

                var bjoUnits = new List<WZBJOUnit>();

                var iniFeatures = new List<IniFeature>();
                var featureIniZipEntry = zip[gameFilesPath + "feature.ini"];
                if ( featureIniZipEntry != null )
                {
                    using ( var reader = new StreamReader(featureIniZipEntry.OpenReader()) )
                    {
                        var text = reader.ReadToEnd();
                        returnResult.Add(read_INI_Features(text, iniFeatures));
                    }
                }

                if ( iniFeatures.Count() == 0 ) // no feature.ini
                {
                    var Result = new clsResult("feat.bjo", false);
                    logger.Info("Loading feat.bjo");

                    var featBJOZipEntry = zip[gameFilesPath + "feat.bjo"];
                    if ( featBJOZipEntry == null )
                    {
                        Result.WarningAdd(string.Format("{0}feat.bjo / feature.ini file not found", gameFilesPath));
                    }
                    else
                    {
                        using ( Stream s = featBJOZipEntry.OpenReader() )
                        {
                            var reader = new BinaryReader(s);
                            subResult = read_WZ_Features(reader, bjoUnits);
                            reader.Close();
                            if ( !subResult.Success )
                            {
                                Result.WarningAdd(subResult.Problem);
                            }
                        }
                    }
                    returnResult.Add(Result);
                }

                var result = new clsResult("ttypes.ttp", false);
                logger.Info("Loading ttypes.ttp");
                var ttypesEntry = zip[gameFilesPath + "ttypes.ttp"];
                if ( ttypesEntry == null )
                {
                    result.WarningAdd(string.Format("{0}ttypes.ttp file not found", gameFilesPath));
                }
                else
                {
                    using ( Stream s = ttypesEntry.OpenReader() )
                    {
                        var reader = new BinaryReader(s);
                        subResult = read_WZ_TileTypes(reader);
                        reader.Close();
                        if ( !subResult.Success )
                        {
                            result.WarningAdd(subResult.Problem);
                        }
                    }
                }
                returnResult.Add(result);

                var iniStructures = new List<IniStructure>();
                var structIniEntry = zip[gameFilesPath + "struct.ini"];
                if ( structIniEntry != null )
                {
                    using ( var reader = new StreamReader(structIniEntry.OpenReader()) )
                    {
                        var text = reader.ReadToEnd();
                        returnResult.Add(read_INI_Structures(text, iniStructures));
                    }
                }

                if ( iniStructures.Count() == 0 )
                {
                    var Result = new clsResult("struct.bjo", false);
                    logger.Info("Loading struct.bjo");
                    var structBjoEntry = zip[gameFilesPath + "struct.bjo"];
                    if ( structBjoEntry == null )
                    {
                        Result.WarningAdd(string.Format("{0}struct.bjo / struct.ini file not found", gameFilesPath));
                    }
                    else
                    {
                        using ( Stream s = structBjoEntry.OpenReader() )
                        {
                            var reader = new BinaryReader(s);
                            subResult = read_WZ_Structures(reader, bjoUnits);
                            reader.Close();
                            if ( !subResult.Success )
                            {
                                Result.WarningAdd(subResult.Problem);
                            }
                        }
                    }
                    returnResult.Add(Result);
                }

                var iniDroids = new List<IniDroid>();
                if ( structIniEntry != null )
                {
                    var droidIniEntry = zip[gameFilesPath + "droid.ini"];
                    if ( droidIniEntry != null )
                    {
                        using ( var reader = new StreamReader(droidIniEntry.OpenReader()) )
                        {
                            var text = reader.ReadToEnd();
                            returnResult.Add(read_INI_Droids(text, iniDroids));
                        }
                    }
                }

                if ( iniDroids.Count() == 0 ) // No droid.ini
                {
                    var Result = new clsResult("dinit.bjo", false);
                    logger.Info("Loading dinit.bjo");
                    var diniBjoEntry = zip[gameFilesPath + "dinit.bjo"];
                    if ( diniBjoEntry == null )
                    {
                        Result.WarningAdd(string.Format("{0}dinit.bjo / droid.ini file not found", gameFilesPath));
                    }
                    else
                    {
                        using ( Stream s = diniBjoEntry.OpenReader() )
                        {
                            var reader = new BinaryReader(s);
                            subResult = read_WZ_Droids(reader, bjoUnits);
                            reader.Close();
                            if ( !subResult.Success )
                            {
                                Result.WarningAdd(subResult.Problem);
                            }
                        }
                    }
                    returnResult.Add(Result);
                }

                returnResult.Add(createWZObjects(bjoUnits, iniStructures, iniDroids, iniFeatures));

                //objects are modified by this and must already exist
                var labelsIniEntry = zip[gameFilesPath + "labels.ini"];
                if ( labelsIniEntry != null )
                {
                    using ( var reader = new StreamReader(labelsIniEntry.OpenReader()) )
                    {
                        var text = reader.ReadToEnd();
                        returnResult.Add(read_INI_Labels(text));
                    }
                }
            }

            return returnResult;
        }
Пример #2
0
        public clsResult Load_WZ(string Path)
        {
            clsResult ReturnResult =
                new clsResult("Loading WZ from " + Convert.ToString(ControlChars.Quote) + Path + Convert.ToString(ControlChars.Quote));
            App.sResult SubResult = new App.sResult();
            string Quote = ControlChars.Quote.ToString();
            ZipEntry ZipEntry = default(ZipEntry);
            bool GameFound = default(bool);
            bool DatasetFound = default(bool);
            SimpleList<clsWZMapEntry> Maps = new SimpleList<clsWZMapEntry>();
            clsTileset GameTileset = null;
            string GameName = "";
            string strTemp = "";
            ZipSplitPath SplitPath;
            int A = 0;
            int B = 0;
            int C = 0;
            int D = 0;

            FileStream File = default(FileStream);
            try
            {
                File = System.IO.File.OpenRead(Path);
            }
            catch ( Exception ex )
            {
                ReturnResult.ProblemAdd(ex.Message);
                return ReturnResult;
            }

            ZipInputStream ZipStream = new ZipInputStream(File);

            //get all usable lev entries
            do
            {
                ZipEntry = ZipStream.GetNextEntry();
                if ( ZipEntry == null )
                {
                    break;
                }

                SplitPath = new ZipSplitPath(ZipEntry.Name);

                if ( SplitPath.FileExtension == "lev" && SplitPath.PartCount == 1 )
                {
                    if ( ZipEntry.Size > 10 * 1024 * 1024 )
                    {
                        ReturnResult.ProblemAdd("lev file is too large.");
                        ZipStream.Close();
                        return ReturnResult;
                    }
                    BinaryReader Reader = new BinaryReader(ZipStream);
                    SimpleList<string> LineData = IOUtil.BytesToLinesRemoveComments(Reader);
                    //find each level block
                    for ( A = 0; A <= LineData.Count - 1; A++ )
                    {
                        if ( Strings.LCase(Strings.Left(LineData[A], 5)) == "level" )
                        {
                            //find each levels game file
                            GameFound = false;
                            B = 1;
                            while ( A + B < LineData.Count )
                            {
                                if ( Strings.LCase(Strings.Left(Convert.ToString(LineData[A + B]), 4)) == "game" )
                                {
                                    C = Strings.InStr(Convert.ToString(LineData[A + B]), Quote, (CompareMethod)0);
                                    D = Strings.InStrRev(Convert.ToString(LineData[A + B]), Quote, -1, (CompareMethod)0);
                                    if ( C > 0 & D > 0 & D - C > 1 )
                                    {
                                        GameName = Strings.LCase(Strings.Mid(Convert.ToString(LineData[A + B]), C + 1, D - C - 1));
                                        //see if map is already counted
                                        for ( C = 0; C <= Maps.Count - 1; C++ )
                                        {
                                            if ( GameName == Maps[C].Name )
                                            {
                                                break;
                                            }
                                        }
                                        if ( C == Maps.Count )
                                        {
                                            GameFound = true;
                                        }
                                    }
                                    break;
                                }
                                else if ( Strings.LCase(Strings.Left(Convert.ToString(LineData[A + B]), 5)) == "level" )
                                {
                                    break;
                                }
                                B++;
                            }
                            if ( GameFound )
                            {
                                //find the dataset (determines tileset)
                                DatasetFound = false;
                                B = 1;
                                while ( A + B < LineData.Count )
                                {
                                    if ( Strings.LCase(Strings.Left(Convert.ToString(LineData[A + B]), 7)) == "dataset" )
                                    {
                                        strTemp = Strings.LCase(Strings.Right(Convert.ToString(LineData[A + B]), 1));
                                        if ( strTemp == "1" )
                                        {
                                            GameTileset = App.Tileset_Arizona;
                                            DatasetFound = true;
                                        }
                                        else if ( strTemp == "2" )
                                        {
                                            GameTileset = App.Tileset_Urban;
                                            DatasetFound = true;
                                        }
                                        else if ( strTemp == "3" )
                                        {
                                            GameTileset = App.Tileset_Rockies;
                                            DatasetFound = true;
                                        }
                                        break;
                                    }
                                    else if ( Strings.LCase(Strings.Left(Convert.ToString(LineData[A + B]), 5)) == "level" )
                                    {
                                        break;
                                    }
                                    B++;
                                }
                                if ( DatasetFound )
                                {
                                    clsWZMapEntry NewMap = new clsWZMapEntry();
                                    NewMap.Name = GameName;
                                    NewMap.Tileset = GameTileset;
                                    Maps.Add(NewMap);
                                }
                            }
                        }
                    }
                }
            } while ( true );
            ZipStream.Close();

            string MapLoadName = "";

            //prompt user for which of the entries to load
            if ( Maps.Count < 1 )
            {
                ReturnResult.ProblemAdd("No maps found in file.");
                return ReturnResult;
            }
            else if ( Maps.Count == 1 )
            {
                MapLoadName = Convert.ToString(Maps[0].Name);
                Tileset = Maps[0].Tileset;
            }
            else
            {
                frmWZLoad.clsOutput SelectToLoadResult = new frmWZLoad.clsOutput();
                string[] Names = new string[Maps.Count];
                for ( A = 0; A <= Maps.Count - 1; A++ )
                {
                    Names[A] = Convert.ToString(Maps[A].Name);
                }
                frmWZLoad SelectToLoadForm = new frmWZLoad(Names, SelectToLoadResult,
                    "Select a map from " + Convert.ToString(new App.sSplitPath(Path).FileTitle));
                SelectToLoadForm.ShowDialog();
                if ( SelectToLoadResult.Result < 0 )
                {
                    ReturnResult.ProblemAdd("No map selected.");
                    return ReturnResult;
                }
                MapLoadName = Convert.ToString(Maps[SelectToLoadResult.Result].Name);
                Tileset = Maps[SelectToLoadResult.Result].Tileset;
            }

            TileType_Reset();
            SetPainterToDefaults();

            ZipSplitPath GameSplitPath = new ZipSplitPath(MapLoadName);
            string GameFilesPath = GameSplitPath.FilePath + GameSplitPath.FileTitleWithoutExtension + "/";

            ZipStreamEntry ZipSearchResult = default(ZipStreamEntry);

            ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, MapLoadName);
            if ( ZipSearchResult == null )
            {
                ReturnResult.ProblemAdd("Game file not found.");
                return ReturnResult;
            }
            else
            {
                BinaryReader Map_Reader = new BinaryReader(ZipSearchResult.Stream);
                SubResult = Read_WZ_gam(Map_Reader);
                Map_Reader.Close();

                if ( !SubResult.Success )
                {
                    ReturnResult.ProblemAdd(SubResult.Problem);
                    return ReturnResult;
                }
            }

            ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, GameFilesPath + "game.map");
            if ( ZipSearchResult == null )
            {
                ReturnResult.ProblemAdd("game.map file not found");
                return ReturnResult;
            }
            else
            {
                BinaryReader Map_Reader = new BinaryReader(ZipSearchResult.Stream);
                SubResult = Read_WZ_map(Map_Reader);
                Map_Reader.Close();

                if ( !SubResult.Success )
                {
                    ReturnResult.ProblemAdd(SubResult.Problem);
                    return ReturnResult;
                }
            }

            SimpleClassList<clsWZBJOUnit> BJOUnits = new SimpleClassList<clsWZBJOUnit>();

            IniFeatures INIFeatures = null;

            ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, GameFilesPath + "feature.ini");
            if ( ZipSearchResult == null )
            {
            }
            else
            {
                clsResult Result = new clsResult("feature.ini");
                IniReader FeaturesINI = new IniReader();
                StreamReader FeaturesINI_Reader = new StreamReader(ZipSearchResult.Stream);
                Result.Take(FeaturesINI.ReadFile(FeaturesINI_Reader));
                FeaturesINI_Reader.Close();
                INIFeatures = new IniFeatures(FeaturesINI.Sections.Count);
                Result.Take(FeaturesINI.Translate(INIFeatures));
                ReturnResult.Add(Result);
            }

            if ( INIFeatures == null )
            {
                clsResult Result = new clsResult("feat.bjo");
                ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, GameFilesPath + "feat.bjo");
                if ( ZipSearchResult == null )
                {
                    Result.WarningAdd("file not found");
                }
                else
                {
                    BinaryReader Features_Reader = new BinaryReader(ZipSearchResult.Stream);
                    SubResult = Read_WZ_Features(Features_Reader, BJOUnits);
                    Features_Reader.Close();
                    if ( !SubResult.Success )
                    {
                        Result.WarningAdd(SubResult.Problem);
                    }
                }
                ReturnResult.Add(Result);
            }

            if ( true )
            {
                clsResult Result = new clsResult("ttypes.ttp");
                ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, GameFilesPath + "ttypes.ttp");
                if ( ZipSearchResult == null )
                {
                    Result.WarningAdd("file not found");
                }
                else
                {
                    BinaryReader TileTypes_Reader = new BinaryReader(ZipSearchResult.Stream);
                    SubResult = Read_WZ_TileTypes(TileTypes_Reader);
                    TileTypes_Reader.Close();
                    if ( !SubResult.Success )
                    {
                        Result.WarningAdd(SubResult.Problem);
                    }
                }
                ReturnResult.Add(Result);
            }

            IniStructures INIStructures = null;

            ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, GameFilesPath + "struct.ini");
            if ( ZipSearchResult == null )
            {
            }
            else
            {
                clsResult Result = new clsResult("struct.ini");
                IniReader StructuresINI = new IniReader();
                StreamReader StructuresINI_Reader = new StreamReader(ZipSearchResult.Stream);
                Result.Take(StructuresINI.ReadFile(StructuresINI_Reader));
                StructuresINI_Reader.Close();
                INIStructures = new IniStructures(StructuresINI.Sections.Count, this);
                Result.Take(StructuresINI.Translate(INIStructures));
                ReturnResult.Add(Result);
            }

            if ( INIStructures == null )
            {
                clsResult Result = new clsResult("struct.bjo");
                ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, GameFilesPath + "struct.bjo");
                if ( ZipSearchResult == null )
                {
                    Result.WarningAdd("file not found");
                }
                else
                {
                    BinaryReader Structures_Reader = new BinaryReader(ZipSearchResult.Stream);
                    SubResult = Read_WZ_Structures(Structures_Reader, BJOUnits);
                    Structures_Reader.Close();
                    if ( !SubResult.Success )
                    {
                        Result.WarningAdd(SubResult.Problem);
                    }
                }
                ReturnResult.Add(Result);
            }

            IniDroids INIDroids = null;

            ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, GameFilesPath + "droid.ini");
            if ( ZipSearchResult == null )
            {
            }
            else
            {
                clsResult Result = new clsResult("droid.ini");
                IniReader DroidsINI = new IniReader();
                StreamReader DroidsINI_Reader = new StreamReader(ZipSearchResult.Stream);
                Result.Take(DroidsINI.ReadFile(DroidsINI_Reader));
                DroidsINI_Reader.Close();
                INIDroids = new IniDroids(DroidsINI.Sections.Count, this);
                Result.Take(DroidsINI.Translate(INIDroids));
                ReturnResult.Add(Result);
            }

            if ( INIDroids == null )
            {
                clsResult Result = new clsResult("dinit.bjo");
                ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, GameFilesPath + "dinit.bjo");
                if ( ZipSearchResult == null )
                {
                    Result.WarningAdd("file not found");
                }
                else
                {
                    BinaryReader Droids_Reader = new BinaryReader(ZipSearchResult.Stream);
                    SubResult = Read_WZ_Droids(Droids_Reader, BJOUnits);
                    Droids_Reader.Close();
                    if ( !SubResult.Success )
                    {
                        Result.WarningAdd(SubResult.Problem);
                    }
                }
                ReturnResult.Add(Result);
            }

            sCreateWZObjectsArgs CreateObjectsArgs = new sCreateWZObjectsArgs();
            CreateObjectsArgs.BJOUnits = BJOUnits;
            CreateObjectsArgs.INIStructures = INIStructures;
            CreateObjectsArgs.INIDroids = INIDroids;
            CreateObjectsArgs.INIFeatures = INIFeatures;
            ReturnResult.Add(CreateWZObjects(CreateObjectsArgs));

            //objects are modified by this and must already exist
            ZipSearchResult = IOUtil.FindZipEntryFromPath(Path, GameFilesPath + "labels.ini");
            if ( ZipSearchResult == null )
            {
            }
            else
            {
                clsResult Result = new clsResult("labels.ini");
                IniReader LabelsINI = new IniReader();
                StreamReader LabelsINI_Reader = new StreamReader(ZipSearchResult.Stream);
                Result.Take(LabelsINI.ReadFile(LabelsINI_Reader));
                LabelsINI_Reader.Close();
                Result.Take(Read_WZ_Labels(LabelsINI, false));
                ReturnResult.Add(Result);
            }

            return ReturnResult;
        }