예제 #1
0
 private void ShowRegionFlagDefaultsCmd(List <string> args, TTY io, UUID limitedToScene)
 {
     if (limitedToScene != UUID.Zero)
     {
         io.Write("Command not allowed on limited console");
     }
     else if (args[0] == "help")
     {
         io.Write("show defaultregionflags");
     }
     else
     {
         var sb = new StringBuilder("Default RegionFlags:\n----------------------------------------------------------------------\n");
         foreach (KeyValuePair <UUID, RegionFlags> kvp in m_RegionDefaultFlagsService.GetAllRegionDefaultFlags())
         {
             RegionInfo ri;
             if (m_GridService.TryGetValue(kvp.Key, out ri))
             {
                 sb.AppendFormat("Region {0} ({1}):\n- {2}", ri.Name, kvp.Key, kvp.Value.ToString());
             }
             else
             {
                 sb.AppendFormat("Region ? ({0}):\n- {1}", kvp.Key, kvp.Value.ToString());
             }
         }
         io.Write(sb.ToString());
     }
 }
예제 #2
0
 private void PurgeAssetsCmd(List <string> args, TTY io, UUID limitedToScene)
 {
     if (args[0] == "help")
     {
         io.Write("Triggers unused assets purge");
     }
     else
     {
         TimerTriggered(null, null);
         io.Write("assets purge triggered");
     }
 }
예제 #3
0
        private void ClearRegionFlagDefaultsCmd(List <string> args, TTY io, UUID limitedToScene)
        {
            if (limitedToScene != UUID.Zero)
            {
                io.Write("Command not allowed on limited console");
            }
            else if (args[0] == "help" || args.Count != 4)
            {
                io.Write("clear regionflags id <uuid>\n" +
                         "clear regionflags name <name>");
            }
            else
            {
                UUID id;
                if (args[2] == "id")
                {
                    if (!UUID.TryParse(args[3], out id))
                    {
                        io.Write("uuid is not valid");
                        return;
                    }
                }
                else if (args[2] == "name")
                {
                    RegionInfo ri;
                    if (m_GridService.TryGetValue(args[3], out ri))
                    {
                        id = ri.ID;
                    }
                    else
                    {
                        io.WriteFormatted("unknown region {0}", args[3]);
                        return;
                    }
                }
                else
                {
                    io.Write("Invalid parameters");
                    return;
                }

                try
                {
                    m_GridService.RemoveRegionFlags(id, RegionFlags.FallbackRegion | RegionFlags.DefaultRegion | RegionFlags.DefaultIntergridRegion | RegionFlags.Persistent);
                    m_RegionDefaultFlagsService.ChangeRegionDefaultFlags(id, RegionFlags.None, ~RegionFlags.None);
                }
                catch
                {
                    io.Write("Failed to set clear region flag defaults");
                }
            }
        }
예제 #4
0
        private void UnregisterRegionCmd(List <string> args, TTY io, UUID limitedToScene)
        {
            if (limitedToScene != UUID.Zero)
            {
                io.Write("Command not allowed on limited console");
            }
            else if (args[0] == "help" || args.Count != 4)
            {
                io.Write("unregister region id <regionid>\nunregister region name <name>");
            }
            else
            {
                UUID       id;
                RegionInfo ri;
                switch (args[2])
                {
                case "id":
                    if (!UUID.TryParse(args[3], out id))
                    {
                        io.Write("regionid is not valid");
                        return;
                    }
                    break;

                case "name":
                    if (!m_GridService.TryGetValue(args[3], out ri))
                    {
                        io.WriteFormatted("region \"{0}\" is not known", args[3]);
                        return;
                    }
                    id = ri.ID;
                    break;

                default:
                    io.WriteFormatted("Unknown region identifier type {0}", args[2]);
                    return;
                }

                try
                {
                    m_GridService.UnregisterRegion(id);
                }
                catch
                {
                    io.Write("Failed to remove region");
                }
            }
        }
예제 #5
0
 private void ShowRegionsCmd(List <string> args, TTY io, UUID limitedToScene)
 {
     if (limitedToScene != UUID.Zero)
     {
         io.Write("Command not allowed on limited console");
     }
     else if (args[0] == "help" || args.Count != 3)
     {
         io.Write("show gridregions <searchkey>");
     }
     else
     {
         var sb = new StringBuilder("Regions:\n--------------------------------------------------\n");
         foreach (RegionInfo ri in m_GridService.SearchRegionsByName(args[2]))
         {
             sb.AppendFormat("Region {0}\n- ID: ({1})\n- Flags: {2}\n", ri.Name, ri.ID, ri.Flags.ToString());
         }
         io.Write(sb.ToString());
     }
 }
        private static void ShowOarLoadState(ref CurrentOarLoadState currentState, CurrentOarLoadState newState, TTY io)
        {
            if (currentState != newState)
            {
                if (io != null)
                {
                    switch (newState)
                    {
                    case CurrentOarLoadState.Assets:
                        io.Write("Loading assets");
                        break;

                    case CurrentOarLoadState.Objects:
                        io.Write("Loading objects");
                        break;

                    case CurrentOarLoadState.RegionSettings:
                        io.Write("Loading region settings");
                        break;

                    case CurrentOarLoadState.Terrain:
                        io.Write("Loading terrain");
                        break;

                    case CurrentOarLoadState.Region:
                        io.Write("Loading region");
                        break;

                    case CurrentOarLoadState.Parcels:
                        io.Write("Loading parcels");
                        break;

                    default:
                        break;
                    }
                }
                currentState = newState;
            }
        }
        private void SaveIarCommand(List <string> args, TTY io, UUID limitedToScene)
        {
            if (args[0] == "help")
            {
                string outp = "Available commands:\n";
                outp += "save npc-iar [--noassets] <firstname> <lastname> <inventorypath> <filename>\n";
                io.Write(outp);
                return;
            }

            UUID selectedScene = io.SelectedScene;

            if (limitedToScene != UUID.Zero)
            {
                selectedScene = limitedToScene;
            }

            if (UUID.Zero == selectedScene)
            {
                io.Write("No scene selected");
                return;
            }

            string firstname     = null;
            string lastname      = null;
            string filename      = null;
            string inventorypath = null;
            var    options       = InventoryArchiver.IAR.SaveOptions.None;

            for (int argi = 2; argi < args.Count; ++argi)
            {
                string arg = args[argi];
                if (arg == "--noassets")
                {
                    options |= InventoryArchiver.IAR.SaveOptions.NoAssets;
                }
                else if (firstname == null)
                {
                    firstname = arg;
                }
                else if (lastname == null)
                {
                    lastname = arg;
                }
                else if (inventorypath == null)
                {
                    inventorypath = arg;
                }
                else
                {
                    filename = arg;
                }
            }

            if (string.IsNullOrEmpty(filename))
            {
                io.Write("missing parameters");
                return;
            }

            NpcPresenceInfo presence;

            if (!m_NpcPresenceService.TryGetValue(selectedScene, firstname, lastname, out presence))
            {
                io.Write("Persistent npc not found");
                return;
            }

            try
            {
                using (Stream s = new FileStream(filename, FileMode.Create, FileAccess.Write))
                {
                    InventoryArchiver.IAR.Save(presence.Npc, m_NpcInventoryService, m_NpcAssetService, m_AvatarNameServices, options, filename, inventorypath, io);
                }
                io.Write("IAR saved successfully.");
            }
            catch (Exception e)
            {
                io.WriteFormatted("IAR saving failed: {0}", e.Message);
            }
        }
