示例#1
0
        private static void LoadStringData(TSettings settings)
        {
            var path = Path.Combine(settings.GamePath, Dictionary);

            using var packageStream = File.OpenRead(path);

            using var packageReader = new BinaryReader(packageStream);

            var package = UltimaPackage.FromReader(packageReader);

            var file = package.GetBlocks(packageReader).Single().GetFiles(packageReader).Single();

            file.GetData(packageReader, (reader, total) =>
            {
                reader.ReadBytes(0x10);

                var current = 0x10;

                while (current < total)
                {
                    var length = reader.ReadInt16();

                    var bytes = reader.ReadBytes(length);

                    var name = System.Text.Encoding.ASCII.GetString(bytes).Split('%').First();

                    settings.StringData.Add(name);

                    current += 2 + length;
                }
            });
        }
示例#2
0
        private static void LoadCsvDocuments(TSettings settings)
        {
            settings.CsvDocuments.Clear();

            var path = Path.Combine(settings.GamePath, GameData);

            using var packageStream = File.OpenRead(path);

            using var packageReader = new BinaryReader(packageStream);

            var package = UltimaPackage.FromReader(packageReader);

            var buffer = new byte[100];

            foreach (var file in package.GetBlocks(packageReader).SelectMany(b => b.GetFiles(packageReader)))
            {
                file.GetData(packageReader, (reader, total) =>
                {
                    using var text = new StreamReader(reader.BaseStream, leaveOpen: true);

                    var lines = new List <string>();

                    string line;

                    while ((line = text.ReadLine()) != null)
                    {
                        if (line.StartsWith('#'))
                        {
                            continue;
                        }

                        lines.Add(line);
                    }

                    settings.CsvDocuments.Add(file.FileNameHash, new TCsvDocument
                    {
                        Header = lines.First().Split(','),
                        Data   = lines
                                 .Skip(1)
                                 .Select(l => l.Split(','))
                                 .SelectMany(inner => inner.Select((item, index) => new { item, index }))
                                 .GroupBy(i => i.index, i => i.item)
                                 .Select(g => g.ToArray())
                                 .ToArray()
                    });
                });
            }
        }
示例#3
0
        /*public static void LoadCliLoc(TSettings settings)
         * {
         *  var localization = new Dictionary<uint, string>();
         *
         *  var path = Path.Combine(settings.GamePath, Localization);
         *
         *  var package = new MythicPackage(path);
         *
         *  var file = package.Blocks.Single().Files.First();
         *
         *  var bytes = file.Unpack(path);
         *
         *  using var stream = new MemoryStream(bytes);
         *
         *  using var reader = new BinaryReader(stream);
         *
         *  stream.Seek(0x6, SeekOrigin.Begin);
         *
         *  while (stream.Position < stream.Length)
         *  {
         *      var key = reader.ReadUInt32();
         *
         *      stream.Seek(1, SeekOrigin.Current);
         *
         *      var length = reader.ReadUInt16();
         *
         *      bytes = reader.ReadBytes(length);
         *
         *      var text = System.Text.Encoding.UTF8.GetString(bytes);
         *
         *      localization.Add(key, text);
         *  }
         * }*/

        private static void LoadTileArts(TSettings settings)
        {
            var path = Path.Combine(settings.GamePath, TileArt);

            using var packageStream = File.OpenRead(path);

            using var packageReader = new BinaryReader(packageStream);

            var package = UltimaPackage.FromReader(packageReader);

            var buffer = new byte[100];

            foreach (var file in package.GetBlocks(packageReader).SelectMany(b => b.GetFiles(packageReader)))
            {
                file.GetData(packageReader, (reader, total) =>
                {
                    reader.ReadInt16();

                    var index = reader.ReadInt32();

                    var name = settings.StringData[index > 0 ? index - 1 : 0];

                    var id = reader.ReadUInt16();

                    reader.BaseStream.Read(buffer, 0, 51);

                    var flags = reader.ReadUInt64();

                    reader.BaseStream.Read(buffer, 0, 48);

                    var count = reader.ReadByte();

                    var properties = new Dictionary <byte, int>();

                    for (var i = 0; i < count; i++)
                    {
                        properties[reader.ReadByte()] = reader.ReadInt32();
                    }

                    if (!properties.TryGetValue(0, out var weight))
                    {
                        weight = 0;
                    }

                    if (!properties.TryGetValue(3, out var height))
                    {
                        height = 0;
                    }

                    if (!properties.TryGetValue(6, out var layer))
                    {
                        layer = 0;
                    }

                    settings.TileArts.Add(id, new TTileArt
                    {
                        Graphic = id,
                        Name    = name,
                        Flags   = flags,
                        Weight  = (ushort)weight,
                        Height  = height,
                        Layer   = (byte)layer
                    });
                });
            }
        }
