Exemple #1
0
        public static byte[] Convert(RealmManager manager, string json)
        {
            json_dat obj = JsonConvert.DeserializeObject <json_dat>(json);

            byte[] dat = ZlibStream.UncompressBuffer(obj.data);

            Dictionary <ushort, TerrainTile> tileDict = new Dictionary <ushort, TerrainTile>();

            for (int i = 0; i < obj.dict.Length; i++)
            {
                loc o = obj.dict[i];
                tileDict[(ushort)i] = new TerrainTile
                {
                    TileId  = o.ground == null ? (ushort)0xff : manager.GameData.IdToTileType[o.ground],
                    TileObj = o.objs == null ? null : o.objs[0].id,
                    Name    = o.objs == null ? "" : o.objs[0].name ?? "",
                    Terrain = TerrainType.None,
                    Region  =
                        o.regions == null
                            ? TileRegion.None
                            : (TileRegion)Enum.Parse(typeof(TileRegion), o.regions[0].id.Replace(' ', '_'))
                };
            }

            TerrainTile[,] tiles = new TerrainTile[obj.width, obj.height];
            using (NReader rdr = new NReader(new MemoryStream(dat)))
                for (int y = 0; y < obj.height; y++)
                {
                    for (int x = 0; x < obj.width; x++)
                    {
                        tiles[x, y] = tileDict[(ushort)rdr.ReadInt16()];
                    }
                }
            return(WorldMapExporter.Export(tiles));
        }
Exemple #2
0
        public string Export(TerrainTile[,] tiles)
        {
            int w = tiles.GetLength(0);
            int h = tiles.GetLength(1);

            byte[] dat = new byte[w * h * 2];
            int    i   = 0;
            Dictionary <TerrainTile, ushort> idxs = new Dictionary <TerrainTile, ushort>(new TileComparer());
            List <loc> dict = new List <loc>();

            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    TerrainTile tile = tiles[x, y];
                    ushort      idx;
                    if (!idxs.TryGetValue(tile, out idx))
                    {
                        idxs.Add(tile, idx = (ushort)dict.Count);
                        dict.Add(new loc
                        {
                            ground = TileTypes.id[tile.TileId],
                            objs   = tile.TileObj == null
                                ? null
                                : new[]
                            {
                                new obj
                                {
                                    id   = tile.TileObj,
                                    name = tile.Name == null ? null : tile.Name
                                }
                            },
                            regions = tile.TileId == TileTypes.Beach
                                ? new[]
                            {
                                new obj
                                {
                                    id = "Spawn"
                                }
                            }
                                : null
                        });
                    }
                    dat[i + 1] = (byte)(idx & 0xff);
                    dat[i]     = (byte)(idx >> 8);
                    i         += 2;
                }
            }
            json_dat ret = new json_dat
            {
                data   = ZlibStream.CompressBuffer(dat),
                width  = w,
                height = h,
                dict   = dict.ToArray()
            };

            return(JsonConvert.SerializeObject(ret));
        }
Exemple #3
0
        public JSMap(string data)
        {
            json_dat json = JsonConvert.DeserializeObject <json_dat>(data);

            byte[] buffer = ZlibStream.UncompressBuffer(json.data);
            Dictionary <ushort, JSTile> dict = new Dictionary <ushort, JSTile>();

            JSTile[,] tiles = new JSTile[json.width, json.height];

            for (int i = 0; i < json.dict.Length; i++)
            {
                loc o = json.dict[i];
                dict[(ushort)i] = new JSTile
                {
                    GroundType = o.ground == null ? (ushort)255 : Resources.Id2Tile[o.ground].Type,
                    ObjectType = o.objs == null ? (ushort)255 : Resources.Id2Object[o.objs[0].id].Type,
                    Key        = o.objs == null ? null : o.objs[0].name,
                    Region     = o.regions == null ? Region.None : (Region)Enum.Parse(typeof(Region), o.regions[0].id.Replace(' ', '_'))
                };
            }

            using (PacketReader rdr = new PacketReader(new MemoryStream(buffer)))
            {
                for (int y = 0; y < json.height; y++)
                {
                    for (int x = 0; x < json.width; x++)
                    {
                        tiles[x, y] = dict[(ushort)rdr.ReadInt16()];
                    }
                }
            }

            //Add composite under cave walls
            for (int x = 0; x < json.width; x++)
            {
                for (int y = 0; y < json.height; y++)
                {
                    if (tiles[x, y].ObjectType != 255)
                    {
                        ObjectDesc desc = Resources.Type2Object[tiles[x, y].ObjectType];
                        if ((desc.CaveWall || desc.ConnectedWall) && tiles[x, y].GroundType == 255)
                        {
                            tiles[x, y].GroundType = 0xfd;
                        }
                    }
                }
            }

            Tiles  = tiles;
            Width  = json.width;
            Height = json.height;

            InitRegions();
        }