예제 #8
0
        private void LoadIarCommand(List <string> args, TTY io, UUID limitedToScene)
        {
            if (args[0] == "help")
            {
                string outp = "Available commands:\n";
                outp += "load iar [-m|--merge] [--noassets] <firstname> <lastname> <inventorypath> <filename>\n";
                io.Write(outp);
                return;
            }

            string filename      = null;
            string firstname     = null;
            string lastname      = null;
            string inventorypath = null;
            var    options       = InventoryArchiver.IAR.LoadOptions.None;

            for (int argi = 2; argi < args.Count; ++argi)
            {
                string arg = args[argi];
                if (arg == "--skip-assets")
                {
                    options |= InventoryArchiver.IAR.LoadOptions.NoAssets;
                }
                else if (arg == "--merge" || arg == "-m")
                {
                    options |= InventoryArchiver.IAR.LoadOptions.Merge;
                }
                else if (firstname == null)
                {
                    firstname = arg;
                }
                else if (lastname == null)
                {
                    lastname = arg;
                }
                else if (inventorypath == null)
                {
                    inventorypath = arg;
                }
                else
                {
                    filename = arg;
                }
            }

            if (string.IsNullOrEmpty(filename))
            {
                io.Write("No filename or url specified.\n");
                return;
            }

            UserAccount account;
            UUID        token;

            try
            {
                account = Authenticate(firstname, lastname, io.GetPass("Password"), out token);
            }
            catch (Exception e)
            {
                io.WriteFormatted("failed to authenticate: {0}", e.Message);
                return;
            }

            try
            {
                using (Stream s = Uri.IsWellFormedUriString(filename, UriKind.Absolute) ?
                                  new HttpClient.Get(filename).ExecuteStreamRequest() :
                                  new FileStream(filename, FileMode.Open, FileAccess.Read))
                {
                    InventoryArchiver.IAR.Load(account.Principal, m_InventoryService, m_AssetService, m_AvatarNameServices, options, s, inventorypath, io);
                }
                io.Write("IAR loaded successfully.");
            }
            catch (InventoryArchiver.IAR.IARFormatException)
            {
                io.Write("IAR file is corrupt");
            }
            catch (Exception e)
            {
                m_Log.Info("IAR load exception encountered", e);
                io.Write(e.Message);
            }
            finally
            {
                m_AuthInfoService.ReleaseToken(account.Principal.ID, token);
            }
        }
        private void LoadAssetsCommand(List <string> args, TTY io, UUID limitedToScene)
        {
            if (args[0] == "help")
            {
                string outp = "Available commands:\n";
                outp += "load osassets <filename> - Load assets to scene\n";
                io.Write(outp);
                return;
            }

            UUID selectedScene = io.SelectedScene;

            if (limitedToScene != UUID.Zero)
            {
                selectedScene = limitedToScene;
            }

            AssetServiceInterface assetService;
            UGUI owner;

            if (args.Count == 3)
            {
                /* scene */
                if (selectedScene == UUID.Zero)
                {
                    io.Write("No region selected");
                    return;
                }
                else
                {
                    try
                    {
                        SceneInterface scene = m_Scenes[selectedScene];
                        assetService = scene.AssetService;
                        owner        = scene.Owner;
                    }
                    catch
                    {
                        io.Write("Selected region not found");
                        return;
                    }
                }
            }
            else
            {
                io.Write("Invalid arguments to load osassets");
                return;
            }

            try
            {
                using (Stream s = Uri.IsWellFormedUriString(args[2], UriKind.Absolute) ?
                                  new HttpClient.Get(args[2]).ExecuteStreamRequest() :
                                  new FileStream(args[2], FileMode.Open, FileAccess.Read))
                {
                    Assets.AssetsLoad.Load(assetService, owner, s);
                }
                io.Write("Assets loaded successfully.");
            }
            catch (Exception e)
            {
                io.Write(e.Message);
            }
        }
        private void LoadIarCommand(List <string> args, TTY io, UUID limitedToScene)
        {
            if (args[0] == "help")
            {
                string outp = "Available commands:\n";
                outp += "load npc-iar [-m|--merge] [--noassets] <firstname> <lastname> <inventorypath> <filename>\n";
                io.Write(outp);
                return;
            }

            UUID selectedScene = io.SelectedScene;

            if (limitedToScene != UUID.Zero)
            {
                selectedScene = limitedToScene;
            }

            if (UUID.Zero == selectedScene)
            {
                io.Write("No scene selected");
                return;
            }

            string filename      = null;
            string firstname     = null;
            string lastname      = null;
            string inventorypath = null;
            var    options       = InventoryArchiver.IAR.LoadOptions.None;

            for (int argi = 2; argi < args.Count; ++argi)
            {
                string arg = args[argi];
                if (arg == "--skip-assets")
                {
                    options |= InventoryArchiver.IAR.LoadOptions.NoAssets;
                }
                else if (arg == "--merge" || arg == "-m")
                {
                    options |= InventoryArchiver.IAR.LoadOptions.Merge;
                }
                else if (firstname == null)
                {
                    firstname = arg;
                }
                else if (lastname == null)
                {
                    lastname = arg;
                }
                else if (inventorypath == null)
                {
                    inventorypath = arg;
                }
                else
                {
                    filename = arg;
                }
            }

            if (string.IsNullOrEmpty(filename))
            {
                io.Write("No filename or url specified.\n");
                return;
            }

            NpcPresenceInfo presenceInfo;

            if (!m_NpcPresenceService.TryGetValue(selectedScene, firstname, lastname, out presenceInfo))
            {
                io.Write("Persistent npc not found");
                return;
            }

            try
            {
                using (Stream s = Uri.IsWellFormedUriString(filename, UriKind.Absolute) ?
                                  new HttpClient.Get(filename).ExecuteStreamRequest() :
                                  new FileStream(filename, FileMode.Open, FileAccess.Read))
                {
                    InventoryArchiver.IAR.Load(presenceInfo.Npc, m_NpcInventoryService, m_NpcAssetService, m_AvatarNameServices, options, s, inventorypath, io);
                }
                io.Write("IAR loaded successfully.");
            }
            catch (InventoryArchiver.IAR.IARFormatException)
            {
                io.Write("IAR file is corrupt");
            }
            catch (Exception e)
            {
                m_Log.Info("IAR load exception encountered", e);
                io.Write(e.Message);
            }
        }
        private void SaveOarCommand(List <string> args, TTY io, UUID limitedToScene)
        {
            if (args[0] == "help")
            {
                string outp = "Available commands:\n";
                outp += "save oar [--publish] [--noassets] <filename>\n";
                io.Write(outp);
                return;
            }

            UUID           selectedScene = io.SelectedScene;
            SceneInterface scene;

            if (limitedToScene != UUID.Zero)
            {
                selectedScene = limitedToScene;
            }

            if (UUID.Zero == selectedScene)
            {
                io.Write("Multi-region OARs currently not supported");
                return;
            }
            else
            {
                try
                {
                    scene = m_Scenes[selectedScene];
                }
                catch
                {
                    io.Write("Selected region does not exist");
                    return;
                }
            }

            string filename = null;
            var    options  = RegionArchiver.OAR.SaveOptions.None;

            for (int argi = 2; argi < args.Count; ++argi)
            {
                string arg = args[argi];
                if (arg == "--noassets")
                {
                    options |= RegionArchiver.OAR.SaveOptions.NoAssets;
                }
                else if (arg == "--publish")
                {
                    options |= RegionArchiver.OAR.SaveOptions.Publish;
                }
                else
                {
                    filename = arg;
                }
            }

            try
            {
                using (Stream s = new FileStream(filename, FileMode.Create, FileAccess.Write))
                {
                    RegionArchiver.OAR.Save(scene, options, s, io);
                }
                io.Write("OAR saved successfully.");
            }
            catch (Exception e)
            {
                io.Write(e.Message);
            }
        }
