Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="package"></param>
        /// <returns></returns>
        public static string ComputeUID(IReadOnlyPackage package)
        {
            var requiredFiles = new[] { "map.yaml", "map.bin" };
            var contents      = package.Contents.ToList();

            foreach (var required in requiredFiles)
            {
                if (!contents.Contains(required))
                {
                    throw new FileNotFoundException("Required file {0} not present in this map".F(required));
                }
            }

            //using(var ms = new MemoryStream())
            //{
            //    foreach(var filename in contents)
            //    {
            //        if(filename.EndsWith(".yaml") || filename.EndsWith(".bin") || filename.EndsWith(".lua"))
            //        {
            //            using (var s = package.GetStream(filename))
            //                s.CopyTo(ms);
            //        }
            //    }

            //    ms.Seek(0, SeekOrigin.Begin);
            //    return CryptoUtil.SHA1Hash(ms);
            //}
            var streams = new List <Stream>();

            try
            {
                foreach (var filename in contents)
                {
                    if (filename.EndsWith(".yaml") || filename.EndsWith(".bin") || filename.EndsWith(".lua"))
                    {
                        streams.Add(package.GetStream(filename));
                    }
                }

                //Take the SHA1
                if (streams.Count == 0)
                {
                    return(CryptoUtil.SHA1Hash(new byte[0]));
                }

                var merged = streams[0];
                for (var i = 1; i < streams.Count; i++)
                {
                    merged = new MergedStream(merged, streams[i]);
                }

                return(CryptoUtil.SHA1Hash(merged));
            }
            finally{
                foreach (var stream in streams)
                {
                    stream.Dispose();
                }
            }
        }
Example #2
0
        public static string ComputeUID(IReadOnlyPackage package)
        {
            // UID is calculated by taking an SHA1 of the yaml and binary data
            var requiredFiles = new[] { "map.yaml", "map.bin" };
            var contents      = package.Contents.ToList();

            foreach (var required in requiredFiles)
            {
                if (!contents.Contains(required))
                {
                    throw new FileNotFoundException("Required file {0} not present in this map".F(required));
                }
            }

            using (var ms = new MemoryStream())
            {
                foreach (var filename in contents)
                {
                    if (filename.EndsWith(".yaml") || filename.EndsWith(".bin") || filename.EndsWith(".lua"))
                    {
                        using (var s = package.GetStream(filename))
                            s.CopyTo(ms);
                    }
                }

                // Take the SHA1
                ms.Seek(0, SeekOrigin.Begin);
                return(CryptoUtil.SHA1Hash(ms));
            }
        }
Example #3
0
        public IReadOnlyPackage OpenPackage(string filename, IReadOnlyPackage parent)
        {
            // HACK: limit support to zip and folder until we generalize the PackageLoader support
            if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase) ||
                filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
            {
                using (var s = parent.GetStream(filename))
                    return(new ZipFile(s, filename, parent));
            }

            if (parent is ZipFile)
            {
                return(new ZipFolder(this, (ZipFile)parent, filename, filename));
            }

            if (parent is ZipFolder)
            {
                var folder = (ZipFolder)parent;
                return(new ZipFolder(this, folder.Parent, folder.Name + "/" + filename, filename));
            }

            if (parent is Folder)
            {
                var subFolder = Platform.ResolvePath(Path.Combine(parent.Name, filename));
                if (Directory.Exists(subFolder))
                {
                    return(new Folder(subFolder));
                }
            }

            return(null);
        }