Exemple #4
0
        public string Export(TerrainTile[,] tiles)
        {
            var w    = tiles.GetLength(0);
            var h    = tiles.GetLength(1);
            var dat  = new byte[w * h * 2];
            var i    = 0;
            var idxs = new Dictionary <TerrainTile, short>(new TileComparer());
            var dict = new List <loc>();

            for (var y = 0; y < h; y++)
            {
                for (var x = 0; x < w; x++)
                {
                    var   tile = tiles[x, y];
                    short idx;
                    if (!idxs.TryGetValue(tile, out idx))
                    {
                        idxs.Add(tile, idx = (short)dict.Count);
                        dict.Add(new loc
                        {
                            ground = XmlDatas.TypeToId[tile.TileId],
                            objs   = tile.TileObj == null
                                ? null
                                : new[]
                            {
                                new obj
                                {
                                    id   = tile.TileObj,
                                    name = tile.Name == null ? null : tile.Name
                                }
                            },
                            regions = null
                        });
                    }
                    dat[i + 1] = (byte)(idx & 0xff);
                    dat[i]     = (byte)(idx >> 8);
                    i         += 2;
                }
            }
            var ret = new json_dat
            {
                data   = ZlibStream.CompressBuffer(dat),
                width  = w,
                height = h,
                dict   = dict.ToArray()
            };

            return(JsonConvert.SerializeObject(ret));
        }
        public string ToJson()
        {
            var obj = new json_dat();

            obj.width  = Width;
            obj.height = Height;
            var locs = new List <loc>();
            var ms   = new MemoryStream();

            using (var wtr = new NWriter(ms))
                for (int y = 0; y < obj.height; y++)
                {
                    for (int x = 0; x < obj.width; x++)
                    {
                        var loc = new loc();
                        loc.ground = dat.TileTypeToId[(byte)Tiles[x][y]];
                        loc.objs   = new obj[Entities[x][y].Length];
                        for (int i = 0; i < loc.objs.Length; i++)
                        {
                            ObjectDef en = Entities[x][y][i];
                            var       o  = new obj
                            {
                                id = dat.ObjectTypeToId[en.ObjectType]
                            };
                            string s    = "";
                            var    vals = new Dictionary <StatsType, object>();
                            foreach (var z in en.Stats.Stats)
                            {
                                vals.Add(z.Key, z.Value);
                            }
                            if (vals.ContainsKey(StatsType.Name))
                            {
                                s += ";name:" + vals[StatsType.Name];
                            }
                            if (vals.ContainsKey(StatsType.Size))
                            {
                                s += ";size:" + vals[StatsType.Size];
                            }
                            if (vals.ContainsKey(StatsType.ObjectConnection))
                            {
                                s += ";conn:0x" + ((int)vals[StatsType.ObjectConnection]).ToString("X8");
                            }
                            if (vals.ContainsKey(StatsType.MerchantMerchandiseType))
                            {
                                s += ";mtype:" + vals[StatsType.MerchantMerchandiseType];
                            }
                            if (vals.ContainsKey(StatsType.MerchantRemainingCount))
                            {
                                s += ";mcount:" + vals[StatsType.MerchantRemainingCount];
                            }
                            if (vals.ContainsKey(StatsType.MerchantRemainingMinute))
                            {
                                s += ";mtime:" + vals[StatsType.MerchantRemainingMinute];
                            }
                            if (vals.ContainsKey(StatsType.NameChangerStar))
                            {
                                s += ";nstar:" + vals[StatsType.NameChangerStar];
                            }
                            o.name      = s.Trim(';');
                            loc.objs[i] = o;
                        }

                        int ix = -1;
                        for (int i = 0; i < locs.Count; i++)
                        {
                            if (locs[i].ground != loc.ground)
                            {
                                continue;
                            }
                            if (!((locs[i].objs != null && loc.objs != null) ||
                                  (locs[i].objs == null && loc.objs == null)))
                            {
                                continue;
                            }
                            if (locs[i].objs != null)
                            {
                                if (locs[i].objs.Length != loc.objs.Length)
                                {
                                    continue;
                                }
                                bool b = false;
                                for (int j = 0; j < loc.objs.Length; j++)
                                {
                                    if (locs[i].objs[j].id != loc.objs[j].id ||
                                        locs[i].objs[j].name != loc.objs[j].name)
                                    {
                                        b = true;
                                        break;
                                    }
                                }
                                if (b)
                                {
                                    continue;
                                }
                            }
                            ix = i;
                            break;
                        }
                        if (ix == -1)
                        {
                            ix = locs.Count;
                            locs.Add(loc);
                        }
                        wtr.Write((short)ix);
                    }
                }
            obj.data = ZlibStream.CompressBuffer(ms.ToArray());
            obj.dict = locs.ToArray();
            return(JsonConvert.SerializeObject(obj));
        }
