diff options
author | UbitUmarov | 2015-09-01 11:43:07 +0100 |
---|---|---|
committer | UbitUmarov | 2015-09-01 11:43:07 +0100 |
commit | fb78b182520fc9bb0f971afd0322029c70278ea6 (patch) | |
tree | b4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Region/CoreModules/World/Objects | |
parent | lixo (diff) | |
parent | Mantis #7713: fixed bug introduced by 1st MOSES patch. (diff) | |
download | opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.zip opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2 opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz |
Merge remote-tracking branch 'os/master'
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Objects')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs | 253 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | 934 |
2 files changed, 1187 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs new file mode 100644 index 0000000..2abc910 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs | |||
@@ -0,0 +1,253 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using log4net; | ||
32 | using Mono.Addins; | ||
33 | using Nini.Config; | ||
34 | using OpenMetaverse; | ||
35 | using OpenMetaverse.Packets; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Framework; | ||
38 | using OpenSim.Region.Framework.Interfaces; | ||
39 | using OpenSim.Region.Framework.Scenes; | ||
40 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
41 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
42 | |||
43 | namespace OpenSim.Region.CoreModules.World.Objects.BuySell | ||
44 | { | ||
45 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BuySellModule")] | ||
46 | public class BuySellModule : IBuySellModule, INonSharedRegionModule | ||
47 | { | ||
48 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | protected Scene m_scene = null; | ||
51 | protected IDialogModule m_dialogModule; | ||
52 | |||
53 | public string Name { get { return "Object BuySell Module"; } } | ||
54 | public Type ReplaceableInterface { get { return null; } } | ||
55 | |||
56 | public void Initialise(IConfigSource source) {} | ||
57 | |||
58 | public void AddRegion(Scene scene) | ||
59 | { | ||
60 | m_scene = scene; | ||
61 | m_scene.RegisterModuleInterface<IBuySellModule>(this); | ||
62 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; | ||
63 | } | ||
64 | |||
65 | public void RemoveRegion(Scene scene) | ||
66 | { | ||
67 | m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; | ||
68 | } | ||
69 | |||
70 | public void RegionLoaded(Scene scene) | ||
71 | { | ||
72 | m_dialogModule = scene.RequestModuleInterface<IDialogModule>(); | ||
73 | } | ||
74 | |||
75 | public void Close() | ||
76 | { | ||
77 | RemoveRegion(m_scene); | ||
78 | } | ||
79 | |||
80 | public void SubscribeToClientEvents(IClientAPI client) | ||
81 | { | ||
82 | client.OnObjectSaleInfo += ObjectSaleInfo; | ||
83 | } | ||
84 | |||
85 | protected void ObjectSaleInfo( | ||
86 | IClientAPI client, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice) | ||
87 | { | ||
88 | SceneObjectPart part = m_scene.GetSceneObjectPart(localID); | ||
89 | if (part == null) | ||
90 | return; | ||
91 | |||
92 | if (part.ParentGroup.IsDeleted) | ||
93 | return; | ||
94 | |||
95 | if (part.OwnerID != client.AgentId && (!m_scene.Permissions.IsGod(client.AgentId))) | ||
96 | return; | ||
97 | |||
98 | part = part.ParentGroup.RootPart; | ||
99 | |||
100 | part.ObjectSaleType = saleType; | ||
101 | part.SalePrice = salePrice; | ||
102 | |||
103 | part.ParentGroup.HasGroupChanged = true; | ||
104 | |||
105 | part.SendPropertiesToClient(client); | ||
106 | } | ||
107 | |||
108 | public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) | ||
109 | { | ||
110 | SceneObjectPart part = m_scene.GetSceneObjectPart(localID); | ||
111 | |||
112 | if (part == null) | ||
113 | return false; | ||
114 | |||
115 | SceneObjectGroup group = part.ParentGroup; | ||
116 | |||
117 | switch (saleType) | ||
118 | { | ||
119 | case 1: // Sell as original (in-place sale) | ||
120 | uint effectivePerms = group.GetEffectivePermissions(); | ||
121 | |||
122 | if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) | ||
123 | { | ||
124 | if (m_dialogModule != null) | ||
125 | m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); | ||
126 | return false; | ||
127 | } | ||
128 | |||
129 | group.SetOwnerId(remoteClient.AgentId); | ||
130 | group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); | ||
131 | |||
132 | if (m_scene.Permissions.PropagatePermissions()) | ||
133 | { | ||
134 | foreach (SceneObjectPart child in group.Parts) | ||
135 | { | ||
136 | child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); | ||
137 | child.TriggerScriptChangedEvent(Changed.OWNER); | ||
138 | child.ApplyNextOwnerPermissions(); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | part.ObjectSaleType = 0; | ||
143 | part.SalePrice = 10; | ||
144 | part.ClickAction = Convert.ToByte(0); | ||
145 | |||
146 | group.HasGroupChanged = true; | ||
147 | part.SendPropertiesToClient(remoteClient); | ||
148 | part.TriggerScriptChangedEvent(Changed.OWNER); | ||
149 | group.ResumeScripts(); | ||
150 | part.ScheduleFullUpdate(); | ||
151 | |||
152 | break; | ||
153 | |||
154 | case 2: // Sell a copy | ||
155 | Vector3 inventoryStoredPosition = new Vector3( | ||
156 | Math.Min(group.AbsolutePosition.X, m_scene.RegionInfo.RegionSizeX - 6), | ||
157 | Math.Min(group.AbsolutePosition.Y, m_scene.RegionInfo.RegionSizeY - 6), | ||
158 | group.AbsolutePosition.Z); | ||
159 | |||
160 | Vector3 originalPosition = group.AbsolutePosition; | ||
161 | |||
162 | group.AbsolutePosition = inventoryStoredPosition; | ||
163 | |||
164 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); | ||
165 | group.AbsolutePosition = originalPosition; | ||
166 | |||
167 | uint perms = group.GetEffectivePermissions(); | ||
168 | |||
169 | if ((perms & (uint)PermissionMask.Transfer) == 0) | ||
170 | { | ||
171 | if (m_dialogModule != null) | ||
172 | m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); | ||
173 | return false; | ||
174 | } | ||
175 | |||
176 | AssetBase asset = m_scene.CreateAsset( | ||
177 | group.GetPartName(localID), | ||
178 | group.GetPartDescription(localID), | ||
179 | (sbyte)AssetType.Object, | ||
180 | Utils.StringToBytes(sceneObjectXml), | ||
181 | group.OwnerID); | ||
182 | m_scene.AssetService.Store(asset); | ||
183 | |||
184 | InventoryItemBase item = new InventoryItemBase(); | ||
185 | item.CreatorId = part.CreatorID.ToString(); | ||
186 | item.CreatorData = part.CreatorData; | ||
187 | |||
188 | item.ID = UUID.Random(); | ||
189 | item.Owner = remoteClient.AgentId; | ||
190 | item.AssetID = asset.FullID; | ||
191 | item.Description = asset.Description; | ||
192 | item.Name = asset.Name; | ||
193 | item.AssetType = asset.Type; | ||
194 | item.InvType = (int)InventoryType.Object; | ||
195 | item.Folder = categoryID; | ||
196 | |||
197 | PermissionsUtil.ApplyFoldedPermissions(perms, ref perms); | ||
198 | |||
199 | item.BasePermissions = perms & part.NextOwnerMask; | ||
200 | item.CurrentPermissions = perms & part.NextOwnerMask; | ||
201 | item.NextPermissions = part.NextOwnerMask; | ||
202 | item.EveryOnePermissions = part.EveryoneMask & | ||
203 | part.NextOwnerMask; | ||
204 | item.GroupPermissions = part.GroupMask & | ||
205 | part.NextOwnerMask; | ||
206 | item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; | ||
207 | item.CreationDate = Util.UnixTimeSinceEpoch(); | ||
208 | |||
209 | if (m_scene.AddInventoryItem(item)) | ||
210 | { | ||
211 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | ||
212 | } | ||
213 | else | ||
214 | { | ||
215 | if (m_dialogModule != null) | ||
216 | m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable"); | ||
217 | return false; | ||
218 | } | ||
219 | break; | ||
220 | |||
221 | case 3: // Sell contents | ||
222 | List<UUID> invList = part.Inventory.GetInventoryList(); | ||
223 | |||
224 | bool okToSell = true; | ||
225 | |||
226 | foreach (UUID invID in invList) | ||
227 | { | ||
228 | TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invID); | ||
229 | if ((item1.CurrentPermissions & | ||
230 | (uint)PermissionMask.Transfer) == 0) | ||
231 | { | ||
232 | okToSell = false; | ||
233 | break; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | if (!okToSell) | ||
238 | { | ||
239 | if (m_dialogModule != null) | ||
240 | m_dialogModule.SendAlertToUser( | ||
241 | remoteClient, "This item's inventory doesn't appear to be for sale"); | ||
242 | return false; | ||
243 | } | ||
244 | |||
245 | if (invList.Count > 0) | ||
246 | m_scene.MoveTaskInventoryItems(remoteClient.AgentId, part.Name, part, invList); | ||
247 | break; | ||
248 | } | ||
249 | |||
250 | return true; | ||
251 | } | ||
252 | } | ||
253 | } | ||
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs new file mode 100644 index 0000000..e77f0aa --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | |||
@@ -0,0 +1,934 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Linq; | ||
32 | using System.Reflection; | ||
33 | using System.Text; | ||
34 | using System.Text.RegularExpressions; | ||
35 | using System.Xml; | ||
36 | using log4net; | ||
37 | using Mono.Addins; | ||
38 | using NDesk.Options; | ||
39 | using Nini.Config; | ||
40 | using OpenMetaverse; | ||
41 | using OpenSim.Framework; | ||
42 | using OpenSim.Framework.Console; | ||
43 | using OpenSim.Framework.Monitoring; | ||
44 | using OpenSim.Region.Framework.Interfaces; | ||
45 | using OpenSim.Region.Framework.Scenes; | ||
46 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
47 | |||
48 | namespace OpenSim.Region.CoreModules.World.Objects.Commands | ||
49 | { | ||
50 | /// <summary> | ||
51 | /// A module that holds commands for manipulating objects in the scene. | ||
52 | /// </summary> | ||
53 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ObjectCommandsModule")] | ||
54 | public class ObjectCommandsModule : INonSharedRegionModule | ||
55 | { | ||
56 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
57 | |||
58 | private Scene m_scene; | ||
59 | private ICommandConsole m_console; | ||
60 | |||
61 | public string Name { get { return "Object Commands Module"; } } | ||
62 | |||
63 | public Type ReplaceableInterface { get { return null; } } | ||
64 | |||
65 | public void Initialise(IConfigSource source) | ||
66 | { | ||
67 | // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: INITIALIZED MODULE"); | ||
68 | } | ||
69 | |||
70 | public void PostInitialise() | ||
71 | { | ||
72 | // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: POST INITIALIZED MODULE"); | ||
73 | } | ||
74 | |||
75 | public void Close() | ||
76 | { | ||
77 | // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: CLOSED MODULE"); | ||
78 | } | ||
79 | |||
80 | public void AddRegion(Scene scene) | ||
81 | { | ||
82 | // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); | ||
83 | |||
84 | m_scene = scene; | ||
85 | m_console = MainConsole.Instance; | ||
86 | |||
87 | m_console.Commands.AddCommand( | ||
88 | "Objects", false, "delete object owner", | ||
89 | "delete object owner <UUID>", | ||
90 | "Delete scene objects by owner", | ||
91 | "Command will ask for confirmation before proceeding.", | ||
92 | HandleDeleteObject); | ||
93 | |||
94 | m_console.Commands.AddCommand( | ||
95 | "Objects", false, "delete object creator", | ||
96 | "delete object creator <UUID>", | ||
97 | "Delete scene objects by creator", | ||
98 | "Command will ask for confirmation before proceeding.", | ||
99 | HandleDeleteObject); | ||
100 | |||
101 | m_console.Commands.AddCommand( | ||
102 | "Objects", false, "delete object id", | ||
103 | "delete object id <UUID-or-localID>", | ||
104 | "Delete a scene object by uuid or localID", | ||
105 | HandleDeleteObject); | ||
106 | |||
107 | m_console.Commands.AddCommand( | ||
108 | "Objects", false, "delete object name", | ||
109 | "delete object name [--regex] <name>", | ||
110 | "Delete a scene object by name.", | ||
111 | "Command will ask for confirmation before proceeding.\n" | ||
112 | + "If --regex is specified then the name is treatead as a regular expression", | ||
113 | HandleDeleteObject); | ||
114 | |||
115 | m_console.Commands.AddCommand( | ||
116 | "Objects", false, "delete object outside", | ||
117 | "delete object outside", | ||
118 | "Delete all scene objects outside region boundaries", | ||
119 | "Command will ask for confirmation before proceeding.", | ||
120 | HandleDeleteObject); | ||
121 | |||
122 | m_console.Commands.AddCommand( | ||
123 | "Objects", | ||
124 | false, | ||
125 | "delete object pos", | ||
126 | "delete object pos <start-coord> to <end-coord>", | ||
127 | "Delete scene objects within the given area.", | ||
128 | ConsoleUtil.CoordHelp, | ||
129 | HandleDeleteObject); | ||
130 | |||
131 | m_console.Commands.AddCommand( | ||
132 | "Objects", | ||
133 | false, | ||
134 | "show object id", | ||
135 | "show object id [--full] <UUID-or-localID>", | ||
136 | "Show details of a scene object with the given UUID or localID", | ||
137 | "The --full option will print out information on all the parts of the object.\n" | ||
138 | + "For yet more detailed part information, use the \"show part\" commands.", | ||
139 | HandleShowObjectById); | ||
140 | |||
141 | m_console.Commands.AddCommand( | ||
142 | "Objects", | ||
143 | false, | ||
144 | "show object name", | ||
145 | "show object name [--full] [--regex] <name>", | ||
146 | "Show details of scene objects with the given name.", | ||
147 | "The --full option will print out information on all the parts of the object.\n" | ||
148 | + "For yet more detailed part information, use the \"show part\" commands.\n" | ||
149 | + "If --regex is specified then the name is treatead as a regular expression.", | ||
150 | HandleShowObjectByName); | ||
151 | |||
152 | m_console.Commands.AddCommand( | ||
153 | "Objects", | ||
154 | false, | ||
155 | "show object pos", | ||
156 | "show object pos [--full] <start-coord> to <end-coord>", | ||
157 | "Show details of scene objects within the given area.", | ||
158 | "The --full option will print out information on all the parts of the object.\n" | ||
159 | + "For yet more detailed part information, use the \"show part\" commands.\n" | ||
160 | + ConsoleUtil.CoordHelp, | ||
161 | HandleShowObjectByPos); | ||
162 | |||
163 | m_console.Commands.AddCommand( | ||
164 | "Objects", | ||
165 | false, | ||
166 | "show part id", | ||
167 | "show part id <UUID-or-localID>", | ||
168 | "Show details of a scene object part with the given UUID or localID", HandleShowPartById); | ||
169 | |||
170 | m_console.Commands.AddCommand( | ||
171 | "Objects", | ||
172 | false, | ||
173 | "show part name", | ||
174 | "show part name [--regex] <name>", | ||
175 | "Show details of scene object parts with the given name.", | ||
176 | "If --regex is specified then the name is treated as a regular expression", | ||
177 | HandleShowPartByName); | ||
178 | |||
179 | m_console.Commands.AddCommand( | ||
180 | "Objects", | ||
181 | false, | ||
182 | "show part pos", | ||
183 | "show part pos <start-coord> to <end-coord>", | ||
184 | "Show details of scene object parts within the given area.", | ||
185 | ConsoleUtil.CoordHelp, | ||
186 | HandleShowPartByPos); | ||
187 | |||
188 | m_console.Commands.AddCommand( | ||
189 | "Objects", | ||
190 | false, | ||
191 | "dump object id", | ||
192 | "dump object id <UUID-or-localID>", | ||
193 | "Dump the formatted serialization of the given object to the file <UUID>.xml", | ||
194 | "e.g. dump object uuid c1ed6809-cc24-4061-a4c2-93082a2d1f1d will dump serialization to c1ed6809-cc24-4061-a4c2-93082a2d1f1d.xml\n" | ||
195 | + "To locate the UUID or localID in the first place, you need to use the other show object commands.\n" | ||
196 | + "If a local ID is given then the filename used is still that for the UUID", | ||
197 | HandleDumpObjectById); | ||
198 | } | ||
199 | |||
200 | public void RemoveRegion(Scene scene) | ||
201 | { | ||
202 | // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||
203 | } | ||
204 | |||
205 | public void RegionLoaded(Scene scene) | ||
206 | { | ||
207 | // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||
208 | } | ||
209 | |||
210 | /// <summary> | ||
211 | /// Outputs the sogs to console. | ||
212 | /// </summary> | ||
213 | /// <param name='searchPredicate'></param> | ||
214 | /// <param name='showFull'>If true then output all part details. If false then output summary.</param> | ||
215 | private void OutputSogsToConsole(Predicate<SceneObjectGroup> searchPredicate, bool showFull) | ||
216 | { | ||
217 | List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups().FindAll(searchPredicate); | ||
218 | |||
219 | StringBuilder sb = new StringBuilder(); | ||
220 | |||
221 | foreach (SceneObjectGroup so in sceneObjects) | ||
222 | { | ||
223 | AddSceneObjectReport(sb, so, showFull); | ||
224 | sb.Append("\n"); | ||
225 | } | ||
226 | |||
227 | sb.AppendFormat("{0} object(s) found in {1}\n", sceneObjects.Count, m_scene.Name); | ||
228 | |||
229 | m_console.OutputFormat(sb.ToString()); | ||
230 | } | ||
231 | |||
232 | private void OutputSopsToConsole(Predicate<SceneObjectPart> searchPredicate, bool showFull) | ||
233 | { | ||
234 | List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups(); | ||
235 | List<SceneObjectPart> parts = new List<SceneObjectPart>(); | ||
236 | |||
237 | sceneObjects.ForEach(so => parts.AddRange(Array.FindAll<SceneObjectPart>(so.Parts, searchPredicate))); | ||
238 | |||
239 | StringBuilder sb = new StringBuilder(); | ||
240 | |||
241 | foreach (SceneObjectPart part in parts) | ||
242 | { | ||
243 | AddScenePartReport(sb, part, showFull); | ||
244 | sb.Append("\n"); | ||
245 | } | ||
246 | |||
247 | sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name); | ||
248 | |||
249 | m_console.OutputFormat(sb.ToString()); | ||
250 | } | ||
251 | |||
252 | private void HandleShowObjectById(string module, string[] cmdparams) | ||
253 | { | ||
254 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
255 | return; | ||
256 | |||
257 | bool showFull = false; | ||
258 | OptionSet options = new OptionSet().Add("full", v => showFull = v != null ); | ||
259 | |||
260 | List<string> mainParams = options.Parse(cmdparams); | ||
261 | |||
262 | if (mainParams.Count < 4) | ||
263 | { | ||
264 | m_console.OutputFormat("Usage: show object uuid <uuid>"); | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | UUID uuid; | ||
269 | uint localId; | ||
270 | if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out uuid, out localId)) | ||
271 | return; | ||
272 | |||
273 | SceneObjectGroup so; | ||
274 | |||
275 | if (localId != ConsoleUtil.LocalIdNotFound) | ||
276 | so = m_scene.GetSceneObjectGroup(localId); | ||
277 | else | ||
278 | so = m_scene.GetSceneObjectGroup(uuid); | ||
279 | |||
280 | if (so == null) | ||
281 | { | ||
282 | // m_console.OutputFormat("No part found with uuid {0}", objectUuid); | ||
283 | return; | ||
284 | } | ||
285 | |||
286 | StringBuilder sb = new StringBuilder(); | ||
287 | AddSceneObjectReport(sb, so, showFull); | ||
288 | |||
289 | m_console.OutputFormat(sb.ToString()); | ||
290 | } | ||
291 | |||
292 | private void HandleShowObjectByName(string module, string[] cmdparams) | ||
293 | { | ||
294 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
295 | return; | ||
296 | |||
297 | bool showFull = false; | ||
298 | bool useRegex = false; | ||
299 | OptionSet options = new OptionSet(); | ||
300 | options.Add("full", v => showFull = v != null ); | ||
301 | options.Add("regex", v => useRegex = v != null ); | ||
302 | |||
303 | List<string> mainParams = options.Parse(cmdparams); | ||
304 | |||
305 | if (mainParams.Count < 4) | ||
306 | { | ||
307 | m_console.OutputFormat("Usage: show object name [--full] [--regex] <name>"); | ||
308 | return; | ||
309 | } | ||
310 | |||
311 | string name = mainParams[3]; | ||
312 | |||
313 | Predicate<SceneObjectGroup> searchPredicate; | ||
314 | |||
315 | if (useRegex) | ||
316 | { | ||
317 | Regex nameRegex = new Regex(name); | ||
318 | searchPredicate = so => nameRegex.IsMatch(so.Name); | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | searchPredicate = so => so.Name == name; | ||
323 | } | ||
324 | |||
325 | OutputSogsToConsole(searchPredicate, showFull); | ||
326 | } | ||
327 | |||
328 | private void HandleShowObjectByPos(string module, string[] cmdparams) | ||
329 | { | ||
330 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
331 | return; | ||
332 | |||
333 | bool showFull = false; | ||
334 | OptionSet options = new OptionSet().Add("full", v => showFull = v != null ); | ||
335 | |||
336 | List<string> mainParams = options.Parse(cmdparams); | ||
337 | |||
338 | if (mainParams.Count < 5) | ||
339 | { | ||
340 | m_console.OutputFormat("Usage: show object pos [--full] <start-coord> to <end-coord>"); | ||
341 | return; | ||
342 | } | ||
343 | |||
344 | Vector3 startVector, endVector; | ||
345 | |||
346 | if (!TryParseVectorRange(cmdparams.Skip(3).Take(3), out startVector, out endVector)) | ||
347 | return; | ||
348 | |||
349 | Predicate<SceneObjectGroup> searchPredicate | ||
350 | = so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector); | ||
351 | |||
352 | OutputSogsToConsole(searchPredicate, showFull); | ||
353 | } | ||
354 | |||
355 | private void HandleShowPartById(string module, string[] cmdparams) | ||
356 | { | ||
357 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
358 | return; | ||
359 | |||
360 | // bool showFull = false; | ||
361 | OptionSet options = new OptionSet(); | ||
362 | // options.Add("full", v => showFull = v != null ); | ||
363 | |||
364 | List<string> mainParams = options.Parse(cmdparams); | ||
365 | |||
366 | if (mainParams.Count < 4) | ||
367 | { | ||
368 | //m_console.OutputFormat("Usage: show part id [--full] <UUID-or-localID>"); | ||
369 | m_console.OutputFormat("Usage: show part id <UUID-or-localID>"); | ||
370 | return; | ||
371 | } | ||
372 | |||
373 | UUID objectUuid; | ||
374 | uint localId; | ||
375 | if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out objectUuid, out localId)) | ||
376 | return; | ||
377 | |||
378 | SceneObjectPart sop; | ||
379 | if (localId == ConsoleUtil.LocalIdNotFound) | ||
380 | sop = m_scene.GetSceneObjectPart(objectUuid); | ||
381 | else | ||
382 | sop = m_scene.GetSceneObjectPart(localId); | ||
383 | |||
384 | if (sop == null) | ||
385 | { | ||
386 | // m_console.OutputFormat("No part found with uuid {0}", objectUuid); | ||
387 | return; | ||
388 | } | ||
389 | |||
390 | StringBuilder sb = new StringBuilder(); | ||
391 | AddScenePartReport(sb, sop, true); | ||
392 | |||
393 | m_console.OutputFormat(sb.ToString()); | ||
394 | } | ||
395 | |||
396 | private void HandleShowPartByPos(string module, string[] cmdparams) | ||
397 | { | ||
398 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
399 | return; | ||
400 | |||
401 | // bool showFull = false; | ||
402 | OptionSet options = new OptionSet(); | ||
403 | // options.Add("full", v => showFull = v != null ); | ||
404 | |||
405 | List<string> mainParams = options.Parse(cmdparams); | ||
406 | |||
407 | if (mainParams.Count < 5) | ||
408 | { | ||
409 | //m_console.OutputFormat("Usage: show part pos <start-coord> to <end-coord>"); | ||
410 | m_console.OutputFormat("Usage: show part pos [--full] <start-coord> to <end-coord>"); | ||
411 | return; | ||
412 | } | ||
413 | |||
414 | string rawConsoleStartVector = mainParams[3]; | ||
415 | Vector3 startVector; | ||
416 | |||
417 | if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) | ||
418 | { | ||
419 | m_console.OutputFormat("Error: Start vector '{0}' does not have a valid format", rawConsoleStartVector); | ||
420 | return; | ||
421 | } | ||
422 | |||
423 | string rawConsoleEndVector = mainParams[5]; | ||
424 | Vector3 endVector; | ||
425 | |||
426 | if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) | ||
427 | { | ||
428 | m_console.OutputFormat("Error: End vector '{0}' does not have a valid format", rawConsoleEndVector); | ||
429 | return; | ||
430 | } | ||
431 | |||
432 | OutputSopsToConsole(sop => Util.IsInsideBox(sop.AbsolutePosition, startVector, endVector), true); | ||
433 | } | ||
434 | |||
435 | private void HandleShowPartByName(string module, string[] cmdparams) | ||
436 | { | ||
437 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
438 | return; | ||
439 | |||
440 | // bool showFull = false; | ||
441 | bool useRegex = false; | ||
442 | OptionSet options = new OptionSet(); | ||
443 | // options.Add("full", v => showFull = v != null ); | ||
444 | options.Add("regex", v => useRegex = v != null ); | ||
445 | |||
446 | List<string> mainParams = options.Parse(cmdparams); | ||
447 | |||
448 | if (mainParams.Count < 4) | ||
449 | { | ||
450 | m_console.OutputFormat("Usage: show part name [--regex] <name>"); | ||
451 | //m_console.OutputFormat("Usage: show part name [--full] [--regex] <name>"); | ||
452 | return; | ||
453 | } | ||
454 | |||
455 | string name = mainParams[3]; | ||
456 | |||
457 | Predicate<SceneObjectPart> searchPredicate; | ||
458 | |||
459 | if (useRegex) | ||
460 | { | ||
461 | Regex nameRegex = new Regex(name); | ||
462 | searchPredicate = sop => nameRegex.IsMatch(sop.Name); | ||
463 | } | ||
464 | else | ||
465 | { | ||
466 | searchPredicate = sop => sop.Name == name; | ||
467 | } | ||
468 | |||
469 | OutputSopsToConsole(searchPredicate, true); | ||
470 | } | ||
471 | |||
472 | private void HandleDumpObjectById(string module, string[] cmdparams) | ||
473 | { | ||
474 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
475 | return; | ||
476 | |||
477 | if (cmdparams.Length < 4) | ||
478 | { | ||
479 | m_console.OutputFormat("Usage: dump object id <UUID-or-localID>"); | ||
480 | return; | ||
481 | } | ||
482 | |||
483 | UUID objectUuid; | ||
484 | uint localId; | ||
485 | if (!ConsoleUtil.TryParseConsoleId(m_console, cmdparams[3], out objectUuid, out localId)) | ||
486 | return; | ||
487 | |||
488 | SceneObjectGroup so; | ||
489 | if (localId == ConsoleUtil.LocalIdNotFound) | ||
490 | so = m_scene.GetSceneObjectGroup(objectUuid); | ||
491 | else | ||
492 | so = m_scene.GetSceneObjectGroup(localId); | ||
493 | |||
494 | if (so == null) | ||
495 | { | ||
496 | // m_console.OutputFormat("No part found with uuid {0}", objectUuid); | ||
497 | return; | ||
498 | } | ||
499 | |||
500 | // In case we found it via local ID. | ||
501 | objectUuid = so.UUID; | ||
502 | |||
503 | string fileName = string.Format("{0}.xml", objectUuid); | ||
504 | |||
505 | if (!ConsoleUtil.CheckFileDoesNotExist(m_console, fileName)) | ||
506 | return; | ||
507 | |||
508 | using (XmlTextWriter xtw = new XmlTextWriter(fileName, Encoding.UTF8)) | ||
509 | { | ||
510 | xtw.Formatting = Formatting.Indented; | ||
511 | SceneObjectSerializer.ToOriginalXmlFormat(so, xtw, true); | ||
512 | } | ||
513 | |||
514 | m_console.OutputFormat("Object dumped to file {0}", fileName); | ||
515 | } | ||
516 | |||
517 | /// <summary> | ||
518 | /// Append a scene object report to an input StringBuilder | ||
519 | /// </summary> | ||
520 | /// <returns></returns> | ||
521 | /// <param name='sb'></param> | ||
522 | /// <param name='so'</param> | ||
523 | /// <param name='showFull'> | ||
524 | /// If true then information on all parts of an object is appended. | ||
525 | /// If false then only summary information about an object is appended. | ||
526 | /// </param> | ||
527 | private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so, bool showFull) | ||
528 | { | ||
529 | if (showFull) | ||
530 | { | ||
531 | foreach (SceneObjectPart sop in so.Parts) | ||
532 | { | ||
533 | AddScenePartReport(sb, sop, false); | ||
534 | sb.Append("\n"); | ||
535 | } | ||
536 | } | ||
537 | else | ||
538 | { | ||
539 | AddSummarySceneObjectReport(sb, so); | ||
540 | } | ||
541 | |||
542 | return sb; | ||
543 | } | ||
544 | |||
545 | private StringBuilder AddSummarySceneObjectReport(StringBuilder sb, SceneObjectGroup so) | ||
546 | { | ||
547 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
548 | cdl.AddRow("Name", so.Name); | ||
549 | cdl.AddRow("Description", so.Description); | ||
550 | cdl.AddRow("Local ID", so.LocalId); | ||
551 | cdl.AddRow("UUID", so.UUID); | ||
552 | cdl.AddRow("Location", string.Format("{0} @ {1}", so.AbsolutePosition, so.Scene.Name)); | ||
553 | cdl.AddRow("Parts", so.PrimCount); | ||
554 | cdl.AddRow("Flags", so.RootPart.Flags); | ||
555 | |||
556 | return sb.Append(cdl.ToString()); | ||
557 | } | ||
558 | |||
559 | /// <summary> | ||
560 | /// Append a scene object part report to an input StringBuilder | ||
561 | /// </summary> | ||
562 | /// <returns></returns> | ||
563 | /// <param name='sb'></param> | ||
564 | /// <param name='sop'</param> | ||
565 | /// <param name='showFull'> | ||
566 | /// If true then information on each inventory item will be shown. | ||
567 | /// If false then only summary inventory information is shown. | ||
568 | /// </param> | ||
569 | private StringBuilder AddScenePartReport(StringBuilder sb, SceneObjectPart sop, bool showFull) | ||
570 | { | ||
571 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
572 | cdl.AddRow("Name", sop.Name); | ||
573 | cdl.AddRow("Description", sop.Description); | ||
574 | cdl.AddRow("Local ID", sop.LocalId); | ||
575 | cdl.AddRow("UUID", sop.UUID); | ||
576 | cdl.AddRow("Location", string.Format("{0} @ {1}", sop.AbsolutePosition, sop.ParentGroup.Scene.Name)); | ||
577 | cdl.AddRow( | ||
578 | "Parent", | ||
579 | sop.IsRoot ? "Is Root" : string.Format("{0} {1}", sop.ParentGroup.Name, sop.ParentGroup.UUID)); | ||
580 | cdl.AddRow("Link number", sop.LinkNum); | ||
581 | cdl.AddRow("Flags", sop.Flags); | ||
582 | |||
583 | if (showFull) | ||
584 | { | ||
585 | PrimitiveBaseShape s = sop.Shape; | ||
586 | cdl.AddRow("FlexiDrag", s.FlexiDrag); | ||
587 | cdl.AddRow("FlexiEntry", s.FlexiEntry); | ||
588 | cdl.AddRow("FlexiForce", string.Format("<{0},{1},{2}>", s.FlexiForceX, s.FlexiForceY, s.FlexiForceZ)); | ||
589 | cdl.AddRow("FlexiGravity", s.FlexiGravity); | ||
590 | cdl.AddRow("FlexiSoftness", s.FlexiSoftness); | ||
591 | cdl.AddRow("HollowShape", s.HollowShape); | ||
592 | cdl.AddRow( | ||
593 | "LightColor", | ||
594 | string.Format("<{0},{1},{2},{3}>", s.LightColorR, s.LightColorB, s.LightColorG, s.LightColorA)); | ||
595 | cdl.AddRow("LightCutoff", s.LightCutoff); | ||
596 | cdl.AddRow("LightEntry", s.LightEntry); | ||
597 | cdl.AddRow("LightFalloff", s.LightFalloff); | ||
598 | cdl.AddRow("LightIntensity", s.LightIntensity); | ||
599 | cdl.AddRow("LightRadius", s.LightRadius); | ||
600 | cdl.AddRow("Location (relative)", sop.RelativePosition); | ||
601 | cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a")); | ||
602 | cdl.AddRow("PathBegin", s.PathBegin); | ||
603 | cdl.AddRow("PathEnd", s.PathEnd); | ||
604 | cdl.AddRow("PathCurve", s.PathCurve); | ||
605 | cdl.AddRow("PathRadiusOffset", s.PathRadiusOffset); | ||
606 | cdl.AddRow("PathRevolutions", s.PathRevolutions); | ||
607 | cdl.AddRow("PathScale", string.Format("<{0},{1}>", s.PathScaleX, s.PathScaleY)); | ||
608 | cdl.AddRow("PathSkew", string.Format("<{0},{1}>", s.PathShearX, s.PathShearY)); | ||
609 | cdl.AddRow("FlexiDrag", s.PathSkew); | ||
610 | cdl.AddRow("PathTaper", string.Format("<{0},{1}>", s.PathTaperX, s.PathTaperY)); | ||
611 | cdl.AddRow("PathTwist", s.PathTwist); | ||
612 | cdl.AddRow("PathTwistBegin", s.PathTwistBegin); | ||
613 | cdl.AddRow("PCode", s.PCode); | ||
614 | cdl.AddRow("ProfileBegin", s.ProfileBegin); | ||
615 | cdl.AddRow("ProfileEnd", s.ProfileEnd); | ||
616 | cdl.AddRow("ProfileHollow", s.ProfileHollow); | ||
617 | cdl.AddRow("ProfileShape", s.ProfileShape); | ||
618 | cdl.AddRow("ProjectionAmbiance", s.ProjectionAmbiance); | ||
619 | cdl.AddRow("ProjectionEntry", s.ProjectionEntry); | ||
620 | cdl.AddRow("ProjectionFocus", s.ProjectionFocus); | ||
621 | cdl.AddRow("ProjectionFOV", s.ProjectionFOV); | ||
622 | cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID); | ||
623 | cdl.AddRow("Rotation (Relative)", sop.RotationOffset); | ||
624 | cdl.AddRow("Rotation (World)", sop.GetWorldRotation()); | ||
625 | cdl.AddRow("Scale", s.Scale); | ||
626 | cdl.AddRow( | ||
627 | "SculptData", | ||
628 | string.Format("{0} bytes", s.SculptData != null ? s.SculptData.Length.ToString() : "n/a")); | ||
629 | cdl.AddRow("SculptEntry", s.SculptEntry); | ||
630 | cdl.AddRow("SculptTexture", s.SculptTexture); | ||
631 | cdl.AddRow("SculptType", s.SculptType); | ||
632 | cdl.AddRow("State", s.State); | ||
633 | |||
634 | // TODO, need to display more information about textures but in a compact format | ||
635 | // to stop output becoming huge. | ||
636 | for (int i = 0; i < sop.GetNumberOfSides(); i++) | ||
637 | { | ||
638 | Primitive.TextureEntryFace teFace = s.Textures.FaceTextures[i]; | ||
639 | |||
640 | UUID textureID; | ||
641 | |||
642 | if (teFace != null) | ||
643 | textureID = teFace.TextureID; | ||
644 | else | ||
645 | textureID = s.Textures.DefaultTexture.TextureID; | ||
646 | |||
647 | cdl.AddRow(string.Format("Face {0} texture ID", i), textureID); | ||
648 | } | ||
649 | |||
650 | //cdl.AddRow("Textures", string.Format("{0} entries", s.Textures. | ||
651 | } | ||
652 | |||
653 | object itemsOutput; | ||
654 | if (showFull) | ||
655 | { | ||
656 | StringBuilder itemsSb = new StringBuilder("\n"); | ||
657 | itemsOutput = AddScenePartItemsReport(itemsSb, sop.Inventory).ToString(); | ||
658 | } | ||
659 | else | ||
660 | { | ||
661 | itemsOutput = sop.Inventory.Count; | ||
662 | } | ||
663 | |||
664 | cdl.AddRow("Items", itemsOutput); | ||
665 | |||
666 | return sb.Append(cdl.ToString()); | ||
667 | } | ||
668 | |||
669 | private StringBuilder AddScenePartItemsReport(StringBuilder sb, IEntityInventory inv) | ||
670 | { | ||
671 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
672 | cdt.Indent = 2; | ||
673 | |||
674 | cdt.AddColumn("Name", 50); | ||
675 | cdt.AddColumn("Type", 12); | ||
676 | cdt.AddColumn("Running", 7); | ||
677 | cdt.AddColumn("Item UUID", 36); | ||
678 | cdt.AddColumn("Asset UUID", 36); | ||
679 | |||
680 | foreach (TaskInventoryItem item in inv.GetInventoryItems()) | ||
681 | { | ||
682 | bool foundScriptInstance, scriptRunning; | ||
683 | foundScriptInstance | ||
684 | = SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, item, out scriptRunning); | ||
685 | |||
686 | cdt.AddRow( | ||
687 | item.Name, | ||
688 | ((InventoryType)item.InvType).ToString(), | ||
689 | foundScriptInstance ? scriptRunning.ToString() : "n/a", | ||
690 | item.ItemID.ToString(), | ||
691 | item.AssetID.ToString()); | ||
692 | } | ||
693 | |||
694 | return sb.Append(cdt.ToString()); | ||
695 | } | ||
696 | |||
697 | private void HandleDeleteObject(string module, string[] cmd) | ||
698 | { | ||
699 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
700 | return; | ||
701 | |||
702 | if (cmd.Length < 3) | ||
703 | return; | ||
704 | |||
705 | string mode = cmd[2]; | ||
706 | string o = ""; | ||
707 | |||
708 | if (mode != "outside") | ||
709 | { | ||
710 | if (cmd.Length < 4) | ||
711 | return; | ||
712 | |||
713 | o = cmd[3]; | ||
714 | } | ||
715 | |||
716 | List<SceneObjectGroup> deletes = null; | ||
717 | UUID match; | ||
718 | bool requireConfirmation = true; | ||
719 | |||
720 | switch (mode) | ||
721 | { | ||
722 | case "owner": | ||
723 | if (!UUID.TryParse(o, out match)) | ||
724 | return; | ||
725 | |||
726 | deletes = new List<SceneObjectGroup>(); | ||
727 | |||
728 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
729 | { | ||
730 | if (g.OwnerID == match && !g.IsAttachment) | ||
731 | deletes.Add(g); | ||
732 | }); | ||
733 | |||
734 | // if (deletes.Count == 0) | ||
735 | // m_console.OutputFormat("No objects were found with owner {0}", match); | ||
736 | |||
737 | break; | ||
738 | |||
739 | case "creator": | ||
740 | if (!UUID.TryParse(o, out match)) | ||
741 | return; | ||
742 | |||
743 | deletes = new List<SceneObjectGroup>(); | ||
744 | |||
745 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
746 | { | ||
747 | if (g.RootPart.CreatorID == match && !g.IsAttachment) | ||
748 | deletes.Add(g); | ||
749 | }); | ||
750 | |||
751 | // if (deletes.Count == 0) | ||
752 | // m_console.OutputFormat("No objects were found with creator {0}", match); | ||
753 | |||
754 | break; | ||
755 | |||
756 | case "id": | ||
757 | UUID uuid; | ||
758 | uint localId; | ||
759 | if (!ConsoleUtil.TryParseConsoleId(m_console, o, out uuid, out localId)) | ||
760 | return; | ||
761 | |||
762 | requireConfirmation = false; | ||
763 | deletes = new List<SceneObjectGroup>(); | ||
764 | |||
765 | SceneObjectGroup so; | ||
766 | if (localId == ConsoleUtil.LocalIdNotFound) | ||
767 | so = m_scene.GetSceneObjectGroup(uuid); | ||
768 | else | ||
769 | so = m_scene.GetSceneObjectGroup(localId); | ||
770 | |||
771 | if (!so.IsAttachment) | ||
772 | deletes.Add(so); | ||
773 | |||
774 | // if (deletes.Count == 0) | ||
775 | // m_console.OutputFormat("No objects were found with uuid {0}", match); | ||
776 | |||
777 | break; | ||
778 | |||
779 | case "name": | ||
780 | deletes = GetDeleteCandidatesByName(module, cmd); | ||
781 | break; | ||
782 | |||
783 | case "outside": | ||
784 | deletes = new List<SceneObjectGroup>(); | ||
785 | |||
786 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
787 | { | ||
788 | SceneObjectPart rootPart = g.RootPart; | ||
789 | bool delete = false; | ||
790 | |||
791 | if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) | ||
792 | { | ||
793 | delete = true; | ||
794 | } | ||
795 | else | ||
796 | { | ||
797 | ILandObject parcel | ||
798 | = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); | ||
799 | |||
800 | if (parcel == null || parcel.LandData.Name == "NO LAND") | ||
801 | delete = true; | ||
802 | } | ||
803 | |||
804 | if (delete && !g.IsAttachment && !deletes.Contains(g)) | ||
805 | deletes.Add(g); | ||
806 | }); | ||
807 | |||
808 | if (deletes.Count == 0) | ||
809 | m_console.OutputFormat("No objects were found outside region bounds"); | ||
810 | |||
811 | break; | ||
812 | |||
813 | case "pos": | ||
814 | deletes = GetDeleteCandidatesByPos(module, cmd); | ||
815 | break; | ||
816 | |||
817 | default: | ||
818 | m_console.OutputFormat("Unrecognized mode {0}", mode); | ||
819 | return; | ||
820 | } | ||
821 | |||
822 | if (deletes == null || deletes.Count <= 0) | ||
823 | return; | ||
824 | |||
825 | if (requireConfirmation) | ||
826 | { | ||
827 | string response = MainConsole.Instance.CmdPrompt( | ||
828 | string.Format( | ||
829 | "Are you sure that you want to delete {0} objects from {1}", | ||
830 | deletes.Count, m_scene.RegionInfo.RegionName), | ||
831 | "y/N"); | ||
832 | |||
833 | if (response.ToLower() != "y") | ||
834 | { | ||
835 | MainConsole.Instance.OutputFormat( | ||
836 | "Aborting delete of {0} objects from {1}", deletes.Count, m_scene.RegionInfo.RegionName); | ||
837 | |||
838 | return; | ||
839 | } | ||
840 | } | ||
841 | |||
842 | m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName); | ||
843 | |||
844 | foreach (SceneObjectGroup g in deletes) | ||
845 | { | ||
846 | m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name); | ||
847 | m_scene.DeleteSceneObject(g, false); | ||
848 | } | ||
849 | } | ||
850 | |||
851 | private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams) | ||
852 | { | ||
853 | bool useRegex = false; | ||
854 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); | ||
855 | |||
856 | List<string> mainParams = options.Parse(cmdparams); | ||
857 | |||
858 | if (mainParams.Count < 4) | ||
859 | { | ||
860 | m_console.OutputFormat("Usage: delete object name [--regex] <name>"); | ||
861 | return null; | ||
862 | } | ||
863 | |||
864 | string name = mainParams[3]; | ||
865 | |||
866 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); | ||
867 | Action<SceneObjectGroup> searchAction; | ||
868 | |||
869 | if (useRegex) | ||
870 | { | ||
871 | Regex nameRegex = new Regex(name); | ||
872 | searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; | ||
873 | } | ||
874 | else | ||
875 | { | ||
876 | searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; | ||
877 | } | ||
878 | |||
879 | m_scene.ForEachSOG(searchAction); | ||
880 | |||
881 | if (sceneObjects.Count == 0) | ||
882 | m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); | ||
883 | |||
884 | return sceneObjects; | ||
885 | } | ||
886 | |||
887 | /// <summary> | ||
888 | /// Get scene object delete candidates by position | ||
889 | /// </summary> | ||
890 | /// <param name='module'></param> | ||
891 | /// <param name='cmdparams'></param> | ||
892 | /// <returns>null if parsing failed on one of the arguments, otherwise a list of objects to delete. If there | ||
893 | /// are no objects to delete then the list will be empty./returns> | ||
894 | private List<SceneObjectGroup> GetDeleteCandidatesByPos(string module, string[] cmdparams) | ||
895 | { | ||
896 | if (cmdparams.Length < 5) | ||
897 | { | ||
898 | m_console.OutputFormat("Usage: delete object pos <start-coord> to <end-coord>"); | ||
899 | return null; | ||
900 | } | ||
901 | |||
902 | Vector3 startVector, endVector; | ||
903 | |||
904 | if (!TryParseVectorRange(cmdparams.Skip(3).Take(3), out startVector, out endVector)) | ||
905 | return null; | ||
906 | |||
907 | return m_scene.GetSceneObjectGroups().FindAll( | ||
908 | so => !so.IsAttachment && Util.IsInsideBox(so.AbsolutePosition, startVector, endVector)); | ||
909 | } | ||
910 | |||
911 | private bool TryParseVectorRange(IEnumerable<string> rawComponents, out Vector3 startVector, out Vector3 endVector) | ||
912 | { | ||
913 | string rawConsoleStartVector = rawComponents.Take(1).Single(); | ||
914 | |||
915 | if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) | ||
916 | { | ||
917 | m_console.OutputFormat("Error: Start vector '{0}' does not have a valid format", rawConsoleStartVector); | ||
918 | endVector = Vector3.Zero; | ||
919 | |||
920 | return false; | ||
921 | } | ||
922 | |||
923 | string rawConsoleEndVector = rawComponents.Skip(2).Take(1).Single(); | ||
924 | |||
925 | if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) | ||
926 | { | ||
927 | m_console.OutputFormat("Error: End vector '{0}' does not have a valid format", rawConsoleEndVector); | ||
928 | return false; | ||
929 | } | ||
930 | |||
931 | return true; | ||
932 | } | ||
933 | } | ||
934 | } \ No newline at end of file | ||