示例#4
0
        public static void Import(BinaryReader uopReader, BinaryWriter uopWriter, string mapPath, string indexPath, string staticsPath, string radarPath, bool mulInMemory = false, Action <int> progress = null)
        {
            using var mapStream = mulInMemory ? new MemoryStream(File.ReadAllBytes(mapPath)) : (Stream)File.OpenRead(mapPath);

            using var mapReader = new BinaryReader(mapStream);

            using var indexStream = mulInMemory ? new MemoryStream(File.ReadAllBytes(indexPath)) : (Stream)File.OpenRead(indexPath);

            using var indexReader = new BinaryReader(indexStream);

            using var staticsStream = mulInMemory ? new MemoryStream(File.ReadAllBytes(staticsPath)) : (Stream)File.OpenRead(staticsPath);

            using var staticsReader = new BinaryReader(staticsStream);

            using var radarStream = mulInMemory ? new MemoryStream(File.ReadAllBytes(radarPath)) : (Stream)File.OpenRead(radarPath);

            using var radarReader = new BinaryReader(radarStream);

            var package = UltimaPackage.FromReader(uopReader);

            var(width, height, facet) = (0, 0, 0);

            var firstBlock = package.GetBlocks(uopReader).First();

            var firstTwoFiles = firstBlock.GetFiles(uopReader).Take(2).ToArray();

            firstTwoFiles[0].GetData(uopReader, (r, _) =>
            {
                height = r.ReadInt32();

                width = r.ReadInt32();
            });

            firstTwoFiles[1].GetData(uopReader, (r, _) => facet = r.ReadByte());

            package.ToWriter(uopReader, uopWriter, (width, height, facet, mapReader, indexReader, staticsReader, radarReader, progress), (w, b, f, s) =>
            {
                if (b == 0 && f == 0)
                {
                    return(false);
                }

                var delimiters = new List <Action <byte> >();

                var statics = new Dictionary <int, Dictionary <(int x, int y), List <(ushort value, sbyte altitude, ushort unknown, ushort hue)> > >();

                var mapBlockId = 100 * b + f - 1;

                s.progress?.Invoke(100 * (mapBlockId + 1) / (width * height / 4096));

                for (var k = 0; k < 4096; k++)
                {
                    var(x, y) = GetCoordinatesFromUopIndex(mapBlockId, k, s.height);

                    var(mulMapBlock, mulBlockIndex) = GetMulIndexFromCoordinates(x, y, s.height);

                    var mulOffset = mulMapBlock * 4 + 4 + mulMapBlock * 64 * 3 + mulBlockIndex * 3;

                    if (mulOffset >= s.mapReader.BaseStream.Length)
                    {
                        return(false);
                    }

                    s.mapReader.BaseStream.Seek(mulOffset, SeekOrigin.Begin);

                    WriteTile(s.mapReader.ReadUInt16(), s.mapReader.ReadSByte());

                    void WriteTile(ushort value, sbyte altitude)
                    {
                        ushort graphic = 0;

                        byte unknown = 0;

                        if (TileCollection.Values.TryGetValue(value, out var val))
                        {
                            graphic = val.Item1;

                            unknown = val.Item2;
                        }

                        if (k == 0)
                        {
                            w.Write((byte)s.facet);

                            w.Write((ushort)mapBlockId);
                        }
                        else
                        {
                            w.Write((byte)0);

                            w.Write((byte)0);
                        }

                        w.Write(altitude);

                        w.Write(graphic);

                        w.Write(unknown);

                        w.Write((byte)(value & 0xFF));

                        w.Write((byte)(value >> 8));
                    }

                    delimiters.Clear();

                    if (x % 64 == 0)
                    {
                        AddDelimiter(x - 1, y, 0);
                    }

                    if (x % 64 == 0 && y % 64 == 0)
                    {
                        AddDelimiter(x - 1, y - 1, 1);
                    }

                    if (y % 64 == 0)
                    {
                        AddDelimiter(x, y - 1, 2);
                    }

                    if ((x + 1) % 64 == 0)
                    {
                        AddDelimiter(x + 1, y, 3);
                    }

                    if ((x + 1) % 64 == 0 && (y + 1) % 64 == 0)
                    {
                        AddDelimiter(x + 1, y + 1, 4);
                    }

                    if ((y + 1) % 64 == 0)
                    {
                        AddDelimiter(x, y + 1, 5);
                    }

                    if (x % 64 == 0 && (y + 1) % 64 == 0)
                    {
                        AddDelimiter(x - 1, y + 1, 6);
                    }

                    if (y % 64 == 0 && (x + 1) % 64 == 0)
                    {
                        AddDelimiter(x + 1, y - 1, 7);
                    }

                    for (var l = 0; l < delimiters.Count; l++)
                    {
                        if (l == 0)
                        {
                            delimiters[l].Invoke((byte)delimiters.Count);
                        }

                        else
                        {
                            delimiters[l].Invoke(0);
                        }
                    }

                    void AddDelimiter(int refX, int refY, byte direction)
                    {
                        if (refX < 0 || refY < 0)
                        {
                            return;
                        }

                        var(refMulMapBlock, refMulBlockIndex) = GetMulIndexFromCoordinates(refX, refY, s.height);

                        var refMulOffset = refMulMapBlock * 4 + 4 + refMulMapBlock * 64 * 3 + refMulBlockIndex * 3;

                        if (refMulOffset >= s.mapReader.BaseStream.Length)
                        {
                            return;
                        }

                        delimiters.Add(c => WriteDelimiter(refMulOffset, direction, c));
                    }

                    void WriteDelimiter(int refMulOffset, byte direction, byte count)
                    {
                        s.mapReader.BaseStream.Seek(refMulOffset, SeekOrigin.Begin);

                        var value = s.mapReader.ReadUInt16();

                        var altitude = s.mapReader.ReadSByte();

                        ushort graphic = 0;

                        byte unknown = 0;

                        if (TileCollection.Values.TryGetValue(value, out var val))
                        {
                            graphic = val.Item1;

                            unknown = val.Item2;
                        }

                        w.Write(count);

                        w.Write(direction);

                        w.Write(altitude);

                        w.Write(graphic);

                        w.Write(unknown);
                    }

                    if (!statics.TryGetValue(mulMapBlock, out var blockStatics))
                    {
                        ReadBlockStatics();
                    }

                    void ReadBlockStatics()
                    {
                        statics[mulMapBlock] = blockStatics = new Dictionary <(int x, int y), List <(ushort value, sbyte altitude, ushort unknown, ushort hue)> >();

                        s.indexReader.BaseStream.Seek(mulMapBlock * 12, SeekOrigin.Begin);

                        var indexValue = s.indexReader.ReadInt32();

                        var staticsEnd = indexValue + s.indexReader.ReadInt32();

                        s.indexReader.ReadInt32();

                        if (indexValue == -1)
                        {
                            return;
                        }

                        s.staticsReader.BaseStream.Seek(indexValue, SeekOrigin.Begin);

                        while (true)
                        {
                            if (s.staticsReader.BaseStream.Position == staticsEnd)
                            {
                                break;
                            }

                            var staticsValue = s.staticsReader.ReadUInt16();

                            s.radarReader.BaseStream.Seek(0x4000 + staticsValue, SeekOrigin.Begin);

                            var(staticX, staticY) = GetCoordinatesFromMulIndex(mulMapBlock, s.staticsReader.ReadByte() + 8 * s.staticsReader.ReadByte(), s.height);

                            var tileStatics = blockStatics.TryGetValue((staticX, staticY), out var entry) ? entry : blockStatics[(staticX, staticY)] = new List <(ushort value, sbyte altitude, ushort unknown, ushort hue)>();

                            var current = (staticsValue, s.staticsReader.ReadSByte(), s.staticsReader.ReadUInt16(), s.radarReader.ReadUInt16());

                            if (!StaticCollection.Values.Contains(staticsValue))
                            {
                                continue;
                            }

                            tileStatics.Add(current);
                        }
                    }