Example #4
0
        public IReadOnlyPackage OpenPackage(string filename, IReadOnlyPackage parent)
        {
            // HACK: limit support to zip and folder until we generalize the PackageLoader support
            if (parent is Folder)
            {
                var path = Path.Combine(parent.Name, filename);

                // HACK: work around SharpZipLib's lack of support for writing to in-memory files
                if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
                {
                    return(new ZipFile(this, path));
                }
                if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
                {
                    return(new ZipFile(this, path));
                }

                var subFolder = Platform.ResolvePath(path);
                if (Directory.Exists(subFolder))
                {
                    return(new Folder(subFolder));
                }
            }

            if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
            {
                return(new ZipFile(this, filename, parent.GetStream(filename)));
            }
            if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
            {
                return(new ZipFile(this, filename, parent.GetStream(filename)));
            }

            if (parent is ZipFile)
            {
                return(new ZipFolder(this, (ZipFile)parent, filename, filename));
            }

            if (parent is ZipFolder)
            {
                var folder = (ZipFolder)parent;
                return(new ZipFolder(this, folder.Parent, folder.Name + "/" + filename, filename));
            }

            return(null);
        }
Example #5
0
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary <string, MiniYaml> yaml;

            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                {
                    throw new FileNotFoundException("Required file map.yaml not present in this map");
                }

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml", stringPool: cache.StringPool)).ToDictionary();
            }

            Package       = p;
            parentPackage = parent;

            var newData = innerData.Clone();

            newData.GridType = gridType;
            newData.Class    = classification;

            if (yaml.TryGetValue("MapFormat", out var temp))
            {
                var format = FieldLoader.GetValue <int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                {
                    throw new InvalidDataException($"Map format {format} is not supported.");
                }
            }

            if (yaml.TryGetValue("Title", out temp))
            {
                newData.Title = temp.Value;
            }

            if (yaml.TryGetValue("Categories", out temp))
            {
                newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value);
            }

            if (yaml.TryGetValue("Tileset", out temp))
            {
                newData.TileSet = temp.Value;
            }

            if (yaml.TryGetValue("Author", out temp))
            {
                newData.Author = temp.Value;
            }

            if (yaml.TryGetValue("Bounds", out temp))
            {
                newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value);
            }

            if (yaml.TryGetValue("Visibility", out temp))
            {
                newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value);
            }

            string requiresMod = string.Empty;

            if (yaml.TryGetValue("RequiresMod", out temp))
            {
                requiresMod = temp.Value;
            }

            if (yaml.TryGetValue("MapFormat", out temp))
            {
                newData.MapFormat = FieldLoader.GetValue <int>("MapFormat", temp.Value);
            }

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                             MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                if (yaml.TryGetValue("Actors", out var actorDefinitions))
                {
                    var spawns = new List <CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.Get <LocationInit>().Value);
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                {
                    newData.SpawnPoints = Array.Empty <CPos>();
                }
            }
            catch (Exception)
            {
                newData.SpawnPoints = Array.Empty <CPos>();
                newData.Status      = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                if (yaml.TryGetValue("Players", out var playerDefinitions))
                {
                    newData.Players     = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetCustomRules(modData, this, yaml);

            if (p.Contains("map.png"))
            {
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Png(dataStream);
            }

            // Assign the new data atomically
            innerData = newData;
        }
Example #6
0
        public Manifest(string modId, IReadOnlyPackage package)
        {
            Id      = modId;
            Package = package;

            var nodes = MiniYaml.FromStream(package.GetStream("mod.yaml"), "mod.yaml");

            for (var i = nodes.Count - 1; i >= 0; i--)
            {
                if (nodes[i].Key != "Include")
                {
                    continue;
                }

                // Replace `Includes: filename.yaml` with the contents of filename.yaml
                var filename = nodes[i].Value.Value;
                var contents = package.GetStream(filename);
                if (contents == null)
                {
                    throw new YamlException("{0}: File `{1}` not found.".F(nodes[i].Location, filename));
                }

                nodes.RemoveAt(i);
                nodes.InsertRange(i, MiniYaml.FromStream(contents, filename));
            }

            // Merge inherited overrides
            yaml = new MiniYaml(null, MiniYaml.Merge(new[] { nodes })).ToDictionary();

            Metadata = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);

            // TODO: Use fieldloader
            MapFolders = YamlDictionary(yaml, "MapFolders");

            if (yaml.TryGetValue("Packages", out var packages))
            {
                Packages = packages.ToDictionary(x => x.Value);
            }

            Rules          = YamlList(yaml, "Rules");
            Sequences      = YamlList(yaml, "Sequences");
            ModelSequences = YamlList(yaml, "ModelSequences");
            Cursors        = YamlList(yaml, "Cursors");
            Chrome         = YamlList(yaml, "Chrome");
            Assemblies     = YamlList(yaml, "Assemblies");
            ChromeLayout   = YamlList(yaml, "ChromeLayout");
            Weapons        = YamlList(yaml, "Weapons");
            Voices         = YamlList(yaml, "Voices");
            Notifications  = YamlList(yaml, "Notifications");
            Music          = YamlList(yaml, "Music");
            TileSets       = YamlList(yaml, "TileSets");
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics");
            Missions       = YamlList(yaml, "Missions");
            Hotkeys        = YamlList(yaml, "Hotkeys");

            ServerTraits = YamlList(yaml, "ServerTraits");

            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("`LoadScreen` section is not defined.");
            }

            // Allow inherited mods to import parent maps.
            var compat = new List <string> {
                Id
            };

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                compat.AddRange(yaml["SupportsMapsFrom"].Value.Split(',').Select(c => c.Trim()));
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("PackageFormats"))
            {
                PackageFormats = FieldLoader.GetValue <string[]>("PackageFormats", yaml["PackageFormats"].Value);
            }

            if (yaml.ContainsKey("SoundFormats"))
            {
                SoundFormats = FieldLoader.GetValue <string[]>("SoundFormats", yaml["SoundFormats"].Value);
            }

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }

            if (yaml.ContainsKey("VideoFormats"))
            {
                VideoFormats = FieldLoader.GetValue <string[]>("VideoFormats", yaml["VideoFormats"].Value);
            }
        }