예제 #12
0
        public static void Save(
            SceneInterface scene,
            SaveOptions options,
            Stream outputFile,
            TTY console_io = null)
        {
            using (var gzip = new GZipStream(outputFile, CompressionMode.Compress))
            {
                var writer = new TarArchiveWriter(gzip);

                bool saveAssets = (options & SaveOptions.NoAssets) == 0;
                var  xmloptions = XmlSerializationOptions.None;
                if ((options & SaveOptions.Publish) == 0)
                {
                    xmloptions |= XmlSerializationOptions.WriteOwnerInfo;
                }

                if (console_io != null)
                {
                    console_io.Write("Saving archive info...");
                }

                writer.WriteFile("archive.xml", WriteArchiveXml08(scene, saveAssets));

                var objectAssets = new Dictionary <string, AssetData>();

                if (console_io != null)
                {
                    console_io.Write("Collecting object data...");
                }
                foreach (ObjectGroup sog in scene.Objects)
                {
                    if (sog.IsTemporary || sog.IsAttached)
                    {
                        /* skip temporary or attached */
                        continue;
                    }
                    AssetData data = sog.Asset(xmloptions | XmlSerializationOptions.WriteXml2 | XmlSerializationOptions.WriteKeyframeMotion | XmlSerializationOptions.WriteRezDate);
                    objectAssets.Add(EscapingMethods.EscapeName(sog.Name) + "_" + ((int)sog.GlobalPosition.X).ToString() + "-" + ((int)sog.GlobalPosition.Y).ToString() + "-" + ((int)sog.GlobalPosition.Z).ToString() + "__" + sog.ID.ToString() + ".xml", data);
                }

                #region Save Assets
                if (saveAssets)
                {
                    if (console_io != null)
                    {
                        console_io.Write("Saving asset data...");
                    }
                    /* we only parse sim details when saving assets */
                    var       assetIDs = new List <UUID>();
                    AssetData data;

                    foreach (AssetData objdata in objectAssets.Values)
                    {
                        foreach (UUID id in objdata.References)
                        {
                            if (id != UUID.Zero && !assetIDs.Contains(id))
                            {
                                assetIDs.Add(id);
                            }
                        }
                    }

                    foreach (ParcelInfo pinfo in scene.Parcels)
                    {
                        if (pinfo.MediaID != UUID.Zero)
                        {
                            assetIDs.Add(pinfo.MediaID);
                        }
                        if (pinfo.SnapshotID != UUID.Zero)
                        {
                            assetIDs.Add(pinfo.SnapshotID);
                        }
                    }

                    int assetidx = 0;
                    while (assetidx < assetIDs.Count)
                    {
                        UUID assetID = assetIDs[assetidx++];
                        try
                        {
                            data = scene.AssetService[assetID];
                        }
                        catch
                        {
                            continue;
                        }
                        writer.WriteAsset(data);
                        try
                        {
                            foreach (UUID refid in data.References)
                            {
                                if (!assetIDs.Contains(refid))
                                {
                                    assetIDs.Add(refid);
                                }
                            }
                        }
                        catch
                        {
                            console_io.WriteFormatted("Failed to parse asset {0}", assetID);
                        }
                    }
                }
                #endregion

                #region Region Settings
                if (console_io != null)
                {
                    console_io.Write("Saving region settings...");
                }
                using (var ms = new MemoryStream())
                {
                    using (XmlTextWriter xmlwriter = ms.UTF8XmlTextWriter())
                    {
                        RegionSettings settings = scene.RegionSettings;
                        xmlwriter.WriteStartElement("RegionSettings");
                        {
                            xmlwriter.WriteStartElement("General");
                            {
                                xmlwriter.WriteNamedValue("AllowDamage", settings.AllowDamage);
                                xmlwriter.WriteNamedValue("AllowLandResell", settings.AllowLandResell);
                                xmlwriter.WriteNamedValue("AllowLandJoinDivide", settings.AllowLandJoinDivide);
                                xmlwriter.WriteNamedValue("BlockFly", settings.BlockFly);
                                xmlwriter.WriteNamedValue("BlockFlyOver", settings.BlockFlyOver);
                                xmlwriter.WriteNamedValue("BlockLandShowInSearch", settings.BlockShowInSearch);
                                xmlwriter.WriteNamedValue("BlockTerraform", settings.BlockTerraform);
                                xmlwriter.WriteNamedValue("DisableCollisions", settings.DisableCollisions);
                                xmlwriter.WriteNamedValue("DisablePhysics", settings.DisablePhysics);
                                xmlwriter.WriteNamedValue("DisableScripts", settings.DisableScripts);
                                switch (scene.Access)
                                {
                                case RegionAccess.PG:
                                    xmlwriter.WriteNamedValue("MaturityRating", 0);
                                    break;

                                case RegionAccess.Mature:
                                    xmlwriter.WriteNamedValue("MaturityRating", 1);
                                    break;

                                case RegionAccess.Adult:
                                default:
                                    xmlwriter.WriteNamedValue("MaturityRating", 2);
                                    break;
                                }
                                xmlwriter.WriteNamedValue("RestrictPushing", settings.RestrictPushing);
                                xmlwriter.WriteNamedValue("AgentLimit", settings.AgentLimit);
                                xmlwriter.WriteNamedValue("ObjectBonus", settings.ObjectBonus);
                                xmlwriter.WriteNamedValue("ResetHomeOnTeleport", settings.ResetHomeOnTeleport);
                                xmlwriter.WriteNamedValue("AllowLandmark", settings.AllowLandmark);
                                xmlwriter.WriteNamedValue("AllowDirectTeleport", settings.AllowDirectTeleport);
                                xmlwriter.WriteNamedValue("MaxBasePrims", settings.MaxBasePrims);
                            }
                            xmlwriter.WriteEndElement();
                            xmlwriter.WriteStartElement("GroundTextures");
                            {
                                xmlwriter.WriteNamedValue("Texture1", settings.TerrainTexture1);
                                xmlwriter.WriteNamedValue("Texture2", settings.TerrainTexture2);
                                xmlwriter.WriteNamedValue("Texture3", settings.TerrainTexture3);
                                xmlwriter.WriteNamedValue("Texture4", settings.TerrainTexture4);
                                xmlwriter.WriteNamedValue("ElevationLowSW", settings.Elevation1SW);
                                xmlwriter.WriteNamedValue("ElevationLowNW", settings.Elevation1NW);
                                xmlwriter.WriteNamedValue("ElevationLowSE", settings.Elevation1SE);
                                xmlwriter.WriteNamedValue("ElevationLowNE", settings.Elevation1NE);
                                xmlwriter.WriteNamedValue("ElevationHighSW", settings.Elevation2SW);
                                xmlwriter.WriteNamedValue("ElevationHighNW", settings.Elevation2NW);
                                xmlwriter.WriteNamedValue("ElevationHighSE", settings.Elevation2SE);
                                xmlwriter.WriteNamedValue("ElevationHighNE", settings.Elevation2NE);
                            }
                            xmlwriter.WriteEndElement();
                            xmlwriter.WriteStartElement("Terrain");
                            {
                                xmlwriter.WriteNamedValue("WaterHeight", settings.WaterHeight);
                                xmlwriter.WriteNamedValue("TerrainRaiseLimit", settings.TerrainRaiseLimit);
                                xmlwriter.WriteNamedValue("TerrainLowerLimit", settings.TerrainLowerLimit);
                                xmlwriter.WriteNamedValue("UseEstateSun", settings.UseEstateSun);
                                xmlwriter.WriteNamedValue("FixedSun", settings.IsSunFixed);
                                xmlwriter.WriteNamedValue("SunPosition", settings.SunPosition + 6);
                            }
                            xmlwriter.WriteEndElement();
                            xmlwriter.WriteNamedValue("WalkableCoefficients", Convert.ToBase64String(settings.WalkableCoefficientsSerialization));
                            if (settings.TelehubObject != UUID.Zero)
                            {
                                xmlwriter.WriteStartElement("Telehub");
                                {
                                    xmlwriter.WriteNamedValue("TelehubObject", settings.TelehubObject);
                                    // yes, OpenSim likes to convert around data
                                    double yaw;
                                    double pitch;
                                    double distance;
                                    foreach (Vector3 sp in scene.SpawnPoints)
                                    {
                                        distance = sp.Length;

                                        Vector3 dir = sp.Normalize();

                                        // Get the bearing of the spawn point
                                        yaw = (float)Math.Atan2(dir.Y, dir.X);

                                        // Get the elevation of the spawn point
                                        pitch = (float)-Math.Atan2(dir.Z, Math.Sqrt(dir.X * dir.X + dir.Y * dir.Y));

                                        xmlwriter.WriteNamedValue("SpawnPoint", string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", yaw, pitch, distance));
                                    }
                                }
                                xmlwriter.WriteEndElement();
                            }
                        }
                        xmlwriter.WriteEndElement();
                    }
                    writer.WriteFile("settings/" + scene.Name + ".xml", ms.ToArray());
                }
                #endregion

                #region Saving parcels
                if (console_io != null)
                {
                    console_io.Write("Saving parcel data...");
                }

                foreach (ParcelInfo pinfo in scene.Parcels)
                {
                    using (var ms = new MemoryStream())
                    {
                        using (XmlTextWriter xmlwriter = ms.UTF8XmlTextWriter())
                        {
                            xmlwriter.WriteStartElement("LandData");
                            {
                                xmlwriter.WriteNamedValue("Area", pinfo.Area);
                                xmlwriter.WriteNamedValue("AuctionID", pinfo.AuctionID);
                                xmlwriter.WriteNamedValue("AuthBuyerID", pinfo.AuthBuyer.ID);
                                xmlwriter.WriteNamedValue("Category", (byte)pinfo.Category);
                                xmlwriter.WriteNamedValue("ClaimDate", pinfo.ClaimDate.DateTimeToUnixTime().ToString());
                                xmlwriter.WriteNamedValue("ClaimPrice", pinfo.ClaimPrice);
                                xmlwriter.WriteNamedValue("GlobalID", pinfo.ID);
                                if ((options & SaveOptions.Publish) != 0)
                                {
                                    xmlwriter.WriteNamedValue("GroupID", UUID.Zero);
                                    xmlwriter.WriteNamedValue("IsGroupOwned", false);
                                }
                                else
                                {
                                    xmlwriter.WriteNamedValue("GroupID", pinfo.Group.ID);
                                    xmlwriter.WriteNamedValue("IsGroupOwned", pinfo.GroupOwned);
                                }
                                xmlwriter.WriteNamedValue("Bitmap", Convert.ToBase64String(pinfo.LandBitmap.Data));
                                xmlwriter.WriteNamedValue("Description", pinfo.Description);
                                xmlwriter.WriteNamedValue("Flags", (uint)pinfo.Flags);
                                xmlwriter.WriteNamedValue("LandingType", (uint)pinfo.LandingType);
                                xmlwriter.WriteNamedValue("Name", pinfo.Name);
                                xmlwriter.WriteNamedValue("Status", (uint)pinfo.Status);
                                xmlwriter.WriteNamedValue("LocalID", pinfo.LocalID);
                                xmlwriter.WriteNamedValue("MediaAutoScale", pinfo.MediaAutoScale);
                                xmlwriter.WriteNamedValue("MediaID", pinfo.MediaID);
                                if (pinfo.MediaURI != null)
                                {
                                    xmlwriter.WriteNamedValue("MediaURL", pinfo.MediaURI.ToString());
                                }
                                else
                                {
                                    xmlwriter.WriteStartElement("MediaURL");
                                    xmlwriter.WriteEndElement();
                                }
                                if (pinfo.MusicURI != null)
                                {
                                    xmlwriter.WriteNamedValue("MusicURL", pinfo.MusicURI.ToString());
                                }
                                else
                                {
                                    xmlwriter.WriteStartElement("MusicURL");
                                    xmlwriter.WriteEndElement();
                                }
                                xmlwriter.WriteNamedValue("OwnerID", pinfo.Owner.ID);
                                xmlwriter.WriteStartElement("ParcelAccessList");
                                if ((options & SaveOptions.Publish) == 0)
                                {
                                    /* only serialize ParcelAccessEntry when not writing Publish OAR */
                                    foreach (ParcelAccessEntry pae in scene.Parcels.WhiteList[scene.ID, pinfo.ID])
                                    {
                                        xmlwriter.WriteStartElement("ParcelAccessEntry");
                                        xmlwriter.WriteNamedValue("AgentID", pae.Accessor.ID.ToString());
                                        xmlwriter.WriteNamedValue("AgentData", pae.Accessor.CreatorData);
                                        xmlwriter.WriteNamedValue("Time", pae.ExpiresAt.AsULong);
                                        xmlwriter.WriteNamedValue("AccessList", (int)OarAccessFlags.Access);
                                        xmlwriter.WriteEndElement();
                                    }
                                    foreach (ParcelAccessEntry pae in scene.Parcels.BlackList[scene.ID, pinfo.ID])
                                    {
                                        xmlwriter.WriteStartElement("ParcelAccessEntry");
                                        xmlwriter.WriteNamedValue("AgentID", pae.Accessor.ID.ToString());
                                        xmlwriter.WriteNamedValue("AgentData", pae.Accessor.CreatorData);
                                        xmlwriter.WriteNamedValue("Time", pae.ExpiresAt.AsULong);
                                        xmlwriter.WriteNamedValue("AccessList", (int)OarAccessFlags.Ban);
                                        xmlwriter.WriteEndElement();
                                    }
                                }
                                xmlwriter.WriteEndElement();
                                xmlwriter.WriteNamedValue("PassHours", pinfo.PassHours);
                                xmlwriter.WriteNamedValue("PassPrice", pinfo.PassPrice);
                                xmlwriter.WriteNamedValue("SalePrice", pinfo.SalePrice);
                                xmlwriter.WriteNamedValue("SnapshotID", pinfo.SnapshotID);
                                xmlwriter.WriteNamedValue("UserLocation", pinfo.LandingPosition.ToString());
                                xmlwriter.WriteNamedValue("UserLookAt", pinfo.LandingLookAt.ToString());
                                xmlwriter.WriteNamedValue("Dwell", pinfo.Dwell);
                                xmlwriter.WriteNamedValue("OtherCleanTime", pinfo.OtherCleanTime);
                            }
                            xmlwriter.WriteEndElement();
                            xmlwriter.Flush();

                            writer.WriteFile("landdata/" + pinfo.ID.ToString() + ".xml", ms.ToArray());
                        }
                    }
                }
                #endregion

                #region Storing object data
                if (console_io != null)
                {
                    console_io.Write("Storing object data...");
                }
                foreach (KeyValuePair <string, AssetData> kvp in objectAssets)
                {
                    writer.WriteFile("objects/" + kvp.Key, kvp.Value.Data);
                }
                #endregion

                #region Storing terrain
                if (console_io != null)
                {
                    console_io.Write("Saving terrain data...");
                }
                writer.WriteFile("terrains/" + scene.Name + ".r32", GenTerrainFile(scene.Terrain.AllPatches));
                #endregion
                writer.WriteEndOfTar();
            }
        }
        private void LoadOarCommand(List <string> args, TTY io, UUID limitedToScene)
        {
            if (args[0] == "help")
            {
                string outp = "Available commands:\n";
                outp += "load oar [--skip-assets] [--merge] [--persist-uuids] <filename>\n";
                outp += "load oar [--skip-assets] [--merge] [--persist-uuids] <url>\n\n";
                outp += "--persist-uuids cannot be combined with --merge\n";
                io.Write(outp);
                return;
            }

            UUID           selectedScene = io.SelectedScene;
            SceneInterface scene         = null;

            if (limitedToScene != UUID.Zero)
            {
                selectedScene = limitedToScene;
            }

            if (UUID.Zero != selectedScene)
            {
                try
                {
                    scene = m_Scenes[selectedScene];
                }
                catch
                {
                    io.Write("Selected scene does not exist.");
                    return;
                }
            }

            string filename = null;
            var    options  = RegionArchiver.OAR.LoadOptions.None;

            for (int argi = 2; argi < args.Count; ++argi)
            {
                string arg = args[argi];
                if (arg == "--skip-assets")
                {
                    options |= RegionArchiver.OAR.LoadOptions.NoAssets;
                }
                else if (arg == "--merge")
                {
                    options |= RegionArchiver.OAR.LoadOptions.Merge;
                }
                else if (arg == "--persist-uuids")
                {
                    options |= RegionArchiver.OAR.LoadOptions.PersistUuids;
                }
                else
                {
                    filename = arg;
                }
            }

            if (string.IsNullOrEmpty(filename))
            {
                io.Write("No filename or url specified.\n");
                return;
            }

            try
            {
                using (Stream s = Uri.IsWellFormedUriString(filename, UriKind.Absolute) ?
                                  new HttpClient.Get(filename).ExecuteStreamRequest() :
                                  new FileStream(filename, FileMode.Open, FileAccess.Read))
                {
                    RegionArchiver.OAR.Load(m_Scenes, scene, options, s, io);
                }
                io.Write("OAR loaded successfully.");
            }
            catch (RegionArchiver.OAR.OARLoadingTriedWithoutSelectedRegionException)
            {
                io.Write("No region selected");
            }
            catch (RegionArchiver.OAR.MultiRegionOARLoadingTriedOnRegionException)
            {
                io.Write("Multi-Region OAR cannot be loaded with a selected region");
            }
            catch (RegionArchiver.OAR.OARFormatException)
            {
                io.Write("OAR file is corrupt");
            }
            catch (Exception e)
            {
                m_Log.Info("OAR load exception encountered", e);
                io.Write(e.Message);
            }
        }
예제 #14
0
        public void LoadTerrainCommand(List <string> args, TTY io, UUID limitedToScene)
        {
            UUID           selectedScene = io.SelectedScene;
            SceneInterface scene;

            if (limitedToScene != UUID.Zero)
            {
                selectedScene = limitedToScene;
            }

            ITerrainFileStorage loader;

            if (args[0] == "help")
            {
                var outp = new StringBuilder("Available commands:\n" +
                                             "load terrain <format> <filename>\n" +
                                             "load terrain <format> <filename> x,y w,h\n" +
                                             "\nAvailable Formats:\n");
                foreach (KeyValuePair <string, ITerrainFileStorage> kvp in m_TerrainFileStorages)
                {
                    if (kvp.Value.SupportsLoading)
                    {
                        outp.AppendFormat("{0}\n", kvp.Key);
                    }
                }
                io.Write(outp.ToString());
            }
            else if (args.Count < 4 || args.Count > 6)
            {
                io.Write("invalid parameters for load terrain\n");
            }
            else if (!m_TerrainFileStorages.TryGetValue(args[2], out loader) || !loader.SupportsLoading)
            {
                io.WriteFormatted("unknown terrain file format {0}\n", args[2]);
            }
            else if (selectedScene == UUID.Zero)
            {
                io.Write("No region selected.\n");
            }
            else if (!m_Scenes.TryGetValue(selectedScene, out scene))
            {
                io.Write("Selected region does not exist anymore.\n");
            }
            else
            {
                uint x = 0;
                uint y = 0;
                uint w = scene.SizeX;
                uint h = scene.SizeY;

                if (args.Count >= 5)
                {
                    try
                    {
                        ParseLocation(args[4], out x, out y);
                    }
                    catch
                    {
                        io.WriteFormatted("Invalid start location {0} given", args[4]);
                        return;
                    }
                    if (w <= x || h <= y || (x % 16) != 0 || (y % 16) != 0)
                    {
                        io.WriteFormatted("Invalid start location {0} given", args[4]);
                        return;
                    }
                    w -= x;
                    h -= y;
                }

                if (args.Count == 6)
                {
                    uint nw;
                    uint nh;
                    try
                    {
                        ParseLocation(args[5], out nw, out nh);
                    }
                    catch
                    {
                        io.WriteFormatted("Invalid size {0} given", args[5]);
                        return;
                    }
                    if (w < x + nw || h < y + nh || w < nw || h < nh || (nw % 16) != 0 || (nh % 16) != 0)
                    {
                        io.WriteFormatted("Invalid size {0} given", args[5]);
                        return;
                    }
                    w = nw;
                    h = nh;
                }

                List <LayerPatch> patches;

                try
                {
                    patches = loader.LoadFile(args[3], (int)w, (int)h);
                }
                catch (Exception e)
                {
                    io.WriteFormatted("Could no load file {0}: {1}", args[3], e.Message);
                    return;
                }

                foreach (LayerPatch patch in patches)
                {
                    if (patch.X >= w / 16 || patch.Y >= h / 16)
                    {
                        io.Write("Terrain data from file exceeds given size\n");
                        return;
                    }
                    patch.X += x / 16;
                    patch.Y += y / 16;
                }

                scene.Terrain.AllPatches = patches;
                scene.StoreTerrainAsDefault();
                io.WriteFormatted("Terrain data loaded from file {0}.\n", args[3]);
            }
        }
예제 #15
0
        private void SaveIarCommand(List <string> args, TTY io, UUID limitedToScene)
        {
            if (args[0] == "help")
            {
                string outp = "Available commands:\n";
                outp += "save iar [--noassets] <firstname> <lastname> <inventorypath> <filename>\n";
                io.Write(outp);
                return;
            }

            string firstname     = null;
            string lastname      = null;
            string filename      = null;
            string inventorypath = null;
            var    options       = InventoryArchiver.IAR.SaveOptions.None;

            for (int argi = 2; argi < args.Count; ++argi)
            {
                string arg = args[argi];
                if (arg == "--noassets")
                {
                    options |= InventoryArchiver.IAR.SaveOptions.NoAssets;
                }
                else if (firstname == null)
                {
                    firstname = arg;
                }
                else if (lastname == null)
                {
                    lastname = arg;
                }
                else if (inventorypath == null)
                {
                    inventorypath = arg;
                }
                else
                {
                    filename = arg;
                }
            }

            if (string.IsNullOrEmpty(filename))
            {
                io.Write("missing parameters");
                return;
            }

            UserAccount account;
            UUID        token;

            try
            {
                account = Authenticate(firstname, lastname, io.GetPass("Password"), out token);
            }
            catch (Exception e)
            {
                io.WriteFormatted("failed to authenticate: {0}", e.Message);
                return;
            }

            try
            {
                using (var s = new FileStream(filename, FileMode.Create, FileAccess.Write))
                {
                    InventoryArchiver.IAR.Save(account.Principal, m_InventoryService, m_AssetService, m_AvatarNameServices, options, filename, inventorypath, io);
                }
                io.Write("IAR saved successfully.");
            }
            catch (Exception e)
            {
                io.WriteFormatted("IAR saving failed: {0}", e.Message);
            }
            finally
            {
                m_AuthInfoService.ReleaseToken(account.Principal.ID, token);
            }
        }
        public static void Load(
            UGUI principal,
            InventoryServiceInterface inventoryService,
            AssetServiceInterface assetService,
            List <AvatarNameServiceInterface> nameServices,
            LoadOptions options,
            Stream inputFile,
            string topath,
            TTY console_io = null)
        {
            using (var gzipStream = new GZipStream(inputFile, CompressionMode.Decompress))
            {
                using (var reader = new TarArchiveReader(gzipStream))
                {
                    var inventoryPath = new Dictionary <UUID, UUID>();
                    var reassignedIds = new Dictionary <UUID, UUID>();
                    var linkItems     = new List <InventoryItem>();

                    UUID parentFolder;
                    try
                    {
                        inventoryService.CheckInventory(principal.ID);
                    }
                    catch (NotSupportedException)
                    {
                        /* some handlers may not support this call, so ignore that error */
                    }
                    parentFolder = inventoryService.Folder[principal.ID, AssetType.RootFolder].ID;

                    if (!topath.StartsWith("/"))
                    {
                        throw new InvalidInventoryPathException();
                    }

                    if (topath != "/")
                    {
                        foreach (string pathcomp in topath.Substring(1).Split('/'))
                        {
                            List <InventoryFolder> childfolders = inventoryService.Folder.GetFolders(principal.ID, parentFolder);
                            int idx;
                            for (idx = 0; idx < childfolders.Count; ++idx)
                            {
                                if (pathcomp.ToLower() == childfolders[idx].Name.ToLower())
                                {
                                    break;
                                }
                            }

                            if (idx == childfolders.Count)
                            {
                                throw new InvalidInventoryPathException();
                            }

                            parentFolder = childfolders[idx].ID;
                        }
                    }

                    inventoryPath[UUID.Zero] = parentFolder;

                    for (; ;)
                    {
                        TarArchiveReader.Header header;
                        try
                        {
                            header = reader.ReadHeader();
                        }
                        catch (TarArchiveReader.EndOfTarException)
                        {
                            if (console_io != null)
                            {
                                console_io.Write("Creating link items");
                            }
                            foreach (InventoryItem linkitem in linkItems)
                            {
                                UUID newId;
                                if (linkitem.AssetType == AssetType.Link && reassignedIds.TryGetValue(linkitem.AssetID, out newId))
                                {
                                    linkitem.AssetID = newId;
                                }
                                inventoryService.Item.Add(linkitem);
                            }
                            return;
                        }

                        if (header.FileType == TarFileType.File)
                        {
                            if (header.FileName == "archive.xml")
                            {
                                using (Stream s = new ObjectXmlStreamFilter(reader))
                                {
                                    ArchiveXmlLoader.LoadArchiveXml(s);
                                }
                            }

                            if (header.FileName.StartsWith("assets/") && (options & LoadOptions.NoAssets) == 0)
                            {
                                /* Load asset */
                                AssetData ad = reader.LoadAsset(header, principal);
                                if (!assetService.Exists(ad.ID))
                                {
                                    assetService.Store(ad);
                                }
                            }

                            if (header.FileName.StartsWith("inventory/"))
                            {
                                /* Load inventory */
                                InventoryItem item = LoadInventoryItem(reader, principal, nameServices);
                                item.ParentFolderID = GetPath(principal, inventoryService, inventoryPath, header.FileName, options);

                                UUID oldId = item.ID;
                                item.SetNewID(UUID.Random);
                                reassignedIds.Add(oldId, item.ID);

                                if (item.AssetType == AssetType.Link || item.AssetType == AssetType.LinkFolder)
                                {
                                    inventoryService.Item.Add(item);
                                }
                                else
                                {
                                    linkItems.Add(item);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #17
0
        private void ChangeRegionFlagDefaultsCmd(List <string> args, TTY io, UUID limitedToScene)
        {
            if (limitedToScene != UUID.Zero)
            {
                io.Write("Command not allowed on limited console");
            }
            else if (args[0] == "help" || args.Count < 4 || args.Count % 2 != 0)
            {
                io.Write("change regionflags id <uuid> flags..\n" +
                         "change regionflags name <name> flags..\n\nFlags:\n" +
                         "fallback true|false\ndefault true|false\ndefaulthg true|false\npersistent true|false");
            }
            else
            {
                UUID id;
                if (args[2] == "id")
                {
                    if (!UUID.TryParse(args[3], out id))
                    {
                        io.Write("uuid is not valid");
                        return;
                    }
                }
                else if (args[2] == "name")
                {
                    RegionInfo ri;
                    if (m_GridService.TryGetValue(args[3], out ri))
                    {
                        id = ri.ID;
                    }
                    else
                    {
                        io.WriteFormatted("unknown region {0}", args[3]);
                        return;
                    }
                }
                else
                {
                    io.Write("Invalid parameters");
                    return;
                }

                var setFlags    = RegionFlags.None;
                var removeFlags = RegionFlags.None;

                bool val;
                for (int argi = 4; argi < args.Count; argi += 2)
                {
                    switch (args[argi])
                    {
                    case "fallback":
                        if (!bool.TryParse(args[argi + 1], out val))
                        {
                            io.WriteFormatted("{0} is not a valid boolean", args[argi + 1]);
                            return;
                        }
                        if (val)
                        {
                            setFlags    |= RegionFlags.FallbackRegion;
                            removeFlags &= ~RegionFlags.FallbackRegion;
                        }
                        else
                        {
                            setFlags    &= ~RegionFlags.FallbackRegion;
                            removeFlags |= RegionFlags.FallbackRegion;
                        }
                        break;

                    case "default":
                        if (!bool.TryParse(args[argi + 1], out val))
                        {
                            io.WriteFormatted("{0} is not a valid boolean", args[argi + 1]);
                            return;
                        }
                        if (val)
                        {
                            setFlags    |= RegionFlags.DefaultRegion;
                            removeFlags &= ~RegionFlags.DefaultRegion;
                        }
                        else
                        {
                            setFlags    &= ~RegionFlags.DefaultRegion;
                            removeFlags |= RegionFlags.DefaultRegion;
                        }
                        break;

                    case "defaulthg":
                        if (!bool.TryParse(args[argi + 1], out val))
                        {
                            io.WriteFormatted("{0} is not a valid boolean", args[argi + 1]);
                            return;
                        }
                        if (val)
                        {
                            setFlags    |= RegionFlags.DefaultIntergridRegion;
                            removeFlags &= ~RegionFlags.DefaultIntergridRegion;
                        }
                        else
                        {
                            setFlags    &= ~RegionFlags.DefaultIntergridRegion;
                            removeFlags |= RegionFlags.DefaultIntergridRegion;
                        }
                        break;

                    case "persistent":
                        if (!bool.TryParse(args[argi + 1], out val))
                        {
                            io.WriteFormatted("{0} is not a valid boolean", args[argi + 1]);
                            return;
                        }
                        if (val)
                        {
                            setFlags    |= RegionFlags.Persistent;
                            removeFlags &= ~RegionFlags.Persistent;
                        }
                        else
                        {
                            setFlags    &= ~RegionFlags.Persistent;
                            removeFlags |= RegionFlags.Persistent;
                        }
                        break;

                    default:
                        io.WriteFormatted("{0} is not a known flag", args[argi]);
                        return;
                    }
                }

                try
                {
                    m_GridService.AddRegionFlags(id, setFlags);
                    m_GridService.RemoveRegionFlags(id, removeFlags);
                    m_RegionDefaultFlagsService.ChangeRegionDefaultFlags(id, setFlags, removeFlags);
                }
                catch
                {
                    io.Write("Failed to set new region flag defaults");
                }
            }
        }
        public static void Save(
            UGUI principal,
            InventoryServiceInterface inventoryService,
            AssetServiceInterface assetService,
            List <AvatarNameServiceInterface> nameServices,
            SaveOptions options,
            Stream outputFile,
            string frompath,
            TTY console_io = null)
        {
            UUID parentFolder;
            Dictionary <UUID, KeyValuePair <string, UUID> > folders = new Dictionary <UUID, KeyValuePair <string, UUID> >();

            parentFolder = inventoryService.Folder[principal.ID, AssetType.RootFolder].ID;

            if (!frompath.StartsWith("/"))
            {
                throw new InvalidInventoryPathException();
            }
            foreach (string pathcomp in frompath.Substring(1).Split('/'))
            {
                List <InventoryFolder> childfolders = inventoryService.Folder.GetFolders(principal.ID, parentFolder);
                int idx;
                for (idx = 0; idx < childfolders.Count; ++idx)
                {
                    if (pathcomp.ToLower() == childfolders[idx].Name.ToLower())
                    {
                        break;
                    }
                }

                if (idx == childfolders.Count)
                {
                    throw new InvalidInventoryPathException();
                }

                parentFolder          = childfolders[idx].ID;
                folders[parentFolder] = new KeyValuePair <string, UUID>(childfolders[idx].Name, UUID.Zero);
            }

            using (GZipStream gzip = new GZipStream(outputFile, CompressionMode.Compress))
            {
                TarArchiveWriter writer = new TarArchiveWriter(gzip);

                bool saveAssets = (options & SaveOptions.NoAssets) == 0;

                if (console_io != null)
                {
                    console_io.Write("Saving archive info...");
                }

                writer.WriteFile("archive.xml", WriteArchiveXml(saveAssets));

                List <UUID> nextFolders = new List <UUID>();
                List <UUID> assetIds    = new List <UUID>();
                nextFolders.Add(parentFolder);
                if (console_io != null)
                {
                    console_io.Write("Saving inventory data...");
                }

                while (nextFolders.Count != 0)
                {
                    InventoryFolderContent content;
                    UUID folderId = nextFolders[0];
                    nextFolders.RemoveAt(0);
                    content = inventoryService.Folder.Content[principal.ID, folderId];
                    foreach (InventoryFolder folder in content.Folders)
                    {
                        folders[folder.ID] = new KeyValuePair <string, UUID>(folder.Name, folderId);
                    }

                    foreach (InventoryItem item in content.Items)
                    {
                        if (item.AssetType != AssetType.Link && item.AssetType != AssetType.LinkFolder &&
                            !assetIds.Contains(item.AssetID) && saveAssets)
                        {
                            assetIds.Add(item.AssetID);
                        }

                        writer.WriteFile(GetFolderPath(folders, item), WriteInventoryItem(item));
                    }
                }

                if (saveAssets)
                {
                    if (console_io != null)
                    {
                        console_io.Write("Saving asset data...");
                    }
                    /* we only parse sim details when saving assets */
                    AssetData data;

                    int assetidx = 0;
                    while (assetidx < assetIds.Count)
                    {
                        UUID assetID = assetIds[assetidx++];
                        try
                        {
                            data = assetService[assetID];
                        }
                        catch
                        {
                            continue;
                        }
                        writer.WriteAsset(data);
                        try
                        {
                            foreach (UUID refid in data.References)
                            {
                                if (!assetIds.Contains(refid))
                                {
                                    assetIds.Add(refid);
                                }
                            }
                        }
                        catch
                        {
                            console_io.WriteFormatted("Failed to parse asset {0}", assetID);
                        }
                    }
                }
            }
        }
예제 #19
0
        public void SaveTerrainCommand(List <string> args, TTY io, UUID limitedToScene)
        {
            UUID           selectedScene = io.SelectedScene;
            SceneInterface scene;

            if (limitedToScene != UUID.Zero)
            {
                selectedScene = limitedToScene;
            }

            ITerrainFileStorage storer;

            if (args[0] == "help")
            {
                var outp = new StringBuilder("Available commands:\n" +
                                             "save terrain <format> <filename>\n" +
                                             "save terrain <format> <filename> x,y w,h\n" +
                                             "\nAvailable formats:\n");
                foreach (KeyValuePair <string, ITerrainFileStorage> kvp in m_TerrainFileStorages)
                {
                    if (kvp.Value.SupportsSaving)
                    {
                        outp.AppendFormat("{0}\n", kvp.Key);
                    }
                }
                io.Write(outp.ToString());
            }
            else if (args.Count != 4 && args.Count != 6)
            {
                io.Write("invalid parameters for save terrain\n");
            }
            else if (!m_TerrainFileStorages.TryGetValue(args[1], out storer) || !storer.SupportsSaving)
            {
                io.WriteFormatted("unknown terrain file format {0}\n", args[1]);
            }
            else if (selectedScene == UUID.Zero)
            {
                io.Write("No region selected.\n");
            }
            else if (!m_Scenes.TryGetValue(selectedScene, out scene))
            {
                io.Write("Selected region does not exist anymore.\n");
            }
            else
            {
                uint x = 0;
                uint y = 0;
                uint w = scene.SizeX;
                uint h = scene.SizeY;

                if (args.Count >= 5)
                {
                    try
                    {
                        ParseLocation(args[4], out x, out y);
                    }
                    catch
                    {
                        io.WriteFormatted("Invalid start location {0} given", args[4]);
                        return;
                    }
                    if (w <= x || h <= y || (x % 16) != 0 || (y % 16) != 0)
                    {
                        io.WriteFormatted("Invalid start location {0} given", args[4]);
                        return;
                    }
                    w -= x;
                    h -= y;
                }

                if (args.Count == 6)
                {
                    uint nw;
                    uint nh;
                    try
                    {
                        ParseLocation(args[5], out nw, out nh);
                    }
                    catch
                    {
                        io.WriteFormatted("Invalid size {0} given", args[5]);
                        return;
                    }
                    if (w < x + nw || h < y + nh || w < nw || h < nh || (nw % 16) != 0 || (nh % 16) != 0)
                    {
                        io.WriteFormatted("Invalid size {0} given", args[5]);
                        return;
                    }
                    w = nw;
                    h = nh;
                }

                var patches = new List <LayerPatch>();
                foreach (LayerPatch patch in scene.Terrain.AllPatches)
                {
                    if (patch.X >= x && patch.Y >= y && patch.X < x + w && patch.Y < y + h)
                    {
                        patches.Add(patch);
                    }
                }

                try
                {
                    storer.SaveFile(args[3], patches);
                }
                catch (Exception e)
                {
                    io.WriteFormatted("Could no save terrain file {0}: {1}", args[3], e.Message);
                    return;
                }
                io.WriteFormatted("Saved terrain file {0}", args[3]);
            }
        }