diff options
Diffstat (limited to 'OpenSim/Region')
14 files changed, 538 insertions, 75 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 6f00957..6ccabf1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -5962,7 +5962,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5962 | msgpack.MessageBlock.ID, | 5962 | msgpack.MessageBlock.ID, |
5963 | msgpack.MessageBlock.Offline != 0 ? true : false, | 5963 | msgpack.MessageBlock.Offline != 0 ? true : false, |
5964 | msgpack.MessageBlock.Position, | 5964 | msgpack.MessageBlock.Position, |
5965 | msgpack.MessageBlock.BinaryBucket); | 5965 | msgpack.MessageBlock.BinaryBucket, |
5966 | true); | ||
5966 | 5967 | ||
5967 | handlerInstantMessage(this, im); | 5968 | handlerInstantMessage(this, im); |
5968 | } | 5969 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 60ab70e..b3db064 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -227,6 +227,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
227 | m_pausedAckTimeout = 1000 * 300; // 5 minutes | 227 | m_pausedAckTimeout = 1000 * 300; // 5 minutes |
228 | } | 228 | } |
229 | 229 | ||
230 | // FIXME: This actually only needs to be done once since the PacketPool is shared across all servers. | ||
231 | // However, there is no harm in temporarily doing it multiple times. | ||
232 | IConfig packetConfig = configSource.Configs["PacketPool"]; | ||
233 | if (packetConfig != null) | ||
234 | { | ||
235 | PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); | ||
236 | PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); | ||
237 | } | ||
238 | |||
230 | #region BinaryStats | 239 | #region BinaryStats |
231 | config = configSource.Configs["Statistics.Binary"]; | 240 | config = configSource.Configs["Statistics.Binary"]; |
232 | m_shouldCollectStats = false; | 241 | m_shouldCollectStats = false; |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs new file mode 100644 index 0000000..fc9406b --- /dev/null +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | |||
@@ -0,0 +1,249 @@ | |||
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 OpenMetaverse; | ||
32 | using OpenMetaverse.Packets; | ||
33 | using log4net; | ||
34 | |||
35 | namespace OpenSim.Region.ClientStack.LindenUDP | ||
36 | { | ||
37 | public sealed class PacketPool | ||
38 | { | ||
39 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
40 | |||
41 | private static readonly PacketPool instance = new PacketPool(); | ||
42 | |||
43 | private bool packetPoolEnabled = true; | ||
44 | private bool dataBlockPoolEnabled = true; | ||
45 | |||
46 | /// <summary> | ||
47 | /// Pool of packets available for reuse. | ||
48 | /// </summary> | ||
49 | private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>(); | ||
50 | |||
51 | private static Dictionary<Type, Stack<Object>> DataBlocks = | ||
52 | new Dictionary<Type, Stack<Object>>(); | ||
53 | |||
54 | static PacketPool() | ||
55 | { | ||
56 | } | ||
57 | |||
58 | public static PacketPool Instance | ||
59 | { | ||
60 | get { return instance; } | ||
61 | } | ||
62 | |||
63 | public bool RecyclePackets | ||
64 | { | ||
65 | set { packetPoolEnabled = value; } | ||
66 | get { return packetPoolEnabled; } | ||
67 | } | ||
68 | |||
69 | public bool RecycleDataBlocks | ||
70 | { | ||
71 | set { dataBlockPoolEnabled = value; } | ||
72 | get { return dataBlockPoolEnabled; } | ||
73 | } | ||
74 | |||
75 | public Packet GetPacket(PacketType type) | ||
76 | { | ||
77 | Packet packet; | ||
78 | |||
79 | if (!packetPoolEnabled) | ||
80 | return Packet.BuildPacket(type); | ||
81 | |||
82 | lock (pool) | ||
83 | { | ||
84 | if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0) | ||
85 | { | ||
86 | // Creating a new packet if we cannot reuse an old package | ||
87 | packet = Packet.BuildPacket(type); | ||
88 | } | ||
89 | else | ||
90 | { | ||
91 | // Recycle old packages | ||
92 | packet = (pool[type]).Pop(); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | return packet; | ||
97 | } | ||
98 | |||
99 | // private byte[] decoded_header = new byte[10]; | ||
100 | private static PacketType GetType(byte[] bytes) | ||
101 | { | ||
102 | byte[] decoded_header = new byte[10 + 8]; | ||
103 | ushort id; | ||
104 | PacketFrequency freq; | ||
105 | |||
106 | if ((bytes[0] & Helpers.MSG_ZEROCODED) != 0) | ||
107 | { | ||
108 | Helpers.ZeroDecode(bytes, 16, decoded_header); | ||
109 | } | ||
110 | else | ||
111 | { | ||
112 | Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10); | ||
113 | } | ||
114 | |||
115 | if (decoded_header[6] == 0xFF) | ||
116 | { | ||
117 | if (decoded_header[7] == 0xFF) | ||
118 | { | ||
119 | id = (ushort) ((decoded_header[8] << 8) + decoded_header[9]); | ||
120 | freq = PacketFrequency.Low; | ||
121 | } | ||
122 | else | ||
123 | { | ||
124 | id = decoded_header[7]; | ||
125 | freq = PacketFrequency.Medium; | ||
126 | } | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | id = decoded_header[6]; | ||
131 | freq = PacketFrequency.High; | ||
132 | } | ||
133 | |||
134 | return Packet.GetType(id, freq); | ||
135 | } | ||
136 | |||
137 | public Packet GetPacket(byte[] bytes, ref int packetEnd, byte[] zeroBuffer) | ||
138 | { | ||
139 | PacketType type = GetType(bytes); | ||
140 | |||
141 | Array.Clear(zeroBuffer, 0, zeroBuffer.Length); | ||
142 | |||
143 | int i = 0; | ||
144 | Packet packet = GetPacket(type); | ||
145 | if (packet == null) | ||
146 | m_log.WarnFormat("[PACKETPOOL]: Failed to get packet of type {0}", type); | ||
147 | else | ||
148 | packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer); | ||
149 | |||
150 | return packet; | ||
151 | } | ||
152 | |||
153 | /// <summary> | ||
154 | /// Return a packet to the packet pool | ||
155 | /// </summary> | ||
156 | /// <param name="packet"></param> | ||
157 | public void ReturnPacket(Packet packet) | ||
158 | { | ||
159 | if (dataBlockPoolEnabled) | ||
160 | { | ||
161 | switch (packet.Type) | ||
162 | { | ||
163 | case PacketType.ObjectUpdate: | ||
164 | ObjectUpdatePacket oup = (ObjectUpdatePacket)packet; | ||
165 | |||
166 | foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData) | ||
167 | ReturnDataBlock<ObjectUpdatePacket.ObjectDataBlock>(oupod); | ||
168 | |||
169 | oup.ObjectData = null; | ||
170 | break; | ||
171 | |||
172 | case PacketType.ImprovedTerseObjectUpdate: | ||
173 | ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet; | ||
174 | |||
175 | foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData) | ||
176 | ReturnDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod); | ||
177 | |||
178 | itoup.ObjectData = null; | ||
179 | break; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | if (packetPoolEnabled) | ||
184 | { | ||
185 | switch (packet.Type) | ||
186 | { | ||
187 | // List pooling packets here | ||
188 | case PacketType.PacketAck: | ||
189 | case PacketType.ObjectUpdate: | ||
190 | case PacketType.ImprovedTerseObjectUpdate: | ||
191 | lock (pool) | ||
192 | { | ||
193 | PacketType type = packet.Type; | ||
194 | |||
195 | if (!pool.ContainsKey(type)) | ||
196 | { | ||
197 | pool[type] = new Stack<Packet>(); | ||
198 | } | ||
199 | |||
200 | if ((pool[type]).Count < 50) | ||
201 | { | ||
202 | (pool[type]).Push(packet); | ||
203 | } | ||
204 | } | ||
205 | break; | ||
206 | |||
207 | // Other packets wont pool | ||
208 | default: | ||
209 | return; | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | |||
214 | public static T GetDataBlock<T>() where T: new() | ||
215 | { | ||
216 | lock (DataBlocks) | ||
217 | { | ||
218 | Stack<Object> s; | ||
219 | |||
220 | if (DataBlocks.TryGetValue(typeof(T), out s)) | ||
221 | { | ||
222 | if (s.Count > 0) | ||
223 | return (T)s.Pop(); | ||
224 | } | ||
225 | else | ||
226 | { | ||
227 | DataBlocks[typeof(T)] = new Stack<Object>(); | ||
228 | } | ||
229 | |||
230 | return new T(); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | public static void ReturnDataBlock<T>(T block) where T: new() | ||
235 | { | ||
236 | if (block == null) | ||
237 | return; | ||
238 | |||
239 | lock (DataBlocks) | ||
240 | { | ||
241 | if (!DataBlocks.ContainsKey(typeof(T))) | ||
242 | DataBlocks[typeof(T)] = new Stack<Object>(); | ||
243 | |||
244 | if (DataBlocks[typeof(T)].Count < 50) | ||
245 | DataBlocks[typeof(T)].Push(block); | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs index d942e87..5ec0ea9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs | |||
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
141 | client.FirstName+" "+client.LastName, | 141 | client.FirstName+" "+client.LastName, |
142 | destID, (byte)211, false, | 142 | destID, (byte)211, false, |
143 | String.Empty, | 143 | String.Empty, |
144 | transactionID, false, new Vector3(), new byte[0]), | 144 | transactionID, false, new Vector3(), new byte[0], true), |
145 | delegate(bool success) {} ); | 145 | delegate(bool success) {} ); |
146 | } | 146 | } |
147 | } | 147 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index c14cb17..21dff4b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | |||
@@ -313,6 +313,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
313 | m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); | 313 | m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); |
314 | } | 314 | } |
315 | } | 315 | } |
316 | |||
317 | // XXX: This code was placed here to try and accomdate RLV which moves given folders named #RLV/~<name> | ||
318 | // to a folder called name in #RLV. However, this approach may not be ultimately correct - from analysis | ||
319 | // of Firestorm 4.2.2 on sending an InventoryOffered instead of TaskInventoryOffered (as was previously | ||
320 | // done), the viewer itself would appear to move and rename the folder, rather than the simulator doing it here. | ||
316 | else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) | 321 | else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) |
317 | { | 322 | { |
318 | UUID destinationFolderID = UUID.Zero; | 323 | UUID destinationFolderID = UUID.Zero; |
@@ -324,6 +329,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
324 | 329 | ||
325 | if (destinationFolderID != UUID.Zero) | 330 | if (destinationFolderID != UUID.Zero) |
326 | { | 331 | { |
332 | InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); | ||
333 | if (destinationFolder == null) | ||
334 | { | ||
335 | m_log.WarnFormat( | ||
336 | "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", | ||
337 | client.Name, scene.Name, destinationFolderID); | ||
338 | |||
339 | return; | ||
340 | } | ||
341 | |||
327 | IInventoryService invService = scene.InventoryService; | 342 | IInventoryService invService = scene.InventoryService; |
328 | 343 | ||
329 | UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip | 344 | UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip |
@@ -331,9 +346,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
331 | InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); | 346 | InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); |
332 | item = invService.GetItem(item); | 347 | item = invService.GetItem(item); |
333 | InventoryFolderBase folder = null; | 348 | InventoryFolderBase folder = null; |
349 | UUID? previousParentFolderID = null; | ||
334 | 350 | ||
335 | if (item != null) // It's an item | 351 | if (item != null) // It's an item |
336 | { | 352 | { |
353 | previousParentFolderID = item.Folder; | ||
337 | item.Folder = destinationFolderID; | 354 | item.Folder = destinationFolderID; |
338 | 355 | ||
339 | invService.DeleteItems(item.Owner, new List<UUID>() { item.ID }); | 356 | invService.DeleteItems(item.Owner, new List<UUID>() { item.ID }); |
@@ -346,10 +363,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
346 | 363 | ||
347 | if (folder != null) // It's a folder | 364 | if (folder != null) // It's a folder |
348 | { | 365 | { |
366 | previousParentFolderID = folder.ParentID; | ||
349 | folder.ParentID = destinationFolderID; | 367 | folder.ParentID = destinationFolderID; |
350 | invService.MoveFolder(folder); | 368 | invService.MoveFolder(folder); |
351 | } | 369 | } |
352 | } | 370 | } |
371 | |||
372 | // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). | ||
373 | if (previousParentFolderID != null) | ||
374 | { | ||
375 | InventoryFolderBase previousParentFolder | ||
376 | = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); | ||
377 | previousParentFolder = invService.GetFolder(previousParentFolder); | ||
378 | scene.SendInventoryUpdate(client, previousParentFolder, true, true); | ||
379 | |||
380 | scene.SendInventoryUpdate(client, destinationFolder, true, true); | ||
381 | } | ||
353 | } | 382 | } |
354 | } | 383 | } |
355 | else if ( | 384 | else if ( |
@@ -370,9 +399,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
370 | InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); | 399 | InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); |
371 | item = invService.GetItem(item); | 400 | item = invService.GetItem(item); |
372 | InventoryFolderBase folder = null; | 401 | InventoryFolderBase folder = null; |
402 | UUID? previousParentFolderID = null; | ||
373 | 403 | ||
374 | if (item != null && trashFolder != null) | 404 | if (item != null && trashFolder != null) |
375 | { | 405 | { |
406 | previousParentFolderID = item.Folder; | ||
376 | item.Folder = trashFolder.ID; | 407 | item.Folder = trashFolder.ID; |
377 | 408 | ||
378 | // Diva comment: can't we just update this item??? | 409 | // Diva comment: can't we just update this item??? |
@@ -388,6 +419,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
388 | 419 | ||
389 | if (folder != null & trashFolder != null) | 420 | if (folder != null & trashFolder != null) |
390 | { | 421 | { |
422 | previousParentFolderID = folder.ParentID; | ||
391 | folder.ParentID = trashFolder.ID; | 423 | folder.ParentID = trashFolder.ID; |
392 | invService.MoveFolder(folder); | 424 | invService.MoveFolder(folder); |
393 | client.SendBulkUpdateInventory(folder); | 425 | client.SendBulkUpdateInventory(folder); |
@@ -408,6 +440,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
408 | client.SendAgentAlertMessage("Unable to delete "+ | 440 | client.SendAgentAlertMessage("Unable to delete "+ |
409 | "received inventory" + reason, false); | 441 | "received inventory" + reason, false); |
410 | } | 442 | } |
443 | // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). | ||
444 | else if (previousParentFolderID != null) | ||
445 | { | ||
446 | InventoryFolderBase previousParentFolder | ||
447 | = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); | ||
448 | previousParentFolder = invService.GetFolder(previousParentFolder); | ||
449 | scene.SendInventoryUpdate(client, previousParentFolder, true, true); | ||
450 | |||
451 | scene.SendInventoryUpdate(client, trashFolder, true, true); | ||
452 | } | ||
411 | 453 | ||
412 | ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); | 454 | ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); |
413 | 455 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index 92cf9d1..9c369f6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | |||
@@ -186,7 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
186 | client.FirstName+" "+client.LastName, targetid, | 186 | client.FirstName+" "+client.LastName, targetid, |
187 | (byte)InstantMessageDialog.RequestTeleport, false, | 187 | (byte)InstantMessageDialog.RequestTeleport, false, |
188 | message, sessionID, false, presence.AbsolutePosition, | 188 | message, sessionID, false, presence.AbsolutePosition, |
189 | new Byte[0]); | 189 | new Byte[0], true); |
190 | m.RegionID = client.Scene.RegionInfo.RegionID.Guid; | 190 | m.RegionID = client.Scene.RegionInfo.RegionID.Guid; |
191 | 191 | ||
192 | m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message); | 192 | m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message); |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index c5bb9a5..e355ebf 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -1028,6 +1028,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1028 | Scene initiatingScene) | 1028 | Scene initiatingScene) |
1029 | { | 1029 | { |
1030 | Thread.Sleep(10000); | 1030 | Thread.Sleep(10000); |
1031 | |||
1031 | IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>(); | 1032 | IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>(); |
1032 | if (im != null) | 1033 | if (im != null) |
1033 | { | 1034 | { |
@@ -1040,11 +1041,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1040 | (uint)(int)position.X, | 1041 | (uint)(int)position.X, |
1041 | (uint)(int)position.Y, | 1042 | (uint)(int)position.Y, |
1042 | (uint)(int)position.Z); | 1043 | (uint)(int)position.Z); |
1043 | GridInstantMessage m = new GridInstantMessage(initiatingScene, UUID.Zero, | 1044 | |
1044 | "Region", agent.UUID, | 1045 | GridInstantMessage m |
1045 | (byte)InstantMessageDialog.GodLikeRequestTeleport, false, | 1046 | = new GridInstantMessage( |
1046 | "", gotoLocation, false, new Vector3(127, 0, 0), | 1047 | initiatingScene, |
1047 | new Byte[0]); | 1048 | UUID.Zero, |
1049 | "Region", | ||
1050 | agent.UUID, | ||
1051 | (byte)InstantMessageDialog.GodLikeRequestTeleport, | ||
1052 | false, | ||
1053 | "", | ||
1054 | gotoLocation, | ||
1055 | false, | ||
1056 | new Vector3(127, 0, 0), | ||
1057 | new Byte[0], | ||
1058 | false); | ||
1059 | |||
1048 | im.SendInstantMessage(m, delegate(bool success) | 1060 | im.SendInstantMessage(m, delegate(bool success) |
1049 | { | 1061 | { |
1050 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); | 1062 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 36c84c7..b4811da 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -31,6 +31,7 @@ using System.Reflection; | |||
31 | 31 | ||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Framework.Console; | 33 | using OpenSim.Framework.Console; |
34 | using OpenSim.Region.ClientStack.LindenUDP; | ||
34 | using OpenSim.Region.Framework; | 35 | using OpenSim.Region.Framework; |
35 | using OpenSim.Region.Framework.Interfaces; | 36 | using OpenSim.Region.Framework.Interfaces; |
36 | using OpenSim.Region.Framework.Scenes; | 37 | using OpenSim.Region.Framework.Scenes; |
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 09f6758..6e39e9a 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | |||
@@ -126,6 +126,25 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
126 | m_console.Commands.AddCommand( | 126 | m_console.Commands.AddCommand( |
127 | "Objects", | 127 | "Objects", |
128 | false, | 128 | false, |
129 | "show object pos", | ||
130 | "show object pos <start-coord> to <end-coord>", | ||
131 | "Show details of scene objects within the given area.", | ||
132 | "Each component of the coord is comma separated. There must be no spaces between the commas.\n" | ||
133 | + "If you don't care about the z component you can simply omit it.\n" | ||
134 | + "If you don't care about the x or y components then you can leave them blank (though a comma is still required)\n" | ||
135 | + "If you want to specify the maxmimum value of a component then you can use ~ instead of a number\n" | ||
136 | + "If you want to specify the minimum value of a component then you can use -~ instead of a number\n" | ||
137 | + "e.g.\n" | ||
138 | + "show object pos 20,20,20 to 40,40,40\n" | ||
139 | + "show object pos 20,20 to 40,40\n" | ||
140 | + "show object pos ,20,20 to ,40,40\n" | ||
141 | + "show object pos ,,30 to ,,~\n" | ||
142 | + "show object pos ,,-~ to ,,30", | ||
143 | HandleShowObjectByPos); | ||
144 | |||
145 | m_console.Commands.AddCommand( | ||
146 | "Objects", | ||
147 | false, | ||
129 | "show part uuid", | 148 | "show part uuid", |
130 | "show part uuid <UUID>", | 149 | "show part uuid <UUID>", |
131 | "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); | 150 | "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); |
@@ -138,6 +157,25 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
138 | "Show details of scene object parts with the given name.", | 157 | "Show details of scene object parts with the given name.", |
139 | "If --regex is specified then the name is treatead as a regular expression", | 158 | "If --regex is specified then the name is treatead as a regular expression", |
140 | HandleShowPartByName); | 159 | HandleShowPartByName); |
160 | |||
161 | m_console.Commands.AddCommand( | ||
162 | "Objects", | ||
163 | false, | ||
164 | "show part pos", | ||
165 | "show part pos <start-coord> to <end-coord>", | ||
166 | "Show details of scene object parts within the given area.", | ||
167 | "Each component of the coord is comma separated. There must be no spaces between the commas.\n" | ||
168 | + "If you don't care about the z component you can simply omit it.\n" | ||
169 | + "If you don't care about the x or y components then you can leave them blank (though a comma is still required)\n" | ||
170 | + "If you want to specify the maxmimum value of a component then you can use ~ instead of a number\n" | ||
171 | + "If you want to specify the minimum value of a component then you can use -~ instead of a number\n" | ||
172 | + "e.g.\n" | ||
173 | + "show object pos 20,20,20 to 40,40,40\n" | ||
174 | + "show object pos 20,20 to 40,40\n" | ||
175 | + "show object pos ,20,20 to ,40,40\n" | ||
176 | + "show object pos ,,30 to ,,~\n" | ||
177 | + "show object pos ,,-~ to ,,30", | ||
178 | HandleShowPartByPos); | ||
141 | } | 179 | } |
142 | 180 | ||
143 | public void RemoveRegion(Scene scene) | 181 | public void RemoveRegion(Scene scene) |
@@ -150,6 +188,43 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
150 | // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | 188 | // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); |
151 | } | 189 | } |
152 | 190 | ||
191 | private void OutputSogsToConsole(Predicate<SceneObjectGroup> searchPredicate) | ||
192 | { | ||
193 | List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups().FindAll(searchPredicate); | ||
194 | |||
195 | StringBuilder sb = new StringBuilder(); | ||
196 | |||
197 | foreach (SceneObjectGroup so in sceneObjects) | ||
198 | { | ||
199 | AddSceneObjectReport(sb, so); | ||
200 | sb.Append("\n"); | ||
201 | } | ||
202 | |||
203 | sb.AppendFormat("{0} object(s) found in {1}\n", sceneObjects.Count, m_scene.Name); | ||
204 | |||
205 | m_console.OutputFormat(sb.ToString()); | ||
206 | } | ||
207 | |||
208 | private void OutputSopsToConsole(Predicate<SceneObjectPart> searchPredicate) | ||
209 | { | ||
210 | List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups(); | ||
211 | List<SceneObjectPart> parts = new List<SceneObjectPart>(); | ||
212 | |||
213 | sceneObjects.ForEach(so => parts.AddRange(Array.FindAll<SceneObjectPart>(so.Parts, searchPredicate))); | ||
214 | |||
215 | StringBuilder sb = new StringBuilder(); | ||
216 | |||
217 | foreach (SceneObjectPart part in parts) | ||
218 | { | ||
219 | AddScenePartReport(sb, part); | ||
220 | sb.Append("\n"); | ||
221 | } | ||
222 | |||
223 | sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name); | ||
224 | |||
225 | m_console.OutputFormat(sb.ToString()); | ||
226 | } | ||
227 | |||
153 | private void HandleShowObjectByUuid(string module, string[] cmd) | 228 | private void HandleShowObjectByUuid(string module, string[] cmd) |
154 | { | 229 | { |
155 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 230 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
@@ -200,36 +275,54 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
200 | 275 | ||
201 | string name = mainParams[3]; | 276 | string name = mainParams[3]; |
202 | 277 | ||
203 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); | 278 | Predicate<SceneObjectGroup> searchPredicate; |
204 | Action<SceneObjectGroup> searchAction; | ||
205 | 279 | ||
206 | if (useRegex) | 280 | if (useRegex) |
207 | { | 281 | { |
208 | Regex nameRegex = new Regex(name); | 282 | Regex nameRegex = new Regex(name); |
209 | searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; | 283 | searchPredicate = so => nameRegex.IsMatch(so.Name); |
210 | } | 284 | } |
211 | else | 285 | else |
212 | { | 286 | { |
213 | searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; | 287 | searchPredicate = so => so.Name == name; |
214 | } | 288 | } |
215 | 289 | ||
216 | m_scene.ForEachSOG(searchAction); | 290 | OutputSogsToConsole(searchPredicate); |
291 | } | ||
217 | 292 | ||
218 | if (sceneObjects.Count == 0) | 293 | private void HandleShowObjectByPos(string module, string[] cmdparams) |
294 | { | ||
295 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
296 | return; | ||
297 | |||
298 | if (cmdparams.Length < 5) | ||
219 | { | 299 | { |
220 | m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); | 300 | m_console.OutputFormat("Usage: show object pos <start-coord> to <end-coord>"); |
221 | return; | 301 | return; |
222 | } | 302 | } |
223 | 303 | ||
224 | StringBuilder sb = new StringBuilder(); | 304 | string rawConsoleStartVector = cmdparams[3]; |
305 | Vector3 startVector; | ||
225 | 306 | ||
226 | foreach (SceneObjectGroup so in sceneObjects) | 307 | if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) |
227 | { | 308 | { |
228 | AddSceneObjectReport(sb, so); | 309 | m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector); |
229 | sb.Append("\n"); | 310 | return; |
230 | } | 311 | } |
231 | 312 | ||
232 | m_console.OutputFormat(sb.ToString()); | 313 | string rawConsoleEndVector = cmdparams[5]; |
314 | Vector3 endVector; | ||
315 | |||
316 | if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) | ||
317 | { | ||
318 | m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector); | ||
319 | return; | ||
320 | } | ||
321 | |||
322 | Predicate<SceneObjectGroup> searchPredicate | ||
323 | = so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector); | ||
324 | |||
325 | OutputSogsToConsole(searchPredicate); | ||
233 | } | 326 | } |
234 | 327 | ||
235 | private void HandleShowPartByUuid(string module, string[] cmd) | 328 | private void HandleShowPartByUuid(string module, string[] cmd) |
@@ -264,6 +357,38 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
264 | m_console.OutputFormat(sb.ToString()); | 357 | m_console.OutputFormat(sb.ToString()); |
265 | } | 358 | } |
266 | 359 | ||
360 | private void HandleShowPartByPos(string module, string[] cmdparams) | ||
361 | { | ||
362 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
363 | return; | ||
364 | |||
365 | if (cmdparams.Length < 5) | ||
366 | { | ||
367 | m_console.OutputFormat("Usage: show part pos <start-coord> to <end-coord>"); | ||
368 | return; | ||
369 | } | ||
370 | |||
371 | string rawConsoleStartVector = cmdparams[3]; | ||
372 | Vector3 startVector; | ||
373 | |||
374 | if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) | ||
375 | { | ||
376 | m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector); | ||
377 | return; | ||
378 | } | ||
379 | |||
380 | string rawConsoleEndVector = cmdparams[5]; | ||
381 | Vector3 endVector; | ||
382 | |||
383 | if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) | ||
384 | { | ||
385 | m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector); | ||
386 | return; | ||
387 | } | ||
388 | |||
389 | OutputSopsToConsole(sop => Util.IsInsideBox(sop.AbsolutePosition, startVector, endVector)); | ||
390 | } | ||
391 | |||
267 | private void HandleShowPartByName(string module, string[] cmdparams) | 392 | private void HandleShowPartByName(string module, string[] cmdparams) |
268 | { | 393 | { |
269 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 394 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
@@ -282,37 +407,19 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
282 | 407 | ||
283 | string name = mainParams[3]; | 408 | string name = mainParams[3]; |
284 | 409 | ||
285 | List<SceneObjectPart> parts = new List<SceneObjectPart>(); | 410 | Predicate<SceneObjectPart> searchPredicate; |
286 | |||
287 | Action<SceneObjectGroup> searchAction; | ||
288 | 411 | ||
289 | if (useRegex) | 412 | if (useRegex) |
290 | { | 413 | { |
291 | Regex nameRegex = new Regex(name); | 414 | Regex nameRegex = new Regex(name); |
292 | searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } }); | 415 | searchPredicate = sop => nameRegex.IsMatch(sop.Name); |
293 | } | 416 | } |
294 | else | 417 | else |
295 | { | 418 | { |
296 | searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }); | 419 | searchPredicate = sop => sop.Name == name; |
297 | } | 420 | } |
298 | 421 | ||
299 | m_scene.ForEachSOG(searchAction); | 422 | OutputSopsToConsole(searchPredicate); |
300 | |||
301 | if (parts.Count == 0) | ||
302 | { | ||
303 | m_console.OutputFormat("No parts with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | StringBuilder sb = new StringBuilder(); | ||
308 | |||
309 | foreach (SceneObjectPart part in parts) | ||
310 | { | ||
311 | AddScenePartReport(sb, part); | ||
312 | sb.Append("\n"); | ||
313 | } | ||
314 | |||
315 | m_console.OutputFormat(sb.ToString()); | ||
316 | } | 423 | } |
317 | 424 | ||
318 | private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so) | 425 | private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so) |
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs index 24cd069..f8088c3 100644 --- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs +++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs | |||
@@ -1,4 +1,31 @@ | |||
1 | using System; | 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; | ||
2 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
3 | 30 | ||
4 | using OpenMetaverse; | 31 | using OpenMetaverse; |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 35df85c..30bf744 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -1469,7 +1469,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1469 | return newFolderID; | 1469 | return newFolderID; |
1470 | } | 1470 | } |
1471 | 1471 | ||
1472 | private void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems) | 1472 | public void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems) |
1473 | { | 1473 | { |
1474 | if (folder == null) | 1474 | if (folder == null) |
1475 | return; | 1475 | return; |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index bb3748e..66fc216 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -148,7 +148,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
148 | OnInstantMessage(this, new GridInstantMessage(m_scene, | 148 | OnInstantMessage(this, new GridInstantMessage(m_scene, |
149 | m_uuid, m_firstname + " " + m_lastname, | 149 | m_uuid, m_firstname + " " + m_lastname, |
150 | target, 0, false, message, | 150 | target, 0, false, message, |
151 | UUID.Zero, false, Position, new byte[0])); | 151 | UUID.Zero, false, Position, new byte[0], true)); |
152 | } | 152 | } |
153 | 153 | ||
154 | public void SendAgentOffline(UUID[] agentIDs) | 154 | public void SendAgentOffline(UUID[] agentIDs) |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d8da173..49f0ef7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -4326,7 +4326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4326 | World.RegionInfo.RegionName+" "+ | 4326 | World.RegionInfo.RegionName+" "+ |
4327 | m_host.AbsolutePosition.ToString(), | 4327 | m_host.AbsolutePosition.ToString(), |
4328 | agentItem.ID, true, m_host.AbsolutePosition, | 4328 | agentItem.ID, true, m_host.AbsolutePosition, |
4329 | bucket); | 4329 | bucket, true); |
4330 | 4330 | ||
4331 | ScenePresence sp; | 4331 | ScenePresence sp; |
4332 | 4332 | ||
@@ -6912,16 +6912,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6912 | if (m_TransferModule != null) | 6912 | if (m_TransferModule != null) |
6913 | { | 6913 | { |
6914 | byte[] bucket = new byte[] { (byte)AssetType.Folder }; | 6914 | byte[] bucket = new byte[] { (byte)AssetType.Folder }; |
6915 | 6915 | ||
6916 | Vector3 pos = m_host.AbsolutePosition; | ||
6917 | |||
6916 | GridInstantMessage msg = new GridInstantMessage(World, | 6918 | GridInstantMessage msg = new GridInstantMessage(World, |
6917 | m_host.UUID, m_host.Name + ", an object owned by " + | 6919 | m_host.OwnerID, m_host.Name, destID, |
6918 | resolveName(m_host.OwnerID) + ",", destID, | ||
6919 | (byte)InstantMessageDialog.TaskInventoryOffered, | 6920 | (byte)InstantMessageDialog.TaskInventoryOffered, |
6920 | false, category + "\n" + m_host.Name + " is located at " + | 6921 | false, string.Format("'{0}'"), |
6921 | World.RegionInfo.RegionName + " " + | 6922 | // We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 |
6922 | m_host.AbsolutePosition.ToString(), | 6923 | // false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), |
6923 | folderID, true, m_host.AbsolutePosition, | 6924 | folderID, false, pos, |
6924 | bucket); | 6925 | bucket, false); |
6925 | 6926 | ||
6926 | m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); | 6927 | m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); |
6927 | } | 6928 | } |
diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index c11ea02..625eba4 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs | |||
@@ -61,7 +61,7 @@ namespace OpenSim.Region.UserStatistics | |||
61 | /// <summary> | 61 | /// <summary> |
62 | /// User statistics sessions keyed by agent ID | 62 | /// User statistics sessions keyed by agent ID |
63 | /// </summary> | 63 | /// </summary> |
64 | private Dictionary<UUID, UserSessionID> m_sessions = new Dictionary<UUID, UserSessionID>(); | 64 | private Dictionary<UUID, UserSession> m_sessions = new Dictionary<UUID, UserSession>(); |
65 | 65 | ||
66 | private List<Scene> m_scenes = new List<Scene>(); | 66 | private List<Scene> m_scenes = new List<Scene>(); |
67 | private Dictionary<string, IStatsController> reports = new Dictionary<string, IStatsController>(); | 67 | private Dictionary<string, IStatsController> reports = new Dictionary<string, IStatsController>(); |
@@ -319,14 +319,18 @@ namespace OpenSim.Region.UserStatistics | |||
319 | 319 | ||
320 | private void OnMakeRootAgent(ScenePresence agent) | 320 | private void OnMakeRootAgent(ScenePresence agent) |
321 | { | 321 | { |
322 | // m_log.DebugFormat( | ||
323 | // "[WEB STATS MODULE]: Looking for session {0} for {1} in {2}", | ||
324 | // agent.ControllingClient.SessionId, agent.Name, agent.Scene.Name); | ||
325 | |||
322 | lock (m_sessions) | 326 | lock (m_sessions) |
323 | { | 327 | { |
324 | UserSessionID uid; | 328 | UserSession uid; |
325 | 329 | ||
326 | if (!m_sessions.ContainsKey(agent.UUID)) | 330 | if (!m_sessions.ContainsKey(agent.UUID)) |
327 | { | 331 | { |
328 | UserSessionData usd = UserSessionUtil.newUserSessionData(); | 332 | UserSessionData usd = UserSessionUtil.newUserSessionData(); |
329 | uid = new UserSessionID(); | 333 | uid = new UserSession(); |
330 | uid.name_f = agent.Firstname; | 334 | uid.name_f = agent.Firstname; |
331 | uid.name_l = agent.Lastname; | 335 | uid.name_l = agent.Lastname; |
332 | uid.session_data = usd; | 336 | uid.session_data = usd; |
@@ -411,9 +415,9 @@ namespace OpenSim.Region.UserStatistics | |||
411 | return String.Empty; | 415 | return String.Empty; |
412 | } | 416 | } |
413 | 417 | ||
414 | private UserSessionID ParseViewerStats(string request, UUID agentID) | 418 | private UserSession ParseViewerStats(string request, UUID agentID) |
415 | { | 419 | { |
416 | UserSessionID uid = new UserSessionID(); | 420 | UserSession uid = new UserSession(); |
417 | UserSessionData usd; | 421 | UserSessionData usd; |
418 | OSD message = OSDParser.DeserializeLLSDXml(request); | 422 | OSD message = OSDParser.DeserializeLLSDXml(request); |
419 | OSDMap mmap; | 423 | OSDMap mmap; |
@@ -425,22 +429,25 @@ namespace OpenSim.Region.UserStatistics | |||
425 | if (!m_sessions.ContainsKey(agentID)) | 429 | if (!m_sessions.ContainsKey(agentID)) |
426 | { | 430 | { |
427 | m_log.WarnFormat("[WEB STATS MODULE]: no session for stat disclosure for agent {0}", agentID); | 431 | m_log.WarnFormat("[WEB STATS MODULE]: no session for stat disclosure for agent {0}", agentID); |
428 | return new UserSessionID(); | 432 | return new UserSession(); |
429 | } | 433 | } |
434 | |||
430 | uid = m_sessions[agentID]; | 435 | uid = m_sessions[agentID]; |
436 | |||
437 | // m_log.DebugFormat("[WEB STATS MODULE]: Got session {0} for {1}", uid.session_id, agentID); | ||
431 | } | 438 | } |
432 | else | 439 | else |
433 | { | 440 | { |
434 | // parse through the beginning to locate the session | 441 | // parse through the beginning to locate the session |
435 | if (message.Type != OSDType.Map) | 442 | if (message.Type != OSDType.Map) |
436 | return new UserSessionID(); | 443 | return new UserSession(); |
437 | 444 | ||
438 | mmap = (OSDMap)message; | 445 | mmap = (OSDMap)message; |
439 | { | 446 | { |
440 | UUID sessionID = mmap["session_id"].AsUUID(); | 447 | UUID sessionID = mmap["session_id"].AsUUID(); |
441 | 448 | ||
442 | if (sessionID == UUID.Zero) | 449 | if (sessionID == UUID.Zero) |
443 | return new UserSessionID(); | 450 | return new UserSession(); |
444 | 451 | ||
445 | 452 | ||
446 | // search through each session looking for the owner | 453 | // search through each session looking for the owner |
@@ -459,7 +466,7 @@ namespace OpenSim.Region.UserStatistics | |||
459 | // can't find a session | 466 | // can't find a session |
460 | if (agentID == UUID.Zero) | 467 | if (agentID == UUID.Zero) |
461 | { | 468 | { |
462 | return new UserSessionID(); | 469 | return new UserSession(); |
463 | } | 470 | } |
464 | } | 471 | } |
465 | } | 472 | } |
@@ -468,12 +475,12 @@ namespace OpenSim.Region.UserStatistics | |||
468 | usd = uid.session_data; | 475 | usd = uid.session_data; |
469 | 476 | ||
470 | if (message.Type != OSDType.Map) | 477 | if (message.Type != OSDType.Map) |
471 | return new UserSessionID(); | 478 | return new UserSession(); |
472 | 479 | ||
473 | mmap = (OSDMap)message; | 480 | mmap = (OSDMap)message; |
474 | { | 481 | { |
475 | if (mmap["agent"].Type != OSDType.Map) | 482 | if (mmap["agent"].Type != OSDType.Map) |
476 | return new UserSessionID(); | 483 | return new UserSession(); |
477 | OSDMap agent_map = (OSDMap)mmap["agent"]; | 484 | OSDMap agent_map = (OSDMap)mmap["agent"]; |
478 | usd.agent_id = agentID; | 485 | usd.agent_id = agentID; |
479 | usd.name_f = uid.name_f; | 486 | usd.name_f = uid.name_f; |
@@ -493,17 +500,18 @@ namespace OpenSim.Region.UserStatistics | |||
493 | (float)agent_map["fps"].AsReal()); | 500 | (float)agent_map["fps"].AsReal()); |
494 | 501 | ||
495 | if (mmap["downloads"].Type != OSDType.Map) | 502 | if (mmap["downloads"].Type != OSDType.Map) |
496 | return new UserSessionID(); | 503 | return new UserSession(); |
497 | OSDMap downloads_map = (OSDMap)mmap["downloads"]; | 504 | OSDMap downloads_map = (OSDMap)mmap["downloads"]; |
498 | usd.d_object_kb = (float)downloads_map["object_kbytes"].AsReal(); | 505 | usd.d_object_kb = (float)downloads_map["object_kbytes"].AsReal(); |
499 | usd.d_texture_kb = (float)downloads_map["texture_kbytes"].AsReal(); | 506 | usd.d_texture_kb = (float)downloads_map["texture_kbytes"].AsReal(); |
500 | usd.d_world_kb = (float)downloads_map["workd_kbytes"].AsReal(); | 507 | usd.d_world_kb = (float)downloads_map["workd_kbytes"].AsReal(); |
501 | 508 | ||
509 | // m_log.DebugFormat("[WEB STATS MODULE]: mmap[\"session_id\"] = [{0}]", mmap["session_id"].AsUUID()); | ||
502 | 510 | ||
503 | usd.session_id = mmap["session_id"].AsUUID(); | 511 | usd.session_id = mmap["session_id"].AsUUID(); |
504 | 512 | ||
505 | if (mmap["system"].Type != OSDType.Map) | 513 | if (mmap["system"].Type != OSDType.Map) |
506 | return new UserSessionID(); | 514 | return new UserSession(); |
507 | OSDMap system_map = (OSDMap)mmap["system"]; | 515 | OSDMap system_map = (OSDMap)mmap["system"]; |
508 | 516 | ||
509 | usd.s_cpu = system_map["cpu"].AsString(); | 517 | usd.s_cpu = system_map["cpu"].AsString(); |
@@ -512,13 +520,13 @@ namespace OpenSim.Region.UserStatistics | |||
512 | usd.s_ram = system_map["ram"].AsInteger(); | 520 | usd.s_ram = system_map["ram"].AsInteger(); |
513 | 521 | ||
514 | if (mmap["stats"].Type != OSDType.Map) | 522 | if (mmap["stats"].Type != OSDType.Map) |
515 | return new UserSessionID(); | 523 | return new UserSession(); |
516 | 524 | ||
517 | OSDMap stats_map = (OSDMap)mmap["stats"]; | 525 | OSDMap stats_map = (OSDMap)mmap["stats"]; |
518 | { | 526 | { |
519 | 527 | ||
520 | if (stats_map["failures"].Type != OSDType.Map) | 528 | if (stats_map["failures"].Type != OSDType.Map) |
521 | return new UserSessionID(); | 529 | return new UserSession(); |
522 | OSDMap stats_failures = (OSDMap)stats_map["failures"]; | 530 | OSDMap stats_failures = (OSDMap)stats_map["failures"]; |
523 | usd.f_dropped = stats_failures["dropped"].AsInteger(); | 531 | usd.f_dropped = stats_failures["dropped"].AsInteger(); |
524 | usd.f_failed_resends = stats_failures["failed_resends"].AsInteger(); | 532 | usd.f_failed_resends = stats_failures["failed_resends"].AsInteger(); |
@@ -527,18 +535,18 @@ namespace OpenSim.Region.UserStatistics | |||
527 | usd.f_send_packet = stats_failures["send_packet"].AsInteger(); | 535 | usd.f_send_packet = stats_failures["send_packet"].AsInteger(); |
528 | 536 | ||
529 | if (stats_map["net"].Type != OSDType.Map) | 537 | if (stats_map["net"].Type != OSDType.Map) |
530 | return new UserSessionID(); | 538 | return new UserSession(); |
531 | OSDMap stats_net = (OSDMap)stats_map["net"]; | 539 | OSDMap stats_net = (OSDMap)stats_map["net"]; |
532 | { | 540 | { |
533 | if (stats_net["in"].Type != OSDType.Map) | 541 | if (stats_net["in"].Type != OSDType.Map) |
534 | return new UserSessionID(); | 542 | return new UserSession(); |
535 | 543 | ||
536 | OSDMap net_in = (OSDMap)stats_net["in"]; | 544 | OSDMap net_in = (OSDMap)stats_net["in"]; |
537 | usd.n_in_kb = (float)net_in["kbytes"].AsReal(); | 545 | usd.n_in_kb = (float)net_in["kbytes"].AsReal(); |
538 | usd.n_in_pk = net_in["packets"].AsInteger(); | 546 | usd.n_in_pk = net_in["packets"].AsInteger(); |
539 | 547 | ||
540 | if (stats_net["out"].Type != OSDType.Map) | 548 | if (stats_net["out"].Type != OSDType.Map) |
541 | return new UserSessionID(); | 549 | return new UserSession(); |
542 | OSDMap net_out = (OSDMap)stats_net["out"]; | 550 | OSDMap net_out = (OSDMap)stats_net["out"]; |
543 | 551 | ||
544 | usd.n_out_kb = (float)net_out["kbytes"].AsReal(); | 552 | usd.n_out_kb = (float)net_out["kbytes"].AsReal(); |
@@ -549,11 +557,18 @@ namespace OpenSim.Region.UserStatistics | |||
549 | 557 | ||
550 | uid.session_data = usd; | 558 | uid.session_data = usd; |
551 | m_sessions[agentID] = uid; | 559 | m_sessions[agentID] = uid; |
560 | |||
561 | // m_log.DebugFormat( | ||
562 | // "[WEB STATS MODULE]: Parse data for {0} {1}, session {2}", uid.name_f, uid.name_l, uid.session_id); | ||
563 | |||
552 | return uid; | 564 | return uid; |
553 | } | 565 | } |
554 | 566 | ||
555 | private void UpdateUserStats(UserSessionID uid, SqliteConnection db) | 567 | private void UpdateUserStats(UserSession uid, SqliteConnection db) |
556 | { | 568 | { |
569 | // m_log.DebugFormat( | ||
570 | // "[WEB STATS MODULE]: Updating user stats for {0} {1}, session {2}", uid.name_f, uid.name_l, uid.session_id); | ||
571 | |||
557 | if (uid.session_id == UUID.Zero) | 572 | if (uid.session_id == UUID.Zero) |
558 | return; | 573 | return; |
559 | 574 | ||
@@ -740,7 +755,6 @@ VALUES | |||
740 | s.min_ping = ArrayMin_f(__ping); | 755 | s.min_ping = ArrayMin_f(__ping); |
741 | s.max_ping = ArrayMax_f(__ping); | 756 | s.max_ping = ArrayMax_f(__ping); |
742 | s.mode_ping = ArrayMode_f(__ping); | 757 | s.mode_ping = ArrayMode_f(__ping); |
743 | |||
744 | } | 758 | } |
745 | 759 | ||
746 | #region Statistics | 760 | #region Statistics |
@@ -985,7 +999,7 @@ VALUES | |||
985 | } | 999 | } |
986 | #region structs | 1000 | #region structs |
987 | 1001 | ||
988 | public struct UserSessionID | 1002 | public class UserSession |
989 | { | 1003 | { |
990 | public UUID session_id; | 1004 | public UUID session_id; |
991 | public UUID region_id; | 1005 | public UUID region_id; |