Example #7
0
        public Map(ModData modData, IReadOnlyPackage package)
        {
            this.modData = modData;
            Package      = package;

            if (!Package.Contains("map.yaml") || !Package.Contains("map.bin"))
            {
                throw new InvalidDataException("Not a valid map\n File: {0}".F(package.Name));
            }

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name));

            foreach (var field in YamlFields)
            {
                field.Deserialize(this, yaml.Nodes);
            }

            if (MapFormat != SupportedMapFormat)
            {
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name));
            }

            PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
            ActorDefinitions  = MiniYaml.NodesOrEmpty(yaml, "Actors");

            Grid = modData.Manifest.Get <MapGrid>();

            var size = new Size(MapSize.X, MapSize.Y);

            Tiles     = new CellLayer <TerrainTile>(Grid.Type, size);
            Resources = new CellLayer <ResourceTile>(Grid.Type, size);
            Height    = new CellLayer <byte>(Grid.Type, size);

            using (var s = Package.GetStream("map.bin"))
            {
                var header = new BinaryDataHeader(s, MapSize);
                if (header.TilesOffset > 0)
                {
                    s.Position = header.TilesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var tile  = s.ReadUInt16();
                            var index = s.ReadUInt8();

                            // TODO: Remember to remove this when rewriting tile variants / PickAny
                            if (index == byte.MaxValue)
                            {
                                index = (byte)(i % 4 + (j % 4) * 4);
                            }

                            Tiles[new MPos(i, j)] = new TerrainTile(tile, index);
                        }
                    }
                }

                if (header.ResourcesOffset > 0)
                {
                    s.Position = header.ResourcesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var type    = s.ReadUInt8();
                            var density = s.ReadUInt8();
                            Resources[new MPos(i, j)] = new ResourceTile(type, density);
                        }
                    }
                }

                if (header.HeightsOffset > 0)
                {
                    s.Position = header.HeightsOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            Height[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, Grid.MaximumTerrainHeight);
                        }
                    }
                }
            }

            if (Grid.MaximumTerrainHeight > 0)
            {
                Tiles.CellEntryChanged  += UpdateProjection;
                Height.CellEntryChanged += UpdateProjection;
            }

            PostInit();

            Uid = ComputeUID(Package);
        }
