public Map Load(string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } using (FileStream mapStream = File.OpenRead(fileName)) { GZipStream gs = new GZipStream(mapStream, CompressionMode.Decompress, true); NBTag root = NBTag.ReadStream(gs); // ReSharper disable UseObjectOrCollectionInitializer Map map = new Map(null, root["X"].GetShort(), root["Z"].GetShort(), root["Y"].GetShort(), false); // ReSharper restore UseObjectOrCollectionInitializer NBTag spawnTag = root["Spawn"]; map.Spawn = new Position { X = (spawnTag["X"].GetShort() * 32), Y = (spawnTag["Z"].GetShort() * 32), Z = (spawnTag["Y"].GetShort() * 32), R = spawnTag["H"].GetByte(), L = spawnTag["P"].GetByte(), }; // read UUID map.Guid = new Guid(root["UUID"].GetBytes()); // read creation/modification dates of the file (for fallback) DateTime fileCreationDate = File.GetCreationTime(fileName); DateTime fileModTime = File.GetCreationTime(fileName); // try to read embedded creation date if (root.Contains("TimeCreated")) { map.DateCreated = DateTimeUtil.ToDateTime(root["TimeCreated"].GetLong()); } else { // for fallback, pick the older of two filesystem dates map.DateCreated = (fileModTime > fileCreationDate) ? fileCreationDate : fileModTime; } // try to read embedded modification date if (root.Contains("LastModified")) { map.DateModified = DateTimeUtil.ToDateTime(root["LastModified"].GetLong()); } else { // for fallback, use file modification date map.DateModified = fileModTime; } map.Blocks = root["BlockArray"].GetBytes(); return(map); } }
void ReadMetadata(NBTag root, Map map, String fileName) { if (!root.Contains("CPE")) { return; } NBTag cpe = root["CPE"]; if (cpe.Contains("EnvWeatherType")) { map.Metadata.Add("CPE", "Weather", cpe["EnvWeatherType"]["WeatherType"].GetByte().ToString()); } if (cpe.Contains("ClickDistance")) { map.Metadata.Add("CPE", "ClickDistance", cpe["ClickDistance"]["Distance"].GetShort().ToString()); } if (cpe.Contains("EnvMapAppearance")) { ParseEnvMapAppearance(cpe, map); } if (cpe.Contains("EnvColors")) { ParseEnvColors(cpe, map); } if (cpe.Contains("BlockDefinitions")) { ParseBlockDefinitions(cpe, map, fileName); } }
static string GetColor(NBTag comp, string type) { if (!comp.Contains(type)) { return(""); } NBTag rgb = comp[type]; short r = rgb["R"].GetShort(), g = rgb["G"].GetShort(), b = rgb["B"].GetShort(); if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) { return(""); } return(r.ToString("X2") + g.ToString("X2") + b.ToString("X2")); }
static void ParseEnvMapAppearance(NBTag cpe, Map map) { map.Metadata.Add("CPE", "HasEnvMapAppearance", "true"); NBTag comp = cpe["EnvMapAppearance"]; map.Metadata.Add("CPE", "HorizonBlock", comp["EdgeBlock"].GetByte().ToString()); map.Metadata.Add("CPE", "EdgeBlock", comp["SideBlock"].GetByte().ToString()); map.Metadata.Add("CPE", "EdgeLevel", comp["SideLevel"].GetShort().ToString()); if (!comp.Contains("TextureURL")) { return; } string url = comp["TextureURL"].GetString(); map.Metadata.Add("CPE", "Texture", url == Server.DefaultTerrain ? "default" : url); }
static void ParseBlockDefinitions(NBTag cpe, Map map, string fileName) { NBTag blocks = cpe["BlockDefinitions"]; bool hasBlockDefs = false; BlockDefinition[] defs = new BlockDefinition[256]; foreach (NBTag tag in blocks) { if (tag.Type != NBTType.Compound) { continue; } NBTag props = tag; BlockDefinition def = new BlockDefinition(); def.BlockID = props["ID"].GetByte(); // can't change "ID" to short since backwards compatibility if (props.Contains("ID2")) { ushort tempID = (ushort)props["ID2"].GetShort(); if (tempID >= 256) { continue; } def.BlockID = (byte)tempID; } def.Name = props["Name"].GetString(); def.CollideType = props["CollideType"].GetByte(); def.Speed = props["Speed"].GetFloat(); def.BlocksLight = props["TransmitsLight"].GetByte() == 0; def.WalkSound = props["WalkSound"].GetByte(); def.FullBright = props["FullBright"].GetByte() != 0; def.Shape = props["Shape"].GetByte(); def.BlockDraw = props["BlockDraw"].GetByte(); byte[] fog = props["Fog"].GetBytes(); def.FogDensity = fog[0]; // Fix for older ClassicalSharp versions which saved wrong value for density = 0 if (def.FogDensity == 0xFF) { def.FogDensity = 0; } def.FogR = fog[1]; def.FogG = fog[2]; def.FogB = fog[3]; byte[] tex = props["Textures"].GetBytes(); def.TopTex = tex[0]; def.BottomTex = tex[1]; def.LeftTex = tex[2]; def.RightTex = tex[3]; def.FrontTex = tex[4]; def.BackTex = tex[5]; byte[] coords = props["Coords"].GetBytes(); def.MinX = coords[0]; def.MinZ = coords[1]; def.MinY = coords[2]; def.MaxX = coords[3]; def.MaxZ = coords[4]; def.MaxY = coords[5]; // Don't define level custom block if same as global custom block if (PropsEquals(def, BlockDefinition.GlobalDefs[def.BlockID])) { continue; } defs[def.BlockID] = def; hasBlockDefs = true; } if (hasBlockDefs) { BlockDefinition[] realDefs = new BlockDefinition[256]; int count = 0; for (int i = 0; i < 256; i++) { if (defs[i] == BlockDefinition.GlobalDefs[i]) { realDefs[i] = null; } else { count++; realDefs[i] = defs[i]; } } defs = realDefs; string path = Paths.BlockDefsDirectory; path = Path.Combine(path, Path.GetFileName(fileName) + ".txt"); map.Metadata["CPE", "HasBlockDefFile"] = "true"; map.Metadata["CPE", "BlockDefFileName"] = Path.GetFileName(fileName); try { using (Stream s = File.Create(path)) JsonSerializer.SerializeToStream(defs, s); } catch (Exception ex) { Logger.Log(LogType.Error, "BlockDefinitions.Save: " + ex); } } }