Esempio n. 1
0
        /// <summary>
        /// Returns true if the given prop matches the options selected
        /// on the form.
        /// </summary>
        /// <param name="prop">The prop to check.</param>
        /// <param name="notFoundInDb">
        /// Default value for props that couldn't be found in the loaded
        /// data while filters are applied.
        /// </param>
        /// <returns></returns>
        public bool Matches(Prop prop, bool notFoundInDb)
        {
            if (this.ChkAllProps.Checked)
            {
                return(true);
            }

            if (!PropDb.TryGetEntry(prop.Id, out var data))
            {
                return(notFoundInDb);
            }

            if (this.ChkMatchID.Checked)
            {
                if (data.ClassID.ToString() != this.TxtMatchID.Text.Trim())
                {
                    return(false);
                }
            }

            if (this.ChkMatchClassName.Checked)
            {
                if (data.ClassName != this.TxtMatchClassName.Text.Trim())
                {
                    return(false);
                }
            }

            if (this.ChkNotMatchClassName.Checked)
            {
                if (string.Compare(data.ClassName, this.TxtNotMatchClassName.Text.Trim(), true) == 0)
                {
                    return(false);
                }
            }

            if (this.ChkMatchTag.Checked)
            {
                if (!data.StringID.Matches(this.TxtMatchTag.Text))
                {
                    return(false);
                }
            }

            if (this.ChkNotMatchTag.Checked)
            {
                if (data.StringID.Matches(this.TxtNotMatchTag.Text))
                {
                    return(false);
                }
            }

            if (this.ChkTerrain.Checked)
            {
                if (this.ChkTerrainYes.Checked)
                {
                    if (!data.IsTerrainBlock)
                    {
                        return(false);
                    }
                }
                else if (data.IsTerrainBlock)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Reads given folders and generates regioninfo.dat.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void BtnCreate_Click(object sender, EventArgs e)
        {
            this.UpdateProgressBar(-1);
            this.BtnCreate.Enabled  = false;
            this.TxtSources.Enabled = false;
            this.LblStatus.Text     = "Reading files...";

            var regions = new Dictionary <int, MabiWorld.Region>();

            // Run in task to not block UI
            await Task.Run(() =>
            {
                // Read regions from folders
                foreach (var line in this.TxtSources.Lines)
                {
                    var trimmedLine = line.Trim();

                    if (trimmedLine == "" || trimmedLine.StartsWith("//"))
                    {
                        continue;
                    }

                    if (!Directory.Exists(line))
                    {
                        this.Invoke((MethodInvoker) delegate
                        {
                            MessageBox.Show(this, $"Directory '{line}' not found.", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        });
                        continue;
                    }

                    if (Directory.EnumerateFiles(line, "*.pack", SearchOption.TopDirectoryOnly).Any())
                    {
                        this.GetRegionsFromPacks(line, ref regions);
                    }
                    else
                    {
                        this.GetRegionsFromFolder(line, ref regions);
                    }
                }

                // Remove props from areas that are only enabled during
                // certain events or when features are enabled that are
                // currently not.
                // TODO: Include all props and let the server handle this.
                foreach (var area in regions.Values.SelectMany(a => a.Areas))
                {
                    area.Props.RemoveAll(prop =>
                    {
                        if (!PropDb.TryGetEntry(prop.Id, out var data))
                        {
                            return(false);
                        }

                        if (data.StringID.Value.Contains("/event/") && data.UsedServer)
                        {
                            return(true);
                        }

                        // Some invisible prop at Dunbarton's Unicorn statue
                        if (data.StringID.Value.Contains("/weekly_concert/"))
                        {
                            return(true);
                        }

                        // Invisible Emain cooking contest props
                        if (data.StringID.Value.Contains("/contest/"))
                        {
                            return(true);
                        }

                        // Invisible Emain concert hall barricade
                        if (data.ClassName == "scene_emain_concert_hall_barricade01")
                        {
                            return(true);
                        }

                        // Invisible Gairech Halloween event prop
                        if (data.ClassName == "field_gairech_halloween2018_portal_place01")
                        {
                            // Controlled by the locale ExtraXML property,
                            // where "usa" is not negated while the event is
                            // active <_> WHY DO YOU HATE SERVER SIDED PROPS
                            // DEVCAT!? >__>
                            // ExtraXML="&lt;xml locale=&quot;!korea|usa|japan|!taiwan|!china&quot;/&gt;"
                            if (data.ExtraXML.Contains("!usa"))
                            {
                                return(true);
                            }
                        }

                        if (!string.IsNullOrWhiteSpace(data.Feature) && !Features.IsEnabled(data.Feature))
                        {
                            return(true);
                        }

                        return(false);
                    });
                }
            });

            // Update UI and move region info
            this.Invoke((MethodInvoker) delegate
            {
                this.UpdateProgressBar(0);
                this.UpdateStatus($"Found {regions.Count} regions.");
                this.BtnCreate.Enabled  = true;
                this.TxtSources.Enabled = true;

                if (regions.Count == 0)
                {
                    MessageBox.Show(this, "No regions found.", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                var result = this.SfdRegionInfo.ShowDialog();
                if (result == DialogResult.OK)
                {
                    this.BtnCreate.Select();

                    var filePath   = this.SfdRegionInfo.FileName;
                    var folderPath = Path.GetDirectoryName(filePath);

                    Settings.Default.SaveFolder = folderPath;
                    this.Export(filePath, regions);

                    this.UpdateStatus($"Saved region info at '{filePath}'.");
                }
                else
                {
                    this.UpdateStatus($"Saving cancelled.");
                }
            });
        }
Esempio n. 3
0
        /// <summary>
        /// Reads world.trn in packs and all regions that are listed within.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="regions"></param>
        private void GetRegionsFromPacks(string path, ref Dictionary <int, MabiWorld.Region> regions)
        {
            using (var pack = new PackReader(path))
            {
                var worldEntry = pack.GetEntry(@"world\world.trn");
                if (worldEntry == null)
                {
                    this.Invoke((MethodInvoker) delegate
                    {
                        MessageBox.Show(this, $"File 'world.trn' not found in pack folder '{path}'.", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    });
                    return;
                }

                var propEntry = pack.GetEntry(@"db\propdb.xml");
                if (propEntry != null)
                {
                    PropDb.Clear();
                    PropDb.Load(propEntry.GetDataAsStream());
                }

                var featureEntry = pack.GetEntry(@"features.xml.compiled");
                if (featureEntry != null)
                {
                    Features.Clear();
                    Features.Load(featureEntry.GetDataAsStream());
                    Features.SelectSetting("USA", false, false);
                }

                using (var ms = worldEntry.GetDataAsStream())
                    using (var trnReader = new XmlTextReader(ms))
                    {
                        if (!trnReader.ReadToDescendant("regions"))
                        {
                            throw new FormatException("Tag 'regions' not found in world.trn.");
                        }

                        using (var trnRegionsReader = trnReader.ReadSubtree())
                        {
                            while (trnRegionsReader.ReadToFollowing("region"))
                            {
                                var workDir        = trnRegionsReader.GetAttribute("workdir");
                                var fileName       = trnReader.GetAttribute("name");
                                var regionFilePath = Path.Combine("world", workDir, fileName + ".rgn");
                                var regionEntry    = pack.GetEntry(regionFilePath);

                                if (regionEntry == null)
                                {
                                    continue;
                                }

                                using (var regionStream = regionEntry.GetDataAsStream())
                                {
                                    this.UpdateStatus($"Reading {fileName}...");

                                    var region = MabiWorld.Region.ReadFrom(regionStream);
                                    regions[region.Id] = region;

                                    for (var i = 0; i < region.AreaFileNames.Count; ++i)
                                    {
                                        var areaFileName = region.AreaFileNames[i];
                                        var areaFilePath = Path.Combine("world", workDir, areaFileName + ".area");

                                        using (var areaStream = pack.GetEntry(areaFilePath).GetDataAsStream())
                                        {
                                            var area = Area.ReadFrom(areaStream);
                                            area.AreaPlanes.Clear();
                                            region.Areas.Add(area);
                                        }
                                    }
                                }
                            }
                        }
                    }
            }
        }