Example #8
0
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary <string, MiniYaml> yaml;

            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                {
                    throw new FileNotFoundException("Required file map.yaml not present in this map");
                }

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
            }

            Package       = p;
            parentPackage = parent;

            var newData = innerData.Clone();

            newData.GridType = gridType;
            newData.Class    = classification;

            MiniYaml temp;

            if (yaml.TryGetValue("MapFormat", out temp))
            {
                var format = FieldLoader.GetValue <int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                {
                    throw new InvalidDataException("Map format {0} is not supported.".F(format));
                }
            }

            if (yaml.TryGetValue("Title", out temp))
            {
                newData.Title = temp.Value;
            }

            if (yaml.TryGetValue("Categories", out temp))
            {
                newData.Categories = FieldLoader.GetValue <string[]>("Categories", temp.Value);
            }

            if (yaml.TryGetValue("Tileset", out temp))
            {
                newData.TileSet = temp.Value;
            }

            if (yaml.TryGetValue("Author", out temp))
            {
                newData.Author = temp.Value;
            }

            if (yaml.TryGetValue("Bounds", out temp))
            {
                newData.Bounds = FieldLoader.GetValue <Rectangle>("Bounds", temp.Value);
            }

            if (yaml.TryGetValue("Visibility", out temp))
            {
                newData.Visibility = FieldLoader.GetValue <MapVisibility>("Visibility", temp.Value);
            }

            string requiresMod = string.Empty;

            if (yaml.TryGetValue("RequiresMod", out temp))
            {
                requiresMod = temp.Value;
            }

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                             MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                MiniYaml actorDefinitions;
                if (yaml.TryGetValue("Actors", out actorDefinitions))
                {
                    var spawns = new List <CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.InitDict.Get <LocationInit>().Value(null));
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                {
                    newData.SpawnPoints = new CPos[0];
                }
            }
            catch (Exception)
            {
                newData.SpawnPoints = new CPos[0];
                newData.Status      = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                MiniYaml playerDefinitions;
                if (yaml.TryGetValue("Players", out playerDefinitions))
                {
                    newData.Players     = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetRulesetGenerator(modData, () =>
            {
                var ruleDefinitions          = LoadRuleSection(yaml, "Rules");
                var weaponDefinitions        = LoadRuleSection(yaml, "Weapons");
                var voiceDefinitions         = LoadRuleSection(yaml, "Voices");
                var musicDefinitions         = LoadRuleSection(yaml, "Music");
                var notificationDefinitions  = LoadRuleSection(yaml, "Notifications");
                var sequenceDefinitions      = LoadRuleSection(yaml, "Sequences");
                var modelSequenceDefinitions = LoadRuleSection(yaml, "ModelSequences");
                var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
                                         voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions, modelSequenceDefinitions);
                var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
                                                               weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                return(Pair.New(rules, flagged));
            });

            if (p.Contains("map.png"))
            {
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Bitmap(dataStream);
            }

            // Assign the new data atomically
            innerData = newData;
        }
Example #9
0
        public void UpdateFromMap(IReadOnlyPackage p, IReadOnlyPackage parent, MapClassification classification, string[] mapCompatibility, MapGridType gridType)
        {
            Dictionary<string, MiniYaml> yaml;
            using (var yamlStream = p.GetStream("map.yaml"))
            {
                if (yamlStream == null)
                    throw new FileNotFoundException("Required file map.yaml not present in this map");

                yaml = new MiniYaml(null, MiniYaml.FromStream(yamlStream, "map.yaml")).ToDictionary();
            }

            Package = p;
            parentPackage = parent;

            var newData = innerData.Clone();
            newData.GridType = gridType;
            newData.Class = classification;

            MiniYaml temp;
            if (yaml.TryGetValue("MapFormat", out temp))
            {
                var format = FieldLoader.GetValue<int>("MapFormat", temp.Value);
                if (format != Map.SupportedMapFormat)
                    throw new InvalidDataException("Map format {0} is not supported.".F(format));
            }

            if (yaml.TryGetValue("Title", out temp))
                newData.Title = temp.Value;

            if (yaml.TryGetValue("Categories", out temp))
                newData.Categories = FieldLoader.GetValue<string[]>("Categories", temp.Value);

            if (yaml.TryGetValue("Tileset", out temp))
                newData.TileSet = temp.Value;

            if (yaml.TryGetValue("Author", out temp))
                newData.Author = temp.Value;

            if (yaml.TryGetValue("Bounds", out temp))
                newData.Bounds = FieldLoader.GetValue<Rectangle>("Bounds", temp.Value);

            if (yaml.TryGetValue("Visibility", out temp))
                newData.Visibility = FieldLoader.GetValue<MapVisibility>("Visibility", temp.Value);

            string requiresMod = string.Empty;
            if (yaml.TryGetValue("RequiresMod", out temp))
                requiresMod = temp.Value;

            newData.Status = mapCompatibility == null || mapCompatibility.Contains(requiresMod) ?
                MapStatus.Available : MapStatus.Unavailable;

            try
            {
                // Actor definitions may change if the map format changes
                MiniYaml actorDefinitions;
                if (yaml.TryGetValue("Actors", out actorDefinitions))
                {
                    var spawns = new List<CPos>();
                    foreach (var kv in actorDefinitions.Nodes.Where(d => d.Value.Value == "mpspawn"))
                    {
                        var s = new ActorReference(kv.Value.Value, kv.Value.ToDictionary());
                        spawns.Add(s.InitDict.Get<LocationInit>().Value(null));
                    }

                    newData.SpawnPoints = spawns.ToArray();
                }
                else
                    newData.SpawnPoints = new CPos[0];
            }
            catch (Exception)
            {
                newData.SpawnPoints = new CPos[0];
                newData.Status = MapStatus.Unavailable;
            }

            try
            {
                // Player definitions may change if the map format changes
                MiniYaml playerDefinitions;
                if (yaml.TryGetValue("Players", out playerDefinitions))
                {
                    newData.Players = new MapPlayers(playerDefinitions.Nodes);
                    newData.PlayerCount = newData.Players.Players.Count(x => x.Value.Playable);
                }
            }
            catch (Exception)
            {
                newData.Status = MapStatus.Unavailable;
            }

            newData.SetRulesetGenerator(modData, () =>
            {
                var ruleDefinitions = LoadRuleSection(yaml, "Rules");
                var weaponDefinitions = LoadRuleSection(yaml, "Weapons");
                var voiceDefinitions = LoadRuleSection(yaml, "Voices");
                var musicDefinitions = LoadRuleSection(yaml, "Music");
                var notificationDefinitions = LoadRuleSection(yaml, "Notifications");
                var sequenceDefinitions = LoadRuleSection(yaml, "Sequences");
                var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
                    voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
                var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
                    weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                return Pair.New(rules, flagged);
            });

            if (p.Contains("map.png"))
                using (var dataStream = p.GetStream("map.png"))
                    newData.Preview = new Bitmap(dataStream);

            // Assign the new data atomically
            innerData = newData;
        }