Exemple #6
0
        public static byte[] ConvertMakeWalls(RealmManager manager, string json)
        {
            json_dat obj = JsonConvert.DeserializeObject <json_dat>(json);

            byte[] dat = ZlibStream.UncompressBuffer(obj.data);

            Dictionary <ushort, TerrainTile> tileDict = new Dictionary <ushort, TerrainTile>();

            for (int i = 0; i < obj.dict.Length; i++)
            {
                loc o = obj.dict[i];
                tileDict[(ushort)i] = new TerrainTile
                {
                    TileId  = o.ground == null ? (ushort)0xff : manager.GameData.IdToObjectType[o.ground],
                    TileObj = o.objs == null ? null : o.objs[0].id,
                    Name    = o.objs == null ? "" : o.objs[0].name ?? "",
                    Terrain = TerrainType.None,
                    Region  =
                        o.regions == null
                            ? TileRegion.None
                            : (TileRegion)Enum.Parse(typeof(TileRegion), o.regions[0].id.Replace(' ', '_'))
                };
            }

            TerrainTile[,] tiles = new TerrainTile[obj.width, obj.height];
            using (NReader rdr = new NReader(new MemoryStream(dat)))
                for (int y = 0; y < obj.height; y++)
                {
                    for (int x = 0; x < obj.width; x++)
                    {
                        tiles[x, y]   = tileDict[(ushort)rdr.ReadInt16()];
                        tiles[x, y].X = x;
                        tiles[x, y].Y = y;
                    }
                }

            foreach (TerrainTile i in tiles)
            {
                if (i.TileId == 0xff && i.TileObj == null)
                {
                    bool createWall = false;
                    for (int ty = -1; ty <= 1; ty++)
                    {
                        for (int tx = -1; tx <= 1; tx++)
                        {
                            try
                            {
                                if (tiles[i.X + tx, i.Y + ty].TileId != 0xff)
                                {
                                    createWall = true;
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                    if (createWall)
                    {
                        tiles[i.X, i.Y].TileObj = "Grey Wall";
                    }
                }
            }

            return(WorldMapExporter.Export(tiles));
        }
Exemple #7
0
        public string ToJson()
        {
            var obj = new json_dat();

            obj.width = Width; obj.height = Height;
            List <loc>   locs = new List <loc>();
            MemoryStream ms   = new MemoryStream();

            using (PacketWriter wtr = new PacketWriter(ms))
                for (int y = 0; y < obj.height; y++)
                {
                    for (int x = 0; x < obj.width; x++)
                    {
                        var loc = new loc();
                        loc.ground = Tiles[x][y] != -1 ? GetTileId((ushort)Tiles[x][y]) : null;
                        loc.objs   = new obj[Entities[x][y].Length];
                        for (int i = 0; i < loc.objs.Length; i++)
                        {
                            var en = Entities[x][y][i];
                            obj o  = new obj()
                            {
                                id = GetEntityId(en.ObjectType)
                            };
                            string s = "";
                            Dictionary <StatsType, object> vals = new Dictionary <StatsType, object>();
                            foreach (var z in en.Status.Data)
                            {
                                vals.Add(z.Id, z.IsStringData() ? (object)z.StringValue : (object)z.IntValue);
                            }
                            if (vals.ContainsKey(StatsType.Name))
                            {
                                s += ";name:" + vals[StatsType.Name];
                            }
                            if (vals.ContainsKey(StatsType.Size))
                            {
                                s += ";size:" + vals[StatsType.Size];
                            }
                            if (vals.ContainsKey(StatsType.ObjectConnection))
                            {
                                s += ";conn:0x" + ((int)vals[StatsType.ObjectConnection]).ToString("X8");
                            }
                            if (vals.ContainsKey(StatsType.MerchandiseType))
                            {
                                s += ";mtype:" + vals[StatsType.MerchandiseType];
                            }
                            if (vals.ContainsKey(StatsType.MerchandiseRemainingCount))
                            {
                                s += ";mcount:" + vals[StatsType.MerchandiseRemainingCount];
                            }
                            if (vals.ContainsKey(StatsType.MerchandiseRemainingMinutes))
                            {
                                s += ";mtime:" + vals[StatsType.MerchandiseRemainingMinutes];
                            }
                            if (vals.ContainsKey(StatsType.RankRequired))
                            {
                                s += ";nstar:" + vals[StatsType.RankRequired];
                            }
                            o.name      = s.Trim(';');
                            loc.objs[i] = o;
                        }

                        int ix = -1;
                        for (int i = 0; i < locs.Count; i++)
                        {
                            if (locs[i].ground != loc.ground)
                            {
                                continue;
                            }
                            if (!((locs[i].objs != null && loc.objs != null) ||
                                  (locs[i].objs == null && loc.objs == null)))
                            {
                                continue;
                            }
                            if (locs[i].objs != null)
                            {
                                if (locs[i].objs.Length != loc.objs.Length)
                                {
                                    continue;
                                }
                                bool b = false;
                                for (int j = 0; j < loc.objs.Length; j++)
                                {
                                    if (locs[i].objs[j].id != loc.objs[j].id ||
                                        locs[i].objs[j].name != loc.objs[j].name)
                                    {
                                        b = true;
                                        break;
                                    }
                                }
                                if (b)
                                {
                                    continue;
                                }
                            }
                            ix = i;
                            break;
                        }
                        if (ix == -1)
                        {
                            ix = locs.Count;
                            locs.Add(loc);
                        }
                        wtr.Write((short)ix);
                    }
                }
            obj.data = ZlibStream.CompressBuffer(ms.ToArray());
            obj.dict = locs.ToArray();
            var settings = new JsonSerializerSettings();

            settings.NullValueHandling = NullValueHandling.Ignore;
            return(JsonConvert.SerializeObject(obj, settings));
        }
        public string ToJson()
        {
            var obj = new json_dat();
            obj.width = Width;
            obj.height = Height;
            var locs = new List<loc>();
            var ms = new MemoryStream();
            using (var wtr = new NWriter(ms))
                for (int y = 0; y < obj.height; y++)
                    for (int x = 0; x < obj.width; x++)
                    {
                        var loc = new loc();
                        loc.ground = dat.TileTypeToId[(byte) Tiles[x][y]];
                        loc.objs = new obj[Entities[x][y].Length];
                        for (int i = 0; i < loc.objs.Length; i++)
                        {
                            ObjectDef en = Entities[x][y][i];
                            var o = new obj
                            {
                                id = dat.ObjectTypeToId[en.ObjectType]
                            };
                            string s = "";
                            var vals = new Dictionary<StatsType, object>();
                            foreach (var z in en.Stats.Stats) vals.Add(z.Key, z.Value);
                            if (vals.ContainsKey(StatsType.Name))
                                s += ";name:" + vals[StatsType.Name];
                            if (vals.ContainsKey(StatsType.Size))
                                s += ";size:" + vals[StatsType.Size];
                            if (vals.ContainsKey(StatsType.ObjectConnection))
                                s += ";conn:0x" + ((int) vals[StatsType.ObjectConnection]).ToString("X8");
                            if (vals.ContainsKey(StatsType.MerchantMerchandiseType))
                                s += ";mtype:" + vals[StatsType.MerchantMerchandiseType];
                            if (vals.ContainsKey(StatsType.MerchantRemainingCount))
                                s += ";mcount:" + vals[StatsType.MerchantRemainingCount];
                            if (vals.ContainsKey(StatsType.MerchantRemainingMinute))
                                s += ";mtime:" + vals[StatsType.MerchantRemainingMinute];
                            if (vals.ContainsKey(StatsType.NameChangerStar))
                                s += ";nstar:" + vals[StatsType.NameChangerStar];
                            o.name = s.Trim(';');
                            loc.objs[i] = o;
                        }

                        int ix = -1;
                        for (int i = 0; i < locs.Count; i++)
                        {
                            if (locs[i].ground != loc.ground) continue;
                            if (!((locs[i].objs != null && loc.objs != null) ||
                                  (locs[i].objs == null && loc.objs == null))) continue;
                            if (locs[i].objs != null)
                            {
                                if (locs[i].objs.Length != loc.objs.Length) continue;
                                bool b = false;
                                for (int j = 0; j < loc.objs.Length; j++)
                                    if (locs[i].objs[j].id != loc.objs[j].id ||
                                        locs[i].objs[j].name != loc.objs[j].name)
                                    {
                                        b = true;
                                        break;
                                    }
                                if (b)
                                    continue;
                            }
                            ix = i;
                            break;
                        }
                        if (ix == -1)
                        {
                            ix = locs.Count;
                            locs.Add(loc);
                        }
                        wtr.Write((short) ix);
                    }
            obj.data = ZlibStream.CompressBuffer(ms.ToArray());
            obj.dict = locs.ToArray();
            return JsonConvert.SerializeObject(obj);
        }
        public static string ConvertReverse(XmlData data, byte[] wmap)
        {
            var obj = new json_dat();
            List<TerrainTile> terdict = new List<TerrainTile>();
            List<loc> dict = new List<loc>();

            List<byte> wmb = new List<byte>();
            foreach (var i in wmap)
                wmb.Add(i);
            wmb.RemoveAt(0);
            wmap = ZlibStream.UncompressBuffer(wmb.ToArray());

            List<byte> dat = new List<byte>();
            List<short> newDat = new List<short>();
            using (var rdr = new BinaryReader(new MemoryStream(wmap)))
            {
                short dicLength = rdr.ReadInt16();
                for (short i = 0; i < dicLength; i++)
                {
                    terdict.Add(new TerrainTile()
                    {
                        TileId = rdr.ReadUInt16(),
                        TileObj = rdr.ReadString(),
                        Name = rdr.ReadString(),
                        Terrain = (TerrainType)rdr.ReadByte(),
                        Region = (TileRegion)rdr.ReadByte()
                    });
                }
                obj.width = rdr.ReadInt32();
                obj.height = rdr.ReadInt32();
                dat = new List<byte>(rdr.ReadBytes(obj.width * obj.height * 3));
            }
            using (var rdr = new BinaryReader(new MemoryStream(dat.ToArray())))
            {
                for (int i = 0; i < obj.width * obj.height; i++)
                {
                    newDat.Add(rdr.ReadInt16());
                    rdr.ReadByte(); //Elevation, don't need
                }
            }
            foreach (var i in terdict)
            {
                dict.Add(new loc()
                {
                    ground = data.Tiles[i.TileId].ObjectId,
                    objs = i.TileObj == null ? null : new obj[] { new obj() { id = i.TileObj, name = i.Name } },
                    regions = i.Region == TileRegion.None ? null : new obj[] { new obj() { id = i.Region.ToString().Replace('_', ' '), name = "" } }
                });
            }

            MemoryStream s = new MemoryStream();
            using (var wtr = new NWriter(s))
            {
                foreach (var i in newDat)
                {
                    wtr.Write(i);
                }
            }

            obj.dict = dict.ToArray();

            obj.data = ZlibStream.CompressBuffer(s.ToArray());
            return JsonConvert.SerializeObject(obj);
        }
        public static string ConvertReverse(XmlData data, byte[] wmap)
        {
            var obj = new json_dat();
            List <TerrainTile> terdict = new List <TerrainTile>();
            List <loc>         dict    = new List <loc>();

            List <byte> wmb = new List <byte>();

            foreach (var i in wmap)
            {
                wmb.Add(i);
            }
            wmb.RemoveAt(0);
            wmap = ZlibStream.UncompressBuffer(wmb.ToArray());

            List <byte>  dat    = new List <byte>();
            List <short> newDat = new List <short>();

            using (var rdr = new BinaryReader(new MemoryStream(wmap)))
            {
                short dicLength = rdr.ReadInt16();
                for (short i = 0; i < dicLength; i++)
                {
                    terdict.Add(new TerrainTile()
                    {
                        TileId  = rdr.ReadUInt16(),
                        TileObj = rdr.ReadString(),
                        Name    = rdr.ReadString(),
                        Terrain = (TerrainType)rdr.ReadByte(),
                        Region  = (TileRegion)rdr.ReadByte()
                    });
                }
                obj.width  = rdr.ReadInt32();
                obj.height = rdr.ReadInt32();
                dat        = new List <byte>(rdr.ReadBytes(obj.width * obj.height * 3));
            }
            using (var rdr = new BinaryReader(new MemoryStream(dat.ToArray())))
            {
                for (int i = 0; i < obj.width * obj.height; i++)
                {
                    newDat.Add(rdr.ReadInt16());
                    rdr.ReadByte(); //Elevation, don't need
                }
            }
            foreach (var i in terdict)
            {
                dict.Add(new loc()
                {
                    ground = data.Tiles[i.TileId].ObjectId,
                    objs   = i.TileObj == null ? null : new obj[] { new obj()
                                                                    {
                                                                        id = i.TileObj, name = i.Name
                                                                    } },
                    regions = i.Region == TileRegion.None ? null : new obj[] { new obj()
                                                                               {
                                                                                   id = i.Region.ToString().Replace('_', ' '), name = ""
                                                                               } }
                });
            }

            MemoryStream s = new MemoryStream();

            using (var wtr = new NWriter(s))
            {
                foreach (var i in newDat)
                {
                    wtr.Write(i);
                }
            }

            obj.dict = dict.ToArray();

            obj.data = ZlibStream.CompressBuffer(s.ToArray());
            return(JsonConvert.SerializeObject(obj));
        }
Exemple #11
0
        public string ToJson()
        {
            var obj = new json_dat();
            obj.width = Width; obj.height = Height;
            List<loc> locs = new List<loc>();
            MemoryStream ms = new MemoryStream();
            using (PacketWriter wtr = new PacketWriter(ms))
                for (int y = 0; y < obj.height; y++)
                    for (int x = 0; x < obj.width; x++)
                    {
                        var loc = new loc();
                        loc.ground = Tiles[x][y] != -1 ? GetTileId((ushort)Tiles[x][y]) : null;
                        loc.objs = new obj[Entities[x][y].Length];
                        for (int i = 0; i < loc.objs.Length; i++)
                        {
                            var en = Entities[x][y][i];
                            obj o = new obj()
                            {
                                id = GetEntityId(en.ObjectType)
                            };
                            string s = "";
                            Dictionary<StatsType, object> vals = new Dictionary<StatsType, object>();
                            foreach (var z in en.Status.Data) vals.Add(z.Id, z.IsStringData() ? (object)z.StringValue : (object)z.IntValue);
                            if (vals.ContainsKey(StatsType.Name))
                                s += ";name:" + vals[StatsType.Name];
                            if (vals.ContainsKey(StatsType.Size))
                                s += ";size:" + vals[StatsType.Size];
                            if (vals.ContainsKey(StatsType.ObjectConnection))
                                s += ";conn:0x" + ((int)vals[StatsType.ObjectConnection]).ToString("X8");
                            if (vals.ContainsKey(StatsType.MerchandiseType))
                                s += ";mtype:" + vals[StatsType.MerchandiseType];
                            if (vals.ContainsKey(StatsType.MerchandiseRemainingCount))
                                s += ";mcount:" + vals[StatsType.MerchandiseRemainingCount];
                            if (vals.ContainsKey(StatsType.MerchandiseRemainingMinutes))
                                s += ";mtime:" + vals[StatsType.MerchandiseRemainingMinutes];
                            if (vals.ContainsKey(StatsType.RankRequired))
                                s += ";nstar:" + vals[StatsType.RankRequired];
                            o.name = s.Trim(';');
                            loc.objs[i] = o;
                        }

                        int ix = -1;
                        for (int i = 0; i < locs.Count; i++)
                        {
                            if (locs[i].ground != loc.ground) continue;
                            if (!((locs[i].objs != null && loc.objs != null) ||
                              (locs[i].objs == null && loc.objs == null))) continue;
                            if (locs[i].objs != null)
                            {
                                if (locs[i].objs.Length != loc.objs.Length) continue;
                                bool b = false;
                                for (int j = 0; j < loc.objs.Length; j++)
                                    if (locs[i].objs[j].id != loc.objs[j].id ||
                                        locs[i].objs[j].name != loc.objs[j].name)
                                    {
                                        b = true;
                                        break;
                                    }
                                if (b)
                                    continue;
                            }
                            ix = i;
                            break;
                        }
                        if (ix == -1)
                        {
                            ix = locs.Count;
                            locs.Add(loc);
                        }
                        wtr.Write((short)ix);
                    }
            obj.data = ZlibStream.CompressBuffer(ms.ToArray());
            obj.dict = locs.ToArray();
            var settings = new JsonSerializerSettings();
            settings.NullValueHandling = NullValueHandling.Ignore;
            return JsonConvert.SerializeObject(obj, settings);
        }