Example #10
0
        public Manifest(string modId, IReadOnlyPackage package)
        {
            Id      = modId;
            Package = package;
            yaml    = new MiniYaml(null, MiniYaml.FromStream(package.GetStream("mod.yaml"), "mod.yaml")).ToDictionary();

            Metadata = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);

            // TODO: Use fieldloader
            MapFolders = YamlDictionary(yaml, "MapFolders");

            MiniYaml packages;

            if (yaml.TryGetValue("Packages", out packages))
            {
                Packages = packages.ToDictionary(x => x.Value).AsReadOnly();
            }

            Rules          = YamlList(yaml, "Rules");
            Sequences      = YamlList(yaml, "Sequences");
            ModelSequences = YamlList(yaml, "ModelSequences");
            Cursors        = YamlList(yaml, "Cursors");
            Chrome         = YamlList(yaml, "Chrome");
            Assemblies     = YamlList(yaml, "Assemblies");
            ChromeLayout   = YamlList(yaml, "ChromeLayout");
            Weapons        = YamlList(yaml, "Weapons");
            Voices         = YamlList(yaml, "Voices");
            Notifications  = YamlList(yaml, "Notifications");
            Music          = YamlList(yaml, "Music");
            Translations   = YamlList(yaml, "Translations");
            TileSets       = YamlList(yaml, "TileSets");
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics");
            Missions       = YamlList(yaml, "Missions");
            Hotkeys        = YamlList(yaml, "Hotkeys");

            ServerTraits = YamlList(yaml, "ServerTraits");

            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("`LoadScreen` section is not defined.");
            }

            // Allow inherited mods to import parent maps.
            var compat = new List <string> {
                Id
            };

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                compat.AddRange(yaml["SupportsMapsFrom"].Value.Split(',').Select(c => c.Trim()));
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("PackageFormats"))
            {
                PackageFormats = FieldLoader.GetValue <string[]>("PackageFormats", yaml["PackageFormats"].Value);
            }

            if (yaml.ContainsKey("SoundFormats"))
            {
                SoundFormats = FieldLoader.GetValue <string[]>("SoundFormats", yaml["SoundFormats"].Value);
            }

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }
        }
Example #11
0
        public IReadOnlyPackage OpenPackage(string filename, IReadOnlyPackage parent)
        {
            // HACK: limit support to zip and folder until we generalize the PackageLoader support
            if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase) ||
                filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
            {
                using (var s = parent.GetStream(filename))
                    return new ZipFile(s, filename, parent);
            }

            if (parent is ZipFile)
                return new ZipFolder(this, (ZipFile)parent, filename, filename);

            if (parent is ZipFolder)
            {
                var folder = (ZipFolder)parent;
                return new ZipFolder(this, folder.Parent, folder.Name + "/" + filename, filename);
            }

            if (parent is Folder)
            {
                var subFolder = Platform.ResolvePath(Path.Combine(parent.Name, filename));
                if (Directory.Exists(subFolder))
                    return new Folder(subFolder);
            }

            return null;
        }
Example #12
0
File: Map.cs Project: pchote/OpenRA
        public static string ComputeUID(IReadOnlyPackage package)
        {
            // UID is calculated by taking an SHA1 of the yaml and binary data
            var requiredFiles = new[] { "map.yaml", "map.bin" };
            var contents = package.Contents.ToList();
            foreach (var required in requiredFiles)
                if (!contents.Contains(required))
                    throw new FileNotFoundException("Required file {0} not present in this map".F(required));

            using (var ms = new MemoryStream())
            {
                foreach (var filename in contents)
                    if (filename.EndsWith(".yaml") || filename.EndsWith(".bin") || filename.EndsWith(".lua"))
                        using (var s = package.GetStream(filename))
                            s.CopyTo(ms);

                // Take the SHA1
                ms.Seek(0, SeekOrigin.Begin);
                return CryptoUtil.SHA1Hash(ms);
            }
        }
Example #13
0
File: Map.cs Project: pchote/OpenRA
        public Map(ModData modData, IReadOnlyPackage package)
        {
            this.modData = modData;
            Package = package;

            if (!Package.Contains("map.yaml") || !Package.Contains("map.bin"))
                throw new InvalidDataException("Not a valid map\n File: {0}".F(package.Name));

            var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name));
            foreach (var field in YamlFields)
                field.Deserialize(this, yaml.Nodes);

            if (MapFormat != SupportedMapFormat)
                throw new InvalidDataException("Map format {0} is not supported.\n File: {1}".F(MapFormat, package.Name));

            PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
            ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors");

            Grid = modData.Manifest.Get<MapGrid>();

            var size = new Size(MapSize.X, MapSize.Y);
            Tiles = new CellLayer<TerrainTile>(Grid.Type, size);
            Resources = new CellLayer<ResourceTile>(Grid.Type, size);
            Height = new CellLayer<byte>(Grid.Type, size);

            using (var s = Package.GetStream("map.bin"))
            {
                var header = new BinaryDataHeader(s, MapSize);
                if (header.TilesOffset > 0)
                {
                    s.Position = header.TilesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var tile = s.ReadUInt16();
                            var index = s.ReadUInt8();

                            // TODO: Remember to remove this when rewriting tile variants / PickAny
                            if (index == byte.MaxValue)
                                index = (byte)(i % 4 + (j % 4) * 4);

                            Tiles[new MPos(i, j)] = new TerrainTile(tile, index);
                        }
                    }
                }

                if (header.ResourcesOffset > 0)
                {
                    s.Position = header.ResourcesOffset;
                    for (var i = 0; i < MapSize.X; i++)
                    {
                        for (var j = 0; j < MapSize.Y; j++)
                        {
                            var type = s.ReadUInt8();
                            var density = s.ReadUInt8();
                            Resources[new MPos(i, j)] = new ResourceTile(type, density);
                        }
                    }
                }

                if (header.HeightsOffset > 0)
                {
                    s.Position = header.HeightsOffset;
                    for (var i = 0; i < MapSize.X; i++)
                        for (var j = 0; j < MapSize.Y; j++)
                            Height[new MPos(i, j)] = s.ReadUInt8().Clamp((byte)0, Grid.MaximumTerrainHeight);
                }
            }

            if (Grid.MaximumTerrainHeight > 0)
            {
                Tiles.CellEntryChanged += UpdateProjection;
                Height.CellEntryChanged += UpdateProjection;
            }

            PostInit();

            Uid = ComputeUID(Package);
        }
Example #14
0
        public Manifest(string modId, IReadOnlyPackage package)
        {
            Id      = modId;
            Package = package;

            yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("mod.yaml"), "mod.yaml")).ToDictionary();

            Metadata = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);

            MapFolders = YamlDictionary(yaml, "MapFolders");

            MiniYaml packages;

            if (yaml.TryGetValue("Packages", out packages))
            {
                Packages = packages.ToDictionary(x => x.Value).AsReadOnly();
            }
            Rules          = YamlList(yaml, "Rules");
            Sequences      = YamlList(yaml, "Sequences");
            ModelSequences = YamlList(yaml, "ModelSequences");
            Assemblies     = YamlList(yaml, "Assemblies");
            Weapons        = YamlList(yaml, "Weapons");
            Voices         = YamlList(yaml, "Voices");
            Notifications  = YamlList(yaml, "Notifications");
            Music          = YamlList(yaml, "Music");
            TileSets       = YamlList(yaml, "TileSets");
            Missions       = YamlList(yaml, "Missions");
            ServerTraits   = YamlList(yaml, "ServerTraits");
            Chrome         = YamlList(yaml, "Chrome");
            ChromeLayout   = YamlList(yaml, "ChromeLayout");
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics");
            Fonts          = yaml["Fonts"].ToDictionary(my =>
            {
                var nd = my.ToDictionary();
                return(Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value)));
            });
            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("'LoadScreen' section is not defined.");
            }

            var compat = new List <string> {
                Id
            };

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                compat.AddRange(yaml["SupportsMapsFrom"].Value.Split(',').Select(c => c.Trim()));
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }

            if (yaml.ContainsKey("PackageFormats"))
            {
                PackageFormats = FieldLoader.GetValue <string[]>("PackageFormats", yaml["PackageFormats"].Value);
            }

            if (yaml.ContainsKey("SoundFormats"))
            {
                SoundFormats = FieldLoader.GetValue <string[]>("SoundFormats", yaml["SoundFormats"].Value);
            }
        }