aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorJonathan Freedman2010-11-21 20:01:48 -0800
committerJonathan Freedman2010-11-21 20:01:48 -0800
commitb7f5e8284360f92e0e102b9546076573c57d9397 (patch)
tree132663da8c1882e524241b55a739ef2758ef8958 /OpenSim/Region
parentMerge https://github.com/opensim/opensim into mantis5110 (diff)
parentMerge branch 'master' of /var/git/opensim/ (diff)
downloadopensim-SC_OLD-b7f5e8284360f92e0e102b9546076573c57d9397.zip
opensim-SC_OLD-b7f5e8284360f92e0e102b9546076573c57d9397.tar.gz
opensim-SC_OLD-b7f5e8284360f92e0e102b9546076573c57d9397.tar.bz2
opensim-SC_OLD-b7f5e8284360f92e0e102b9546076573c57d9397.tar.xz
Merge branch 'master-core' into mantis5110
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs143
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs5
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs23
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs34
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs127
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs10
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs9
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs19
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs310
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs25
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs24
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs31
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs203
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs22
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs20
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs21
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityInventory.cs1
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserManagement.cs13
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs20
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs40
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs17
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs56
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs40
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs49
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs104
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs348
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs276
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs56
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs28
38 files changed, 1199 insertions, 967 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index f80cb34..6127c2d 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.IO; 31using System.IO;
32using System.Reflection; 32using System.Reflection;
33using System.Text;
33using System.Timers; 34using System.Timers;
34using log4net; 35using log4net;
35using Nini.Config; 36using Nini.Config;
@@ -264,9 +265,10 @@ namespace OpenSim
264 LoadOar); 265 LoadOar);
265 266
266 m_console.Commands.AddCommand("region", false, "save oar", 267 m_console.Commands.AddCommand("region", false, "save oar",
267 "save oar [-v|version=N] [<OAR path>]", 268 "save oar [-v|--version=N] [-p|--profile=url] [<OAR path>]",
268 "Save a region's data to an OAR archive.", 269 "Save a region's data to an OAR archive.",
269 "-v|version=N generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine 270 "-v|--version=N generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
271 + "-p|--profile=url adds the url of the profile service to the saved user information" + Environment.NewLine
270 + "The OAR path must be a filesystem path." 272 + "The OAR path must be a filesystem path."
271 + " If this is not given then the oar is saved to region.oar in the current directory.", 273 + " If this is not given then the oar is saved to region.oar in the current directory.",
272 SaveOar); 274 SaveOar);
@@ -285,16 +287,15 @@ namespace OpenSim
285 287
286 m_console.Commands.AddCommand("region", false, "show users", 288 m_console.Commands.AddCommand("region", false, "show users",
287 "show users [full]", 289 "show users [full]",
288 "Show user data", HandleShow); 290 "Show user data for users currently on the region",
291 "Without the 'full' option, only users actually on the region are shown."
292 + " With the 'full' option child agents of users in neighbouring regions are also shown.",
293 HandleShow);
289 294
290 m_console.Commands.AddCommand("region", false, "show connections", 295 m_console.Commands.AddCommand("region", false, "show connections",
291 "show connections", 296 "show connections",
292 "Show connection data", HandleShow); 297 "Show connection data", HandleShow);
293 298
294 m_console.Commands.AddCommand("region", false, "show users full",
295 "show users full",
296 String.Empty, HandleShow);
297
298 m_console.Commands.AddCommand("region", false, "show modules", 299 m_console.Commands.AddCommand("region", false, "show modules",
299 "show modules", 300 "show modules",
300 "Show module data", HandleShow); 301 "Show module data", HandleShow);
@@ -304,8 +305,12 @@ namespace OpenSim
304 "Show region data", HandleShow); 305 "Show region data", HandleShow);
305 306
306 m_console.Commands.AddCommand("region", false, "show queues", 307 m_console.Commands.AddCommand("region", false, "show queues",
307 "show queues", 308 "show queues [full]",
308 "Show queue data", HandleShow); 309 "Show queue data for each client",
310 "Without the 'full' option, only users actually on the region are shown."
311 + " With the 'full' option child agents of users in neighbouring regions are also shown.",
312 HandleShow);
313
309 m_console.Commands.AddCommand("region", false, "show ratings", 314 m_console.Commands.AddCommand("region", false, "show ratings",
310 "show ratings", 315 "show ratings",
311 "Show rating data", HandleShow); 316 "Show rating data", HandleShow);
@@ -876,7 +881,7 @@ namespace OpenSim
876 { 881 {
877 agents = m_sceneManager.GetCurrentSceneAvatars(); 882 agents = m_sceneManager.GetCurrentSceneAvatars();
878 } 883 }
879 884
880 MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count)); 885 MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count));
881 886
882 MainConsole.Instance.Output( 887 MainConsole.Instance.Output(
@@ -953,7 +958,7 @@ namespace OpenSim
953 break; 958 break;
954 959
955 case "queues": 960 case "queues":
956 Notice(GetQueuesReport()); 961 Notice(GetQueuesReport(showParams));
957 break; 962 break;
958 963
959 case "ratings": 964 case "ratings":
@@ -983,43 +988,91 @@ namespace OpenSim
983 } 988 }
984 989
985 /// <summary> 990 /// <summary>
986 /// print UDP Queue data for each client 991 /// Generate UDP Queue data report for each client
987 /// </summary> 992 /// </summary>
993 /// <param name="showParams"></param>
988 /// <returns></returns> 994 /// <returns></returns>
989 private string GetQueuesReport() 995 private string GetQueuesReport(string[] showParams)
990 { 996 {
991 string report = String.Empty; 997 bool showChildren = false;
992 998
993 m_sceneManager.ForEachScene(delegate(Scene scene) 999 if (showParams.Length > 1 && showParams[1] == "full")
994 { 1000 showChildren = true;
995 scene.ForEachClient(delegate(IClientAPI client) 1001
996 { 1002 StringBuilder report = new StringBuilder();
997 if (client is IStatsCollector) 1003
998 { 1004 int columnPadding = 2;
999 report = report + client.FirstName + 1005 int maxNameLength = 18;
1000 " " + client.LastName; 1006 int maxRegionNameLength = 14;
1001 1007 int maxTypeLength = 4;
1002 IStatsCollector stats = 1008 int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
1003 (IStatsCollector) client; 1009
1004 1010 report.AppendFormat("{0,-" + maxNameLength + "}{1,-" + columnPadding + "}", "User", "");
1005 report = report + string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}\n", 1011 report.AppendFormat("{0,-" + maxRegionNameLength + "}{1,-" + columnPadding + "}", "Region", "");
1006 "Send", 1012 report.AppendFormat("{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}", "Type", "");
1007 "In", 1013
1008 "Out", 1014 report.AppendFormat(
1009 "Resend", 1015 "{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n",
1010 "Land", 1016 "Packets",
1011 "Wind", 1017 "Packets",
1012 "Cloud", 1018 "Bytes",
1013 "Task", 1019 "Bytes",
1014 "Texture", 1020 "Bytes",
1015 "Asset"); 1021 "Bytes",
1016 report = report + stats.Report() + 1022 "Bytes",
1017 "\n"; 1023 "Bytes",
1018 } 1024 "Bytes",
1019 }); 1025 "Bytes",
1020 }); 1026 "Bytes");
1021 1027
1022 return report; 1028 report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
1029 report.AppendFormat(
1030 "{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}\n",
1031 "Out",
1032 "In",
1033 "Unacked",
1034 "Resend",
1035 "Land",
1036 "Wind",
1037 "Cloud",
1038 "Task",
1039 "Texture",
1040 "Asset",
1041 "State");
1042
1043 m_sceneManager.ForEachScene(
1044 delegate(Scene scene)
1045 {
1046 scene.ForEachClient(
1047 delegate(IClientAPI client)
1048 {
1049 if (client is IStatsCollector)
1050 {
1051 bool isChild = scene.PresenceChildStatus(client.AgentId);
1052 if (isChild && !showChildren)
1053 return;
1054
1055 string name = client.Name;
1056 string regionName = scene.RegionInfo.RegionName;
1057
1058 report.AppendFormat(
1059 "{0,-" + maxNameLength + "}{1,-" + columnPadding + "}",
1060 name.Length > maxNameLength ? name.Substring(0, maxNameLength) : name, "");
1061 report.AppendFormat(
1062 "{0,-" + maxRegionNameLength + "}{1,-" + columnPadding + "}",
1063 regionName.Length > maxRegionNameLength ? regionName.Substring(0, maxRegionNameLength) : regionName, "");
1064 report.AppendFormat(
1065 "{0,-" + maxTypeLength + "}{1,-" + columnPadding + "}",
1066 isChild ? "Cd" : "Rt", "");
1067
1068 IStatsCollector stats = (IStatsCollector)client;
1069
1070 report.AppendLine(stats.Report());
1071 }
1072 });
1073 });
1074
1075 return report.ToString();
1023 } 1076 }
1024 1077
1025 /// <summary> 1078 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 8d85d1a..7851c4d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -6016,8 +6016,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6016 SoundTrigger handlerSoundTrigger = OnSoundTrigger; 6016 SoundTrigger handlerSoundTrigger = OnSoundTrigger;
6017 if (handlerSoundTrigger != null) 6017 if (handlerSoundTrigger != null)
6018 { 6018 {
6019 handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, soundTriggerPacket.SoundData.OwnerID, 6019 // UUIDS are sent as zeroes by the client, substitute agent's id
6020 soundTriggerPacket.SoundData.ObjectID, soundTriggerPacket.SoundData.ParentID, 6020 handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, AgentId,
6021 AgentId, AgentId,
6021 soundTriggerPacket.SoundData.Gain, soundTriggerPacket.SoundData.Position, 6022 soundTriggerPacket.SoundData.Gain, soundTriggerPacket.SoundData.Position,
6022 soundTriggerPacket.SoundData.Handle, 0); 6023 soundTriggerPacket.SoundData.Handle, 0);
6023 6024
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index ca5a7bd..c4db5da 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -246,11 +246,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
246 throw new NotImplementedException(); 246 throw new NotImplementedException();
247 } 247 }
248 248
249 /// <summary>
250 /// Return statistics information about client packet queues.
251 /// </summary>
252 ///
253 /// FIXME: This should really be done in a more sensible manner rather than sending back a formatted string.
254 ///
255 /// <returns></returns>
249 public string GetStats() 256 public string GetStats()
250 { 257 {
251 // TODO: ??? 258 return string.Format(
252 return string.Format("{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7}", 259 "{0,9} {1,9} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}",
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 260 PacketsSent,
261 PacketsReceived,
262 UnackedBytes,
263 m_throttleCategories[(int)ThrottleOutPacketType.Resend].Content,
264 m_throttleCategories[(int)ThrottleOutPacketType.Land].Content,
265 m_throttleCategories[(int)ThrottleOutPacketType.Wind].Content,
266 m_throttleCategories[(int)ThrottleOutPacketType.Cloud].Content,
267 m_throttleCategories[(int)ThrottleOutPacketType.Task].Content,
268 m_throttleCategories[(int)ThrottleOutPacketType.Texture].Content,
269 m_throttleCategories[(int)ThrottleOutPacketType.Asset].Content,
270 m_throttleCategories[(int)ThrottleOutPacketType.State].Content);
254 } 271 }
255 272
256 public void SendPacketStats() 273 public void SendPacketStats()
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 348b8b9..1744fb3 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -273,6 +273,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
273 273
274 if (objatt != null) 274 if (objatt != null)
275 { 275 {
276 // Loading the inventory from XML will have set this, but
277 // there is no way the object could have changed yet,
278 // since scripts aren't running yet. So, clear it here.
279 objatt.HasGroupChanged = false;
276 bool tainted = false; 280 bool tainted = false;
277 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) 281 if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
278 tainted = true; 282 tainted = true;
@@ -470,6 +474,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
470 m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); 474 m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
471 group.DetachToInventoryPrep(); 475 group.DetachToInventoryPrep();
472 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); 476 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
477
478 // If an item contains scripts, it's always changed.
479 // This ensures script state is saved on detach
480 foreach (SceneObjectPart p in group.Parts)
481 if (p.Inventory.ContainsScripts())
482 group.HasGroupChanged = true;
483
473 UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); 484 UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID);
474 m_scene.DeleteSceneObject(group, false); 485 m_scene.DeleteSceneObject(group, false);
475 return; 486 return;
@@ -478,25 +489,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
478 } 489 }
479 } 490 }
480 491
481 public void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos)
482 {
483 // If this is an attachment, then we need to save the modified
484 // object back into the avatar's inventory. First we save the
485 // attachment point information, then we update the relative
486 // positioning (which caused this method to get driven in the
487 // first place. Then we have to mark the object as NOT an
488 // attachment. This is necessary in order to correctly save
489 // and retrieve GroupPosition information for the attachment.
490 // Then we save the asset back into the appropriate inventory
491 // entry. Finally, we restore the object's attachment status.
492 byte attachmentPoint = sog.GetAttachmentPoint();
493 sog.UpdateGroupPosition(pos);
494 sog.RootPart.IsAttachment = false;
495 sog.AbsolutePosition = sog.RootPart.AttachedPos;
496 UpdateKnownItem(client, sog, sog.GetFromItemID(), sog.OwnerID);
497 sog.SetAttachmentPoint(attachmentPoint);
498 }
499
500 /// <summary> 492 /// <summary>
501 /// Update the attachment asset for the new sog details if they have changed. 493 /// Update the attachment asset for the new sog details if they have changed.
502 /// </summary> 494 /// </summary>
@@ -508,7 +500,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
508 /// <param name="grp"></param> 500 /// <param name="grp"></param>
509 /// <param name="itemID"></param> 501 /// <param name="itemID"></param>
510 /// <param name="agentID"></param> 502 /// <param name="agentID"></param>
511 protected void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) 503 public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
512 { 504 {
513 if (grp != null) 505 if (grp != null)
514 { 506 {
@@ -523,7 +515,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
523 grp.UUID, grp.GetAttachmentPoint()); 515 grp.UUID, grp.GetAttachmentPoint());
524 516
525 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 517 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
526
527 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 518 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
528 item = m_scene.InventoryService.GetItem(item); 519 item = m_scene.InventoryService.GetItem(item);
529 520
@@ -617,7 +608,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
617 // In case it is later dropped again, don't let 608 // In case it is later dropped again, don't let
618 // it get cleaned up 609 // it get cleaned up
619 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); 610 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
620 so.HasGroupChanged = false;
621 } 611 }
622 } 612 }
623} 613}
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 2dd444d..0df4585 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -55,6 +55,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
55 private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>(); 55 private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>();
56 private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>(); 56 private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>();
57 57
58 private object m_setAppearanceLock = new object();
59
58 #region RegionModule Members 60 #region RegionModule Members
59 61
60 public void Initialise(Scene scene, IConfigSource config) 62 public void Initialise(Scene scene, IConfigSource config)
@@ -69,6 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
69 { 71 {
70 m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); 72 m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
71 m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); 73 m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
74 // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
72 } 75 }
73 } 76 }
74 77
@@ -117,26 +120,28 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
117 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 120 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
118 if (sp == null) 121 if (sp == null)
119 { 122 {
120 m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}", client.AgentId); 123 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
121 return false; 124 return false;
122 } 125 }
123 126
124 bool cached = true; 127 bool defonly = true; // are we only using default textures
125 128
126 // Process the texture entry 129 // Process the texture entry
127 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) 130 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
128 { 131 {
129 int idx = AvatarAppearance.BAKE_INDICES[i]; 132 int idx = AvatarAppearance.BAKE_INDICES[i];
130 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 133 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
131 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) 134 if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
132 if (! CheckBakedTextureAsset(client,face.TextureID,idx)) 135 continue;
133 { 136
134 sp.Appearance.Texture.FaceTextures[idx] = null; 137 defonly = false; // found a non-default texture reference
135 cached = false; 138
136 } 139 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
140 return false;
137 } 141 }
138 142
139 return cached; 143 // If we only found default textures, then the appearance is not cached
144 return (defonly ? false : true);
140 } 145 }
141 146
142 /// <summary> 147 /// <summary>
@@ -146,44 +151,59 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
146 /// <param name="visualParam"></param> 151 /// <param name="visualParam"></param>
147 public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) 152 public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
148 { 153 {
149// m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance for {0}",client.AgentId);
150
151 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 154 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
152 if (sp == null) 155 if (sp == null)
153 { 156 {
154 m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}",client.AgentId); 157 m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId);
155 return; 158 return;
156 } 159 }
157 160
161 // m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId);
162
158 bool changed = false; 163 bool changed = false;
159 164
160 // Process the texture entry 165 // Process the texture entry transactionally, this doesn't guarantee that Appearance is
161 if (textureEntry != null) 166 // going to be handled correctly but it does serialize the updates to the appearance
167 lock (m_setAppearanceLock)
162 { 168 {
163 changed = sp.Appearance.SetTextureEntries(textureEntry); 169 if (textureEntry != null)
164
165 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
166 { 170 {
167 int idx = AvatarAppearance.BAKE_INDICES[i]; 171 changed = sp.Appearance.SetTextureEntries(textureEntry);
168 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; 172
169 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) 173 // m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId);
170 Util.FireAndForget(delegate(object o) { 174
171 if (! CheckBakedTextureAsset(client,face.TextureID,idx)) 175 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
172 client.SendRebakeAvatarTextures(face.TextureID); 176 {
173 }); 177 int idx = AvatarAppearance.BAKE_INDICES[i];
178 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
179 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
180 Util.FireAndForget(delegate(object o) {
181 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
182 client.SendRebakeAvatarTextures(face.TextureID);
183 });
184 }
185
186 // m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId);
174 } 187 }
175 }
176 188
177 // Process the visual params, this may change height as well 189 // Process the visual params, this may change height as well
178 if (visualParams != null) 190 if (visualParams != null)
179 {
180 if (sp.Appearance.SetVisualParams(visualParams))
181 { 191 {
182 changed = true; 192 if (sp.Appearance.SetVisualParams(visualParams))
183 if (sp.Appearance.AvatarHeight > 0) 193 {
184 sp.SetHeight(sp.Appearance.AvatarHeight); 194 changed = true;
195 if (sp.Appearance.AvatarHeight > 0)
196 sp.SetHeight(sp.Appearance.AvatarHeight);
197 }
185 } 198 }
199
200 // Send the appearance back to the avatar, not clear that this is needed
201 sp.ControllingClient.SendAvatarDataImmediate(sp);
202 // AvatarAppearance avp = sp.Appearance;
203 // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
204
186 } 205 }
206
187 207
188 // If something changed in the appearance then queue an appearance save 208 // If something changed in the appearance then queue an appearance save
189 if (changed) 209 if (changed)
@@ -192,10 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
192 // And always queue up an appearance update to send out 212 // And always queue up an appearance update to send out
193 QueueAppearanceSend(client.AgentId); 213 QueueAppearanceSend(client.AgentId);
194 214
195 // Send the appearance back to the avatar 215 // m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
196 // AvatarAppearance avp = sp.Appearance;
197 // sp.ControllingClient.SendAvatarDataImmediate(sp);
198 // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
199 } 216 }
200 217
201 /// <summary> 218 /// <summary>
@@ -209,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
209 { 226 {
210 if (m_scene.AssetService.Get(textureID.ToString()) == null) 227 if (m_scene.AssetService.Get(textureID.ToString()) == null)
211 { 228 {
212 m_log.WarnFormat("[AVATAR FACTORY MODULE]: Missing baked texture {0} ({1}) for avatar {2}", 229 m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",
213 textureID, idx, client.Name); 230 textureID, idx, client.Name);
214 return false; 231 return false;
215 } 232 }
@@ -220,10 +237,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
220 237
221 public void QueueAppearanceSend(UUID agentid) 238 public void QueueAppearanceSend(UUID agentid)
222 { 239 {
223// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance send for {0}", agentid); 240 // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
224 241
225 // 100 nanoseconds (ticks) we should wait 242 // 10000 ticks per millisecond, 1000 milliseconds per second
226 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 10000000); 243 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
227 lock (m_sendqueue) 244 lock (m_sendqueue)
228 { 245 {
229 m_sendqueue[agentid] = timestamp; 246 m_sendqueue[agentid] = timestamp;
@@ -233,10 +250,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
233 250
234 public void QueueAppearanceSave(UUID agentid) 251 public void QueueAppearanceSave(UUID agentid)
235 { 252 {
236// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance save for {0}", agentid); 253 // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid);
237 254
238 // 100 nanoseconds (ticks) we should wait 255 // 10000 ticks per millisecond, 1000 milliseconds per second
239 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 10000000); 256 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000);
240 lock (m_savequeue) 257 lock (m_savequeue)
241 { 258 {
242 m_savequeue[agentid] = timestamp; 259 m_savequeue[agentid] = timestamp;
@@ -249,15 +266,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
249 ScenePresence sp = m_scene.GetScenePresence(agentid); 266 ScenePresence sp = m_scene.GetScenePresence(agentid);
250 if (sp == null) 267 if (sp == null)
251 { 268 {
252 m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid); 269 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
253 return; 270 return;
254 } 271 }
255 272
256// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Handle appearance send for {0}", agentid); 273 // m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid);
257 274
258 // Send the appearance to everyone in the scene 275 // Send the appearance to everyone in the scene
259 sp.SendAppearanceToAllOtherAgents(); 276 sp.SendAppearanceToAllOtherAgents();
260 sp.ControllingClient.SendAvatarDataImmediate(sp); 277 // sp.ControllingClient.SendAvatarDataImmediate(sp);
261 278
262 // Send the appearance back to the avatar 279 // Send the appearance back to the avatar
263 // AvatarAppearance avp = sp.Appearance; 280 // AvatarAppearance avp = sp.Appearance;
@@ -279,10 +296,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
279 ScenePresence sp = m_scene.GetScenePresence(agentid); 296 ScenePresence sp = m_scene.GetScenePresence(agentid);
280 if (sp == null) 297 if (sp == null)
281 { 298 {
282 m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid); 299 m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
283 return; 300 return;
284 } 301 }
285 302
303 // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
304
286 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); 305 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
287 } 306 }
288 307
@@ -330,11 +349,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
330 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 349 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
331 if (sp == null) 350 if (sp == null)
332 { 351 {
333 m_log.WarnFormat("[AVATAR FACTORY MODULE]: SendWearables unable to find presence for {0}", client.AgentId); 352 m_log.WarnFormat("[AVFACTORY]: SendWearables unable to find presence for {0}", client.AgentId);
334 return; 353 return;
335 } 354 }
336 355
337// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Received request for wearables of {0}", client.AgentId); 356 // m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId);
338 357
339 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); 358 client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
340 } 359 }
@@ -349,11 +368,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
349 ScenePresence sp = m_scene.GetScenePresence(client.AgentId); 368 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
350 if (sp == null) 369 if (sp == null)
351 { 370 {
352 m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing unable to find presence for {0}", client.AgentId); 371 m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
353 return; 372 return;
354 } 373 }
355 374
356// m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing called for {0}", client.AgentId); 375 // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
357 376
358 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); 377 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
359 378
@@ -368,6 +387,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
368 // This could take awhile since it needs to pull inventory 387 // This could take awhile since it needs to pull inventory
369 SetAppearanceAssets(sp.UUID, ref avatAppearance); 388 SetAppearanceAssets(sp.UUID, ref avatAppearance);
370 389
390 // could get fancier with the locks here, but in the spirit of "last write wins"
391 // this should work correctly
371 sp.Appearance = avatAppearance; 392 sp.Appearance = avatAppearance;
372 m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); 393 m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance);
373 } 394 }
@@ -398,7 +419,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
398 else 419 else
399 { 420 {
400 m_log.ErrorFormat( 421 m_log.ErrorFormat(
401 "[AVATAR FACTORY MODULE]: Can't find inventory item {0} for {1}, setting to default", 422 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
402 appearance.Wearables[i][j].ItemID, (WearableType)i); 423 appearance.Wearables[i][j].ItemID, (WearableType)i);
403 424
404 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); 425 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID);
@@ -408,7 +429,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
408 } 429 }
409 else 430 else
410 { 431 {
411 m_log.WarnFormat("[AVATAR FACTORY MODULE]: user {0} has no inventory, appearance isn't going to work", userID); 432 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
412 } 433 }
413 } 434 }
414 } 435 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
index 25322a1..a5fcb49 100644
--- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
@@ -115,10 +115,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
115 // Try to find the avatar wielding the killing object 115 // Try to find the avatar wielding the killing object
116 killingAvatar = deadAvatar.Scene.GetScenePresence(part.OwnerID); 116 killingAvatar = deadAvatar.Scene.GetScenePresence(part.OwnerID);
117 if (killingAvatar == null) 117 if (killingAvatar == null)
118 deadAvatarMessage = String.Format("You impaled yourself on {0} owned by {1}!", part.Name, deadAvatar.Scene.GetUserName(part.OwnerID)); 118 {
119 IUserManagement userManager = deadAvatar.Scene.RequestModuleInterface<IUserManagement>();
120 string userName = "Unkown User";
121 if (userManager != null)
122 userName = userManager.GetUserName(part.OwnerID);
123 deadAvatarMessage = String.Format("You impaled yourself on {0} owned by {1}!", part.Name, userName);
124 }
119 else 125 else
120 { 126 {
121// killingAvatarMessage = String.Format("You fragged {0}!", deadAvatar.Name); 127 // killingAvatarMessage = String.Format("You fragged {0}!", deadAvatar.Name);
122 deadAvatarMessage = String.Format("You got killed by {0}!", killingAvatar.Name); 128 deadAvatarMessage = String.Format("You got killed by {0}!", killingAvatar.Name);
123 } 129 }
124 } 130 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 9ba144d..56aefa5 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -1200,11 +1200,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1200 } 1200 }
1201 1201
1202 m_log.Debug("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); 1202 m_log.Debug("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString());
1203
1204 } 1203 }
1205
1206 } 1204 }
1207 1205
1206 /// <summary>
1207 /// Return the list of regions that are considered to be neighbours to the given scene.
1208 /// </summary>
1209 /// <param name="pScene"></param>
1210 /// <param name="pRegionLocX"></param>
1211 /// <param name="pRegionLocY"></param>
1212 /// <returns></returns>
1208 protected List<GridRegion> RequestNeighbours(Scene pScene, uint pRegionLocX, uint pRegionLocY) 1213 protected List<GridRegion> RequestNeighbours(Scene pScene, uint pRegionLocX, uint pRegionLocY)
1209 { 1214 {
1210 RegionInfo m_regionInfo = pScene.RegionInfo; 1215 RegionInfo m_regionInfo = pScene.RegionInfo;
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 7a175ea..67732ff 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -370,6 +370,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
370 370
371 item = new InventoryItemBase(); 371 item = new InventoryItemBase();
372 item.CreatorId = objectGroup.RootPart.CreatorID.ToString(); 372 item.CreatorId = objectGroup.RootPart.CreatorID.ToString();
373 item.CreatorData = objectGroup.RootPart.CreatorData;
373 item.ID = UUID.Random(); 374 item.ID = UUID.Random();
374 item.InvType = (int)InventoryType.Object; 375 item.InvType = (int)InventoryType.Object;
375 item.Folder = folder.ID; 376 item.Folder = folder.ID;
@@ -569,12 +570,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
569 { 570 {
570 group.RootPart.Flags |= PrimFlags.Phantom; 571 group.RootPart.Flags |= PrimFlags.Phantom;
571 group.RootPart.IsAttachment = true; 572 group.RootPart.IsAttachment = true;
572 }
573 573
574 // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since 574 // If we're rezzing an attachment then don't ask
575 // we'll be doing that later on. Scheduling more than one full update during the attachment 575 // AddNewSceneObject() to update the client since
576 // process causes some clients to fail to display the attachment properly. 576 // we'll be doing that later on. Scheduling more
577 m_Scene.AddNewSceneObject(group, true, false); 577 // than one full update during the attachment
578 // process causes some clients to fail to display
579 // the attachment properly.
580 // Also, don't persist attachments.
581 m_Scene.AddNewSceneObject(group, false, false);
582 }
583 else
584 {
585 m_Scene.AddNewSceneObject(group, true, false);
586 }
578 587
579 // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); 588 // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
580 // if attachment we set it's asset id so object updates can reflect that 589 // if attachment we set it's asset id so object updates can reflect that
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
new file mode 100644
index 0000000..0d94baa
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -0,0 +1,310 @@
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 */
27using System;
28using System.Collections.Generic;
29using System.IO;
30using System.Reflection;
31
32using OpenSim.Framework;
33
34using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces;
38
39using OpenMetaverse;
40using log4net;
41using Nini.Config;
42
43namespace OpenSim.Region.CoreModules.Framework.UserManagement
44{
45 struct UserData
46 {
47 public UUID Id;
48 public string FirstName;
49 public string LastName;
50 public string ProfileURL;
51 }
52
53 public class UserManagementModule : ISharedRegionModule, IUserManagement
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 private List<Scene> m_Scenes = new List<Scene>();
58
59 // The cache
60 Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
61
62 #region ISharedRegionModule
63
64 public void Initialise(IConfigSource config)
65 {
66 //m_Enabled = config.Configs["Modules"].GetBoolean("LibraryModule", m_Enabled);
67 //if (m_Enabled)
68 //{
69 // IConfig libConfig = config.Configs["LibraryService"];
70 // if (libConfig != null)
71 // {
72 // string dllName = libConfig.GetString("LocalServiceModule", string.Empty);
73 // m_log.Debug("[LIBRARY MODULE]: Library service dll is " + dllName);
74 // if (dllName != string.Empty)
75 // {
76 // Object[] args = new Object[] { config };
77 // m_Library = ServerUtils.LoadPlugin<ILibraryService>(dllName, args);
78 // }
79 // }
80 //}
81 }
82
83 public bool IsSharedModule
84 {
85 get { return true; }
86 }
87
88 public string Name
89 {
90 get { return "UserManagement Module"; }
91 }
92
93 public Type ReplaceableInterface
94 {
95 get { return null; }
96 }
97
98 public void AddRegion(Scene scene)
99 {
100 m_Scenes.Add(scene);
101
102 scene.RegisterModuleInterface<IUserManagement>(this);
103 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
104 }
105
106 public void RemoveRegion(Scene scene)
107 {
108 scene.UnregisterModuleInterface<IUserManagement>(this);
109 m_Scenes.Remove(scene);
110 }
111
112 public void RegionLoaded(Scene scene)
113 {
114 }
115
116 public void PostInitialise()
117 {
118 foreach (Scene s in m_Scenes)
119 {
120 // let's sniff all the user names referenced by objects in the scene
121 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
122 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
123 }
124 }
125
126 public void Close()
127 {
128 m_Scenes.Clear();
129 m_UserCache.Clear();
130 }
131
132 #endregion ISharedRegionModule
133
134
135 #region Event Handlers
136
137 void EventManager_OnNewClient(IClientAPI client)
138 {
139 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
140 }
141
142 void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
143 {
144 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
145 {
146 remote_client.SendNameReply(uuid, "Mr", "OpenSim");
147 }
148 else
149 {
150 string[] names = GetUserNames(uuid);
151 if (names.Length == 2)
152 {
153 remote_client.SendNameReply(uuid, names[0], names[1]);
154 }
155
156 }
157 }
158
159 #endregion Event Handlers
160
161 private void CacheCreators(SceneObjectGroup sog)
162 {
163 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification);
164 AddUser(sog.RootPart.CreatorID, sog.RootPart.CreatorData);
165
166 foreach (SceneObjectPart sop in sog.Parts)
167 {
168 AddUser(sop.CreatorID, sop.CreatorData);
169 foreach (TaskInventoryItem item in sop.TaskInventory.Values)
170 AddUser(item.CreatorID, item.CreatorData);
171 }
172 }
173
174
175 private string[] GetUserNames(UUID uuid)
176 {
177 string[] returnstring = new string[2];
178
179 if (m_UserCache.ContainsKey(uuid))
180 {
181 returnstring[0] = m_UserCache[uuid].FirstName;
182 returnstring[1] = m_UserCache[uuid].LastName;
183 return returnstring;
184 }
185
186 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid);
187
188 if (account != null)
189 {
190 returnstring[0] = account.FirstName;
191 returnstring[1] = account.LastName;
192
193 UserData user = new UserData();
194 user.FirstName = account.FirstName;
195 user.LastName = account.LastName;
196
197 lock (m_UserCache)
198 m_UserCache[uuid] = user;
199 }
200 else
201 {
202 returnstring[0] = "Unknown";
203 returnstring[1] = "User";
204 }
205
206 return returnstring;
207 }
208
209 #region IUserManagement
210
211 public string GetUserName(UUID uuid)
212 {
213 string[] names = GetUserNames(uuid);
214 if (names.Length == 2)
215 {
216 string firstname = names[0];
217 string lastname = names[1];
218
219 return firstname + " " + lastname;
220
221 }
222 return "(hippos)";
223 }
224
225 public void AddUser(UUID id, string creatorData)
226 {
227 if (m_UserCache.ContainsKey(id))
228 return;
229
230 UserData user = new UserData();
231 user.Id = id;
232
233 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id);
234
235 if (account != null)
236 {
237 user.FirstName = account.FirstName;
238 user.LastName = account.LastName;
239 // user.ProfileURL = we should initialize this to the default
240 }
241 else
242 {
243 if (creatorData != null && creatorData != string.Empty)
244 {
245 //creatorData = <endpoint>;<name>
246
247 string[] parts = creatorData.Split(';');
248 if (parts.Length >= 1)
249 {
250 user.ProfileURL = parts[0];
251 try
252 {
253 Uri uri = new Uri(parts[0]);
254 user.LastName = "@" + uri.Authority;
255 }
256 catch
257 {
258 m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
259 user.LastName = "@unknown";
260 }
261 }
262 if (parts.Length >= 2)
263 user.FirstName = parts[1].Replace(' ', '.');
264 }
265 else
266 {
267 user.FirstName = "Unknown";
268 user.LastName = "User";
269 }
270 }
271
272 lock (m_UserCache)
273 m_UserCache[id] = user;
274
275 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
276 }
277
278 //public void AddUser(UUID uuid, string userData)
279 //{
280 // if (m_UserCache.ContainsKey(uuid))
281 // return;
282
283 // UserData user = new UserData();
284 // user.Id = uuid;
285
286 // // userData = <profile url>;<name>
287 // string[] parts = userData.Split(';');
288 // if (parts.Length >= 1)
289 // user.ProfileURL = parts[0].Trim();
290 // if (parts.Length >= 2)
291 // {
292 // string[] name = parts[1].Trim().Split(' ');
293 // if (name.Length >= 1)
294 // user.FirstName = name[0];
295 // if (name.Length >= 2)
296 // user.LastName = name[1];
297 // else
298 // user.LastName = "?";
299 // }
300
301 // lock (m_UserCache)
302 // m_UserCache.Add(uuid, user);
303
304 // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
305
306 //}
307
308 #endregion IUserManagement
309 }
310}
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index df23eac..cfa4109 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -8,6 +8,7 @@
8 </Dependencies> 8 </Dependencies>
9 9
10 <Extension path = "/OpenSim/RegionModules"> 10 <Extension path = "/OpenSim/RegionModules">
11 <RegionModule id="UserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.UserManagementModule" />
11 <RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" /> 12 <RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" />
12 <RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" /> 13 <RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" />
13 <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" /> 14 <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" />
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index ab6be50..c7244c8 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -49,6 +49,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
49 49
50 private IInventoryService m_InventoryService; 50 private IInventoryService m_InventoryService;
51 51
52 private Scene m_Scene;
53
54 private IUserManagement m_UserManager;
55 private IUserManagement UserManager
56 {
57 get
58 {
59 if (m_UserManager == null)
60 {
61 m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>();
62 }
63 return m_UserManager;
64 }
65 }
66
52 private bool m_Enabled = false; 67 private bool m_Enabled = false;
53 68
54 public Type ReplaceableInterface 69 public Type ReplaceableInterface
@@ -115,6 +130,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
115 return; 130 return;
116 131
117 scene.RegisterModuleInterface<IInventoryService>(this); 132 scene.RegisterModuleInterface<IInventoryService>(this);
133
134 if (m_Scene == null)
135 m_Scene = scene;
118 } 136 }
119 137
120 public void RemoveRegion(Scene scene) 138 public void RemoveRegion(Scene scene)
@@ -163,7 +181,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
163 181
164 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 182 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
165 { 183 {
166 return m_InventoryService.GetFolderContent(userID, folderID); 184 InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID);
185 if (UserManager != null)
186 foreach (InventoryItemBase item in invCol.Items)
187 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
188
189 return invCol;
167 } 190 }
168 191
169 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) 192 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs
index 17d80c7..9213132 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteInventoryServiceConnector.cs
@@ -47,9 +47,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
47 47
48 private bool m_Enabled = false; 48 private bool m_Enabled = false;
49 private bool m_Initialized = false; 49 private bool m_Initialized = false;
50// private Scene m_Scene; 50 private Scene m_Scene;
51 private InventoryServicesConnector m_RemoteConnector; 51 private InventoryServicesConnector m_RemoteConnector;
52 52
53 private IUserManagement m_UserManager;
54 private IUserManagement UserManager
55 {
56 get
57 {
58 if (m_UserManager == null)
59 {
60 m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>();
61 }
62 return m_UserManager;
63 }
64 }
65
66
53 public Type ReplaceableInterface 67 public Type ReplaceableInterface
54 { 68 {
55 get { return null; } 69 get { return null; }
@@ -116,6 +130,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
116 130
117 scene.RegisterModuleInterface<IInventoryService>(this); 131 scene.RegisterModuleInterface<IInventoryService>(this);
118 m_cache.AddRegion(scene); 132 m_cache.AddRegion(scene);
133
134 if (m_Scene == null)
135 m_Scene = scene;
119 } 136 }
120 137
121 public void RemoveRegion(Scene scene) 138 public void RemoveRegion(Scene scene)
@@ -186,7 +203,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
186 UUID sessionID = GetSessionID(userID); 203 UUID sessionID = GetSessionID(userID);
187 try 204 try
188 { 205 {
189 return m_RemoteConnector.GetFolderContent(userID.ToString(), folderID, sessionID); 206 InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID.ToString(), folderID, sessionID);
207 foreach (InventoryItemBase item in invCol.Items)
208 UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
209 return invCol;
190 } 210 }
191 catch (Exception e) 211 catch (Exception e)
192 { 212 {
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 117b2fd..3238a81 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -56,7 +56,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
56 /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version 56 /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version
57 /// bumps here should be compatible. 57 /// bumps here should be compatible.
58 /// </summary> 58 /// </summary>
59 public static int MAX_MAJOR_VERSION = 0; 59 public static int MAX_MAJOR_VERSION = 1;
60 60
61 protected Scene m_scene; 61 protected Scene m_scene;
62 protected Stream m_loadStream; 62 protected Stream m_loadStream;
@@ -78,6 +78,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
78 /// </summary> 78 /// </summary>
79 private IDictionary<UUID, bool> m_validUserUuids = new Dictionary<UUID, bool>(); 79 private IDictionary<UUID, bool> m_validUserUuids = new Dictionary<UUID, bool>();
80 80
81 private IUserManagement m_UserMan;
82 private IUserManagement UserManager
83 {
84 get
85 {
86 if (m_UserMan == null)
87 {
88 m_UserMan = m_scene.RequestModuleInterface<IUserManagement>();
89 }
90 return m_UserMan;
91 }
92 }
93
81 public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) 94 public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId)
82 { 95 {
83 m_scene = scene; 96 m_scene = scene;
@@ -251,8 +264,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
251 264
252 foreach (SceneObjectPart part in sceneObject.Parts) 265 foreach (SceneObjectPart part in sceneObject.Parts)
253 { 266 {
254 if (!ResolveUserUuid(part.CreatorID)) 267 if (part.CreatorData == null || part.CreatorData == string.Empty)
255 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 268 {
269 if (!ResolveUserUuid(part.CreatorID))
270 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
271 }
272 if (UserManager != null)
273 UserManager.AddUser(part.CreatorID, part.CreatorData);
256 274
257 if (!ResolveUserUuid(part.OwnerID)) 275 if (!ResolveUserUuid(part.OwnerID))
258 part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 276 part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
@@ -276,10 +294,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
276 { 294 {
277 kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 295 kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
278 } 296 }
279 if (!ResolveUserUuid(kvp.Value.CreatorID)) 297 if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
280 { 298 {
281 kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 299 if (!ResolveUserUuid(kvp.Value.CreatorID))
300 kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
282 } 301 }
302 if (UserManager != null)
303 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
283 } 304 }
284 } 305 }
285 } 306 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index 0567a82..b987b5a 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -49,7 +49,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
49 public class ArchiveWriteRequestPreparation 49 public class ArchiveWriteRequestPreparation
50 { 50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 /// <summary>
54 /// The minimum major version of OAR that we can write.
55 /// </summary>
56 public static int MIN_MAJOR_VERSION = 0;
57
58 /// <summary>
59 /// The maximum major version of OAR that we can write.
60 /// </summary>
61 public static int MAX_MAJOR_VERSION = 1;
62
53 protected Scene m_scene; 63 protected Scene m_scene;
54 protected Stream m_saveStream; 64 protected Stream m_saveStream;
55 protected Guid m_requestId; 65 protected Guid m_requestId;
@@ -101,110 +111,137 @@ namespace OpenSim.Region.CoreModules.World.Archiver
101 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> 111 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
102 public void ArchiveRegion(Dictionary<string, object> options) 112 public void ArchiveRegion(Dictionary<string, object> options)
103 { 113 {
104 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); 114 try
105 115 {
106 EntityBase[] entities = m_scene.GetEntities(); 116 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
107 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 117
108 118 EntityBase[] entities = m_scene.GetEntities();
109 /* 119 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
110 foreach (ILandObject lo in m_scene.LandChannel.AllParcels()) 120
121 /*
122 foreach (ILandObject lo in m_scene.LandChannel.AllParcels())
123 {
124 if (name == lo.LandData.Name)
125 {
126 // This is the parcel we want
127 }
128 }
129 */
130
131 // Filter entities so that we only have scene objects.
132 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
133 // end up having to do this
134 foreach (EntityBase entity in entities)
111 { 135 {
112 if (name == lo.LandData.Name) 136 if (entity is SceneObjectGroup)
113 { 137 {
114 // This is the parcel we want 138 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
139
140 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
141 sceneObjects.Add((SceneObjectGroup)entity);
115 } 142 }
116 } 143 }
117 */ 144
118 145 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
119 // Filter entities so that we only have scene objects. 146
120 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods 147 foreach (SceneObjectGroup sceneObject in sceneObjects)
121 // end up having to do this
122 foreach (EntityBase entity in entities)
123 {
124 if (entity is SceneObjectGroup)
125 { 148 {
126 SceneObjectGroup sceneObject = (SceneObjectGroup)entity; 149 assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
127
128 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
129 sceneObjects.Add((SceneObjectGroup)entity);
130 } 150 }
151
152 m_log.DebugFormat(
153 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
154 sceneObjects.Count, assetUuids.Count);
155
156 // Make sure that we also request terrain texture assets
157 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
158
159 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
160 assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
161
162 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
163 assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
164
165 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
166 assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
167
168 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
169 assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
170
171 TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);
172
173 // Asynchronously request all the assets required to perform this archive operation
174 ArchiveWriteRequestExecution awre
175 = new ArchiveWriteRequestExecution(
176 sceneObjects,
177 m_scene.RequestModuleInterface<ITerrainModule>(),
178 m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
179 m_scene,
180 archiveWriter,
181 m_requestId,
182 options);
183
184 m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time.");
185
186 // Write out control file. This has to be done first so that subsequent loaders will see this file first
187 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
188 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
189 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
190
191 new AssetsRequest(
192 new AssetsArchiver(archiveWriter), assetUuids,
193 m_scene.AssetService, awre.ReceivedAllAssets).Execute();
131 } 194 }
132 195 catch (Exception)
133 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
134
135 foreach (SceneObjectGroup sceneObject in sceneObjects)
136 { 196 {
137 assetGatherer.GatherAssetUuids(sceneObject, assetUuids); 197 m_saveStream.Close();
138 } 198 throw;
139 199 }
140 m_log.DebugFormat(
141 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
142 sceneObjects.Count, assetUuids.Count);
143
144 // Make sure that we also request terrain texture assets
145 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
146
147 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
148 assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
149
150 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
151 assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
152
153 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
154 assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
155
156 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
157 assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
158
159 TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);
160
161 // Asynchronously request all the assets required to perform this archive operation
162 ArchiveWriteRequestExecution awre
163 = new ArchiveWriteRequestExecution(
164 sceneObjects,
165 m_scene.RequestModuleInterface<ITerrainModule>(),
166 m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
167 m_scene,
168 archiveWriter,
169 m_requestId,
170 options);
171
172 m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time.");
173
174 // Write out control file. This has to be done first so that subsequent loaders will see this file first
175 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
176 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p2ControlFile(options));
177 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
178
179 new AssetsRequest(
180 new AssetsArchiver(archiveWriter), assetUuids,
181 m_scene.AssetService, awre.ReceivedAllAssets).Execute();
182 } 200 }
183 201
184 /// <summary> 202 /// <summary>
185 /// Create the control file for the most up to date archive 203 /// Create the control file for the most up to date archive
186 /// </summary> 204 /// </summary>
187 /// <returns></returns> 205 /// <returns></returns>
188 public static string Create0p2ControlFile(Dictionary<string, object> options) 206 public static string CreateControlFile(Dictionary<string, object> options)
189 { 207 {
190 int majorVersion = 0, minorVersion = 5; 208 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 0;
191 209
192 if (options.ContainsKey("version")) 210 if (options.ContainsKey("version"))
193 { 211 {
194 minorVersion = 0;
195 string[] parts = options["version"].ToString().Split('.'); 212 string[] parts = options["version"].ToString().Split('.');
196 if (parts.Length >= 1) 213 if (parts.Length >= 1)
197 majorVersion = Int32.Parse(parts[0]); 214 {
198 if (parts.Length >= 2) 215 majorVersion = Int32.Parse(parts[0]);
199 minorVersion = Int32.Parse(parts[1]); 216
217 if (parts.Length >= 2)
218 minorVersion = Int32.Parse(parts[1]);
219 }
200 } 220 }
201 221
202 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion); 222 if (majorVersion < MIN_MAJOR_VERSION || majorVersion > MAX_MAJOR_VERSION)
203// if (majorVersion == 1) 223 {
204// { 224 throw new Exception(
205// m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); 225 string.Format(
206// } 226 "OAR version number for save must be between {0} and {1}",
227 MIN_MAJOR_VERSION, MAX_MAJOR_VERSION));
228 }
229 else if (majorVersion == MAX_MAJOR_VERSION)
230 {
231 // Force 1.0
232 minorVersion = 0;
233 }
234 else if (majorVersion == MIN_MAJOR_VERSION)
235 {
236 // Force 0.4
237 minorVersion = 4;
238 }
207 239
240 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
241 if (majorVersion == 1)
242 {
243 m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
244 }
208 245
209 StringWriter sw = new StringWriter(); 246 StringWriter sw = new StringWriter();
210 XmlTextWriter xtw = new XmlTextWriter(sw); 247 XmlTextWriter xtw = new XmlTextWriter(sw);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index e0ad71e..358d0a7 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
126 126
127 OptionSet ops = new OptionSet(); 127 OptionSet ops = new OptionSet();
128 ops.Add("v|version=", delegate(string v) { options["version"] = v; }); 128 ops.Add("v|version=", delegate(string v) { options["version"] = v; });
129 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
129 130
130 List<string> mainParams = ops.Parse(cmdparams); 131 List<string> mainParams = ops.Parse(cmdparams);
131 132
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 04bdc4f..04b6e3d 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -122,13 +122,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
122 } 122 }
123 123
124 /// <summary> 124 /// <summary>
125 /// Test saving a V0.2 OpenSim Region Archive. 125 /// Test saving an OpenSim Region Archive.
126 /// </summary> 126 /// </summary>
127 [Test] 127 [Test]
128 public void TestSaveOarV0_2() 128 public void TestSaveOar()
129 { 129 {
130 TestHelper.InMethod(); 130 TestHelper.InMethod();
131 //log4net.Config.XmlConfigurator.Configure(); 131// log4net.Config.XmlConfigurator.Configure();
132 132
133 SceneObjectPart part1 = CreateSceneObjectPart1(); 133 SceneObjectPart part1 = CreateSceneObjectPart1();
134 SceneObjectGroup sog1 = new SceneObjectGroup(part1); 134 SceneObjectGroup sog1 = new SceneObjectGroup(part1);
@@ -212,10 +212,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
212 } 212 }
213 213
214 /// <summary> 214 /// <summary>
215 /// Test loading a V0.2 OpenSim Region Archive. 215 /// Test loading an OpenSim Region Archive.
216 /// </summary> 216 /// </summary>
217 [Test] 217 [Test]
218 public void TestLoadOarV0_2() 218 public void TestLoadOar()
219 { 219 {
220 TestHelper.InMethod(); 220 TestHelper.InMethod();
221// log4net.Config.XmlConfigurator.Configure(); 221// log4net.Config.XmlConfigurator.Configure();
@@ -230,7 +230,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
230 // upset load 230 // upset load
231 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 231 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
232 232
233 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.Create0p2ControlFile(new Dictionary<string, Object>())); 233 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>()));
234 234
235 SceneObjectPart part1 = CreateSceneObjectPart1(); 235 SceneObjectPart part1 = CreateSceneObjectPart1();
236 SceneObjectGroup object1 = new SceneObjectGroup(part1); 236 SceneObjectGroup object1 = new SceneObjectGroup(part1);
@@ -317,10 +317,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
317 } 317 }
318 318
319 /// <summary> 319 /// <summary>
320 /// Test loading the region settings of a V0.2 OpenSim Region Archive. 320 /// Test loading the region settings of an OpenSim Region Archive.
321 /// </summary> 321 /// </summary>
322 [Test] 322 [Test]
323 public void TestLoadOarV0_2RegionSettings() 323 public void TestLoadOarRegionSettings()
324 { 324 {
325 TestHelper.InMethod(); 325 TestHelper.InMethod();
326 //log4net.Config.XmlConfigurator.Configure(); 326 //log4net.Config.XmlConfigurator.Configure();
@@ -329,7 +329,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
329 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); 329 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
330 330
331 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 331 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
332 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.Create0p2ControlFile(new Dictionary<string, Object>())); 332 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>()));
333 333
334 RegionSettings rs = new RegionSettings(); 334 RegionSettings rs = new RegionSettings();
335 rs.AgentLimit = 17; 335 rs.AgentLimit = 17;
@@ -409,10 +409,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
409 } 409 }
410 410
411 /// <summary> 411 /// <summary>
412 /// Test merging a V0.2 OpenSim Region Archive into an existing scene 412 /// Test merging an OpenSim Region Archive into an existing scene
413 /// </summary> 413 /// </summary>
414 //[Test] 414 //[Test]
415 public void TestMergeOarV0_2() 415 public void TestMergeOar()
416 { 416 {
417 TestHelper.InMethod(); 417 TestHelper.InMethod();
418 //XmlConfigurator.Configure(); 418 //XmlConfigurator.Configure();
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 6844c60..622fc08 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -771,8 +771,14 @@ namespace OpenSim.Region.CoreModules.World.Estate
771 for (int i = 0; i < uuidarr.Length; i++) 771 for (int i = 0; i < uuidarr.Length; i++)
772 { 772 {
773 // string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]); 773 // string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]);
774 m_scene.GetUserName(uuidarr[i]); 774
775 IUserManagement userManager = m_scene.RequestModuleInterface<IUserManagement>();
776 string userName = "Unkown User";
777 if (userManager != null)
778 userName = userManager.GetUserName(uuidarr[i]);
779
775 // we drop it. It gets cached though... so we're ready for the next request. 780 // we drop it. It gets cached though... so we're ready for the next request.
781 // diva commnent 11/21/2010: uh?!? wft?
776 } 782 }
777 } 783 }
778 #endregion 784 #endregion
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
index c06ccb2..568ba19 100644
--- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs
@@ -189,6 +189,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell
189 189
190 InventoryItemBase item = new InventoryItemBase(); 190 InventoryItemBase item = new InventoryItemBase();
191 item.CreatorId = part.CreatorID.ToString(); 191 item.CreatorId = part.CreatorID.ToString();
192 item.CreatorData = part.CreatorData;
192 193
193 item.ID = UUID.Random(); 194 item.ID = UUID.Random();
194 item.Owner = remoteClient.AgentId; 195 item.Owner = remoteClient.AgentId;
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index abd28c8..8df44fe 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -106,14 +106,20 @@ namespace OpenSim.Region.CoreModules.World.Sound
106 { 106 {
107 SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); 107 SceneObjectPart part = m_scene.GetSceneObjectPart(objectID);
108 if (part == null) 108 if (part == null)
109 return;
110
111 SceneObjectGroup grp = part.ParentGroup;
112
113 if (grp.IsAttachment && grp.GetAttachmentPoint() > 30)
114 { 109 {
115 objectID = ownerID; 110 ScenePresence sp;
116 parentID = ownerID; 111 if (!m_scene.TryGetScenePresence(objectID, out sp))
112 return;
113 }
114 else
115 {
116 SceneObjectGroup grp = part.ParentGroup;
117
118 if (grp.IsAttachment && grp.GetAttachmentPoint() > 30)
119 {
120 objectID = ownerID;
121 parentID = ownerID;
122 }
117 } 123 }
118 124
119 m_scene.ForEachScenePresence(delegate(ScenePresence sp) 125 m_scene.ForEachScenePresence(delegate(ScenePresence sp)
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index 24e481b..b3576c5 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -122,11 +122,20 @@ namespace OpenSim.Region.Framework.Interfaces
122 void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient); 122 void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient);
123 123
124 /// <summary> 124 /// <summary>
125 /// Update the position of an attachment 125 /// Update the user inventory with a changed attachment
126 /// </summary> 126 /// </summary>
127 /// <param name="client"></param> 127 /// <param name="remoteClient">
128 /// <param name="sog"></param> 128 /// A <see cref="IClientAPI"/>
129 /// <param name="pos"></param> 129 /// </param>
130 void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos); 130 /// <param name="grp">
131 /// A <see cref="SceneObjectGroup"/>
132 /// </param>
133 /// <param name="itemID">
134 /// A <see cref="UUID"/>
135 /// </param>
136 /// <param name="agentID">
137 /// A <see cref="UUID"/>
138 /// </param>
139 void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID);
131 } 140 }
132} \ No newline at end of file 141}
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 2e6faa0..64664ab 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -183,6 +183,7 @@ namespace OpenSim.Region.Framework.Interfaces
183 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 183 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
184 bool UpdateInventoryItem(TaskInventoryItem item); 184 bool UpdateInventoryItem(TaskInventoryItem item);
185 bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents); 185 bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents);
186 bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged);
186 187
187 /// <summary> 188 /// <summary>
188 /// Remove an item from this entity's inventory 189 /// Remove an item from this entity's inventory
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
new file mode 100644
index 0000000..1a5cb7e
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -0,0 +1,13 @@
1using System;
2using System.Collections.Generic;
3
4using OpenMetaverse;
5
6namespace OpenSim.Region.Framework.Interfaces
7{
8 public interface IUserManagement
9 {
10 string GetUserName(UUID uuid);
11 void AddUser(UUID uuid, string userData);
12 }
13}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 4cc797b..a29b7f1 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -426,6 +426,7 @@ namespace OpenSim.Region.Framework.Scenes
426 InventoryItemBase itemCopy = new InventoryItemBase(); 426 InventoryItemBase itemCopy = new InventoryItemBase();
427 itemCopy.Owner = recipient; 427 itemCopy.Owner = recipient;
428 itemCopy.CreatorId = item.CreatorId; 428 itemCopy.CreatorId = item.CreatorId;
429 itemCopy.CreatorData = item.CreatorData;
429 itemCopy.ID = UUID.Random(); 430 itemCopy.ID = UUID.Random();
430 itemCopy.AssetID = item.AssetID; 431 itemCopy.AssetID = item.AssetID;
431 itemCopy.Description = item.Description; 432 itemCopy.Description = item.Description;
@@ -699,13 +700,13 @@ namespace OpenSim.Region.Framework.Scenes
699 if (remoteClient.AgentId == oldAgentID) 700 if (remoteClient.AgentId == oldAgentID)
700 { 701 {
701 CreateNewInventoryItem( 702 CreateNewInventoryItem(
702 remoteClient, item.CreatorId, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, 703 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
703 item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch()); 704 item.BasePermissions, item.CurrentPermissions, item.EveryOnePermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
704 } 705 }
705 else 706 else
706 { 707 {
707 CreateNewInventoryItem( 708 CreateNewInventoryItem(
708 remoteClient, item.CreatorId, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, 709 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
709 item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch()); 710 item.NextPermissions, item.NextPermissions, item.EveryOnePermissions & item.NextPermissions, item.NextPermissions, item.GroupPermissions, Util.UnixTimeSinceEpoch());
710 } 711 }
711 } 712 }
@@ -755,11 +756,11 @@ namespace OpenSim.Region.Framework.Scenes
755 /// <param name="asset"></param> 756 /// <param name="asset"></param>
756 /// <param name="invType"></param> 757 /// <param name="invType"></param>
757 /// <param name="nextOwnerMask"></param> 758 /// <param name="nextOwnerMask"></param>
758 private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, UUID folderID, string name, uint flags, uint callbackID, 759 private void CreateNewInventoryItem(IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID,
759 AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate) 760 AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate)
760 { 761 {
761 CreateNewInventoryItem( 762 CreateNewInventoryItem(
762 remoteClient, creatorID, folderID, name, flags, callbackID, asset, invType, 763 remoteClient, creatorID, creatorData, folderID, name, flags, callbackID, asset, invType,
763 (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate); 764 (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate);
764 } 765 }
765 766
@@ -774,12 +775,13 @@ namespace OpenSim.Region.Framework.Scenes
774 /// <param name="nextOwnerMask"></param> 775 /// <param name="nextOwnerMask"></param>
775 /// <param name="creationDate"></param> 776 /// <param name="creationDate"></param>
776 private void CreateNewInventoryItem( 777 private void CreateNewInventoryItem(
777 IClientAPI remoteClient, string creatorID, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType, 778 IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, uint flags, uint callbackID, AssetBase asset, sbyte invType,
778 uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate) 779 uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate)
779 { 780 {
780 InventoryItemBase item = new InventoryItemBase(); 781 InventoryItemBase item = new InventoryItemBase();
781 item.Owner = remoteClient.AgentId; 782 item.Owner = remoteClient.AgentId;
782 item.CreatorId = creatorID; 783 item.CreatorId = creatorID;
784 item.CreatorData = creatorData;
783 item.ID = UUID.Random(); 785 item.ID = UUID.Random();
784 item.AssetID = asset.FullID; 786 item.AssetID = asset.FullID;
785 item.Description = asset.Description; 787 item.Description = asset.Description;
@@ -859,7 +861,7 @@ namespace OpenSim.Region.Framework.Scenes
859 AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId); 861 AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId);
860 AssetService.Store(asset); 862 AssetService.Store(asset);
861 863
862 CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate); 864 CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
863 } 865 }
864 else 866 else
865 { 867 {
@@ -901,7 +903,7 @@ namespace OpenSim.Region.Framework.Scenes
901 asset.Description = description; 903 asset.Description = description;
902 904
903 CreateNewInventoryItem( 905 CreateNewInventoryItem(
904 remoteClient, remoteClient.AgentId.ToString(), folderID, name, 0, callbackID, asset, invType, 906 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType,
905 (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, 907 (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All,
906 (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch()); 908 (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch());
907 } 909 }
@@ -1025,6 +1027,7 @@ namespace OpenSim.Region.Framework.Scenes
1025 1027
1026 agentItem.ID = UUID.Random(); 1028 agentItem.ID = UUID.Random();
1027 agentItem.CreatorId = taskItem.CreatorID.ToString(); 1029 agentItem.CreatorId = taskItem.CreatorID.ToString();
1030 agentItem.CreatorData = taskItem.CreatorData;
1028 agentItem.Owner = destAgent; 1031 agentItem.Owner = destAgent;
1029 agentItem.AssetID = taskItem.AssetID; 1032 agentItem.AssetID = taskItem.AssetID;
1030 agentItem.Description = taskItem.Description; 1033 agentItem.Description = taskItem.Description;
@@ -1226,6 +1229,7 @@ namespace OpenSim.Region.Framework.Scenes
1226 1229
1227 destTaskItem.ItemID = UUID.Random(); 1230 destTaskItem.ItemID = UUID.Random();
1228 destTaskItem.CreatorID = srcTaskItem.CreatorID; 1231 destTaskItem.CreatorID = srcTaskItem.CreatorID;
1232 destTaskItem.CreatorData = srcTaskItem.CreatorData;
1229 destTaskItem.AssetID = srcTaskItem.AssetID; 1233 destTaskItem.AssetID = srcTaskItem.AssetID;
1230 destTaskItem.GroupID = destPart.GroupID; 1234 destTaskItem.GroupID = destPart.GroupID;
1231 destTaskItem.OwnerID = destPart.OwnerID; 1235 destTaskItem.OwnerID = destPart.OwnerID;
@@ -1638,6 +1642,7 @@ namespace OpenSim.Region.Framework.Scenes
1638 1642
1639 destTaskItem.ItemID = UUID.Random(); 1643 destTaskItem.ItemID = UUID.Random();
1640 destTaskItem.CreatorID = srcTaskItem.CreatorID; 1644 destTaskItem.CreatorID = srcTaskItem.CreatorID;
1645 destTaskItem.CreatorData = srcTaskItem.CreatorData;
1641 destTaskItem.AssetID = srcTaskItem.AssetID; 1646 destTaskItem.AssetID = srcTaskItem.AssetID;
1642 destTaskItem.GroupID = destPart.GroupID; 1647 destTaskItem.GroupID = destPart.GroupID;
1643 destTaskItem.OwnerID = destPart.OwnerID; 1648 destTaskItem.OwnerID = destPart.OwnerID;
@@ -1844,6 +1849,7 @@ namespace OpenSim.Region.Framework.Scenes
1844 1849
1845 InventoryItemBase item = new InventoryItemBase(); 1850 InventoryItemBase item = new InventoryItemBase();
1846 item.CreatorId = grp.RootPart.CreatorID.ToString(); 1851 item.CreatorId = grp.RootPart.CreatorID.ToString();
1852 item.CreatorData = grp.RootPart.CreatorData;
1847 item.Owner = remoteClient.AgentId; 1853 item.Owner = remoteClient.AgentId;
1848 item.ID = UUID.Random(); 1854 item.ID = UUID.Random();
1849 item.AssetID = asset.FullID; 1855 item.AssetID = asset.FullID;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 21c36d3..ab567fb 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -462,22 +462,6 @@ namespace OpenSim.Region.Framework.Scenes
462 ); 462 );
463 } 463 }
464 464
465 public void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
466 {
467 if (LibraryService != null && (LibraryService.LibraryRootFolder.Owner == uuid))
468 {
469 remote_client.SendNameReply(uuid, "Mr", "OpenSim");
470 }
471 else
472 {
473 string[] names = GetUserNames(uuid);
474 if (names.Length == 2)
475 {
476 remote_client.SendNameReply(uuid, names[0], names[1]);
477 }
478
479 }
480 }
481 465
482 /// <summary> 466 /// <summary>
483 /// Handle a fetch inventory request from the client 467 /// Handle a fetch inventory request from the client
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 3eb4f3e..55fca9b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -185,6 +185,8 @@ namespace OpenSim.Region.Framework.Scenes
185 private Timer m_mapGenerationTimer = new Timer(); 185 private Timer m_mapGenerationTimer = new Timer();
186 private bool m_generateMaptiles; 186 private bool m_generateMaptiles;
187 187
188 private Dictionary<UUID, string[]> m_UserNamesCache = new Dictionary<UUID, string[]>();
189
188 #endregion Fields 190 #endregion Fields
189 191
190 #region Properties 192 #region Properties
@@ -792,36 +794,6 @@ namespace OpenSim.Region.Framework.Scenes
792 return m_simulatorVersion; 794 return m_simulatorVersion;
793 } 795 }
794 796
795 public string[] GetUserNames(UUID uuid)
796 {
797 string[] returnstring = new string[0];
798
799 UserAccount account = UserAccountService.GetUserAccount(RegionInfo.ScopeID, uuid);
800
801 if (account != null)
802 {
803 returnstring = new string[2];
804 returnstring[0] = account.FirstName;
805 returnstring[1] = account.LastName;
806 }
807
808 return returnstring;
809 }
810
811 public string GetUserName(UUID uuid)
812 {
813 string[] names = GetUserNames(uuid);
814 if (names.Length == 2)
815 {
816 string firstname = names[0];
817 string lastname = names[1];
818
819 return firstname + " " + lastname;
820
821 }
822 return "(hippos)";
823 }
824
825 /// <summary> 797 /// <summary>
826 /// Another region is up. 798 /// Another region is up.
827 /// 799 ///
@@ -2808,7 +2780,7 @@ namespace OpenSim.Region.Framework.Scenes
2808 2780
2809 public virtual void SubscribeToClientGridEvents(IClientAPI client) 2781 public virtual void SubscribeToClientGridEvents(IClientAPI client)
2810 { 2782 {
2811 client.OnNameFromUUIDRequest += HandleUUIDNameRequest; 2783 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
2812 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; 2784 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
2813 client.OnAvatarPickerRequest += ProcessAvatarPickerRequest; 2785 client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
2814 client.OnSetStartLocationRequest += SetHomeRezPoint; 2786 client.OnSetStartLocationRequest += SetHomeRezPoint;
@@ -2935,7 +2907,7 @@ namespace OpenSim.Region.Framework.Scenes
2935 2907
2936 public virtual void UnSubscribeToClientGridEvents(IClientAPI client) 2908 public virtual void UnSubscribeToClientGridEvents(IClientAPI client)
2937 { 2909 {
2938 client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; 2910 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
2939 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; 2911 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
2940 client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest; 2912 client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest;
2941 client.OnSetStartLocationRequest -= SetHomeRezPoint; 2913 client.OnSetStartLocationRequest -= SetHomeRezPoint;
@@ -3152,7 +3124,6 @@ namespace OpenSim.Region.Framework.Scenes
3152 List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles); 3124 List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles);
3153 regions.Remove(RegionInfo.RegionHandle); 3125 regions.Remove(RegionInfo.RegionHandle);
3154 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3126 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions);
3155
3156 } 3127 }
3157 m_eventManager.TriggerClientClosed(agentID, this); 3128 m_eventManager.TriggerClientClosed(agentID, this);
3158 } 3129 }
@@ -3164,6 +3135,9 @@ namespace OpenSim.Region.Framework.Scenes
3164 3135
3165 m_eventManager.TriggerOnRemovePresence(agentID); 3136 m_eventManager.TriggerOnRemovePresence(agentID);
3166 3137
3138 if (avatar != null && (!avatar.IsChildAgent))
3139 avatar.SaveChangedAttachments();
3140
3167 ForEachClient( 3141 ForEachClient(
3168 delegate(IClientAPI client) 3142 delegate(IClientAPI client)
3169 { 3143 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 24d7334..032c859 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -259,7 +259,7 @@ namespace OpenSim.Region.Framework.Scenes
259 protected internal bool AddRestoredSceneObject( 259 protected internal bool AddRestoredSceneObject(
260 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) 260 SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
261 { 261 {
262 if (!alreadyPersisted) 262 if (attachToBackup && (!alreadyPersisted))
263 { 263 {
264 sceneObject.ForceInventoryPersistence(); 264 sceneObject.ForceInventoryPersistence();
265 sceneObject.HasGroupChanged = true; 265 sceneObject.HasGroupChanged = true;
@@ -282,8 +282,10 @@ namespace OpenSim.Region.Framework.Scenes
282 /// </returns> 282 /// </returns>
283 protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) 283 protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
284 { 284 {
285 // Ensure that we persist this new scene object 285 // Ensure that we persist this new scene object if it's not an
286 sceneObject.HasGroupChanged = true; 286 // attachment
287 if (attachToBackup)
288 sceneObject.HasGroupChanged = true;
287 289
288 return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); 290 return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
289 } 291 }
@@ -1279,8 +1281,13 @@ namespace OpenSim.Region.Framework.Scenes
1279 { 1281 {
1280 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) 1282 if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0))
1281 { 1283 {
1282 if (m_parentScene.AttachmentsModule != null) 1284 // Set the new attachment point data in the object
1283 m_parentScene.AttachmentsModule.UpdateAttachmentPosition(remoteClient, group, pos); 1285 byte attachmentPoint = group.GetAttachmentPoint();
1286 group.UpdateGroupPosition(pos);
1287 group.RootPart.IsAttachment = false;
1288 group.AbsolutePosition = group.RootPart.AttachedPos;
1289 group.SetAttachmentPoint(attachmentPoint);
1290 group.HasGroupChanged = true;
1284 } 1291 }
1285 else 1292 else
1286 { 1293 {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 5f00f84..c2810b2 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -491,13 +491,15 @@ namespace OpenSim.Region.Framework.Scenes
491 XmlNodeList nodes = doc.GetElementsByTagName("SavedScriptState"); 491 XmlNodeList nodes = doc.GetElementsByTagName("SavedScriptState");
492 if (nodes.Count > 0) 492 if (nodes.Count > 0)
493 { 493 {
494 m_savedScriptState = new Dictionary<UUID, string>(); 494 if (m_savedScriptState == null)
495 m_savedScriptState = new Dictionary<UUID, string>();
495 foreach (XmlNode node in nodes) 496 foreach (XmlNode node in nodes)
496 { 497 {
497 if (node.Attributes["UUID"] != null) 498 if (node.Attributes["UUID"] != null)
498 { 499 {
499 UUID itemid = new UUID(node.Attributes["UUID"].Value); 500 UUID itemid = new UUID(node.Attributes["UUID"].Value);
500 m_savedScriptState.Add(itemid, node.InnerXml); 501 if (itemid != UUID.Zero)
502 m_savedScriptState[itemid] = node.InnerXml;
501 } 503 }
502 } 504 }
503 } 505 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index f164201..2155e26 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -435,6 +435,7 @@ namespace OpenSim.Region.Framework.Scenes
435 private DateTime m_expires; 435 private DateTime m_expires;
436 private DateTime m_rezzed; 436 private DateTime m_rezzed;
437 private bool m_createSelected = false; 437 private bool m_createSelected = false;
438 private string m_creatorData = string.Empty;
438 439
439 public UUID CreatorID 440 public UUID CreatorID
440 { 441 {
@@ -448,6 +449,61 @@ namespace OpenSim.Region.Framework.Scenes
448 } 449 }
449 } 450 }
450 451
452 public string CreatorData // = <profile url>;<name>
453 {
454 get { return m_creatorData; }
455 set { m_creatorData = value; }
456 }
457
458 /// <summary>
459 /// Used by the DB layer to retrieve / store the entire user identification.
460 /// The identification can either be a simple UUID or a string of the form
461 /// uuid[;profile_url[;name]]
462 /// </summary>
463 public string CreatorIdentification
464 {
465 get
466 {
467 if (m_creatorData != null && m_creatorData != string.Empty)
468 return _creatorID.ToString() + ';' + m_creatorData;
469 else
470 return _creatorID.ToString();
471 }
472 set
473 {
474 if ((value == null) || (value != null && value == string.Empty))
475 {
476 m_creatorData = string.Empty;
477 return;
478 }
479
480 if (!value.Contains(";")) // plain UUID
481 {
482 UUID uuid = UUID.Zero;
483 UUID.TryParse(value, out uuid);
484 _creatorID = uuid;
485 }
486 else // <uuid>[;<endpoint>[;name]]
487 {
488 string name = "Unknown User";
489 string[] parts = value.Split(';');
490 if (parts.Length >= 1)
491 {
492 UUID uuid = UUID.Zero;
493 UUID.TryParse(parts[0], out uuid);
494 _creatorID = uuid;
495 }
496 if (parts.Length >= 2)
497 m_creatorData = parts[1];
498 if (parts.Length >= 3)
499 name = parts[2];
500
501 m_creatorData += ';' + name;
502
503 }
504 }
505 }
506
451 /// <summary> 507 /// <summary>
452 /// A relic from when we we thought that prims contained folder objects. In 508 /// A relic from when we we thought that prims contained folder objects. In
453 /// reality, prim == folder 509 /// reality, prim == folder
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 0c5e62d..6a204c3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -127,8 +127,6 @@ namespace OpenSim.Region.Framework.Scenes
127 if (0 == m_items.Count) 127 if (0 == m_items.Count)
128 return; 128 return;
129 129
130 HasInventoryChanged = true;
131 m_part.ParentGroup.HasGroupChanged = true;
132 IList<TaskInventoryItem> items = GetInventoryItems(); 130 IList<TaskInventoryItem> items = GetInventoryItems();
133 m_items.Clear(); 131 m_items.Clear();
134 132
@@ -144,17 +142,6 @@ namespace OpenSim.Region.Framework.Scenes
144 { 142 {
145 lock (Items) 143 lock (Items)
146 { 144 {
147 if (Items.Count == 0)
148 {
149 return;
150 }
151
152 HasInventoryChanged = true;
153 if (m_part.ParentGroup != null)
154 {
155 m_part.ParentGroup.HasGroupChanged = true;
156 }
157
158 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 145 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
159 Items.Clear(); 146 Items.Clear();
160 147
@@ -208,8 +195,15 @@ namespace OpenSim.Region.Framework.Scenes
208 } 195 }
209 } 196 }
210 197
211 HasInventoryChanged = true; 198 // Don't let this set the HasGroupChanged flag for attachments
212 m_part.ParentGroup.HasGroupChanged = true; 199 // as this happens during rez and we don't want a new asset
200 // for each attachment each time
201 if (!m_part.ParentGroup.RootPart.IsAttachment)
202 {
203 HasInventoryChanged = true;
204 m_part.ParentGroup.HasGroupChanged = true;
205 }
206
213 List<TaskInventoryItem> items = GetInventoryItems(); 207 List<TaskInventoryItem> items = GetInventoryItems();
214 foreach (TaskInventoryItem item in items) 208 foreach (TaskInventoryItem item in items)
215 { 209 {
@@ -674,13 +668,19 @@ namespace OpenSim.Region.Framework.Scenes
674 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 668 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
675 public bool UpdateInventoryItem(TaskInventoryItem item) 669 public bool UpdateInventoryItem(TaskInventoryItem item)
676 { 670 {
677 return UpdateInventoryItem(item, true); 671 return UpdateInventoryItem(item, true, true);
678 } 672 }
679 673
680 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) 674 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents)
681 { 675 {
676 return UpdateInventoryItem(item, fireScriptEvents, true);
677 }
678
679 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
680 {
682 TaskInventoryItem it = GetInventoryItem(item.ItemID); 681 TaskInventoryItem it = GetInventoryItem(item.ItemID);
683 if (it != null) 682 if (it != null)
683
684 { 684 {
685 item.ParentID = m_part.UUID; 685 item.ParentID = m_part.UUID;
686 item.ParentPartID = m_part.UUID; 686 item.ParentPartID = m_part.UUID;
@@ -702,9 +702,11 @@ namespace OpenSim.Region.Framework.Scenes
702 702
703 if (fireScriptEvents) 703 if (fireScriptEvents)
704 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 704 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
705 705 if (considerChanged)
706 HasInventoryChanged = true; 706 {
707 m_part.ParentGroup.HasGroupChanged = true; 707 HasInventoryChanged = true;
708 m_part.ParentGroup.HasGroupChanged = true;
709 }
708 return true; 710 return true;
709 } 711 }
710 else 712 else
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 2e58a46..4526a59 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -3746,5 +3746,28 @@ namespace OpenSim.Region.Framework.Scenes
3746 m_reprioritization_called = false; 3746 m_reprioritization_called = false;
3747 } 3747 }
3748 } 3748 }
3749
3750 public void SaveChangedAttachments()
3751 {
3752 // Need to copy this list because DetachToInventoryPrep mods it
3753 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(Attachments.ToArray());
3754
3755 IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule;
3756 if (attachmentsModule != null)
3757 {
3758 foreach (SceneObjectGroup grp in attachments)
3759 {
3760 if (grp.HasGroupChanged) // Resizer scripts?
3761 {
3762 grp.RootPart.IsAttachment = false;
3763 grp.AbsolutePosition = grp.RootPart.AttachedPos;
3764// grp.DetachToInventoryPrep();
3765 attachmentsModule.UpdateKnownItem(ControllingClient,
3766 grp, grp.GetFromItemID(), grp.OwnerID);
3767 grp.RootPart.IsAttachment = true;
3768 }
3769 }
3770 }
3771 }
3749 } 3772 }
3750} 3773}
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 7f37878..9cf5a39 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -34,6 +34,7 @@ using System.Xml;
34using log4net; 34using log4net;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
38 39
39namespace OpenSim.Region.Framework.Scenes.Serialization 40namespace OpenSim.Region.Framework.Scenes.Serialization
@@ -46,6 +47,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
46 public class SceneObjectSerializer 47 public class SceneObjectSerializer
47 { 48 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private static IUserManagement m_UserManagement;
49 52
50 /// <summary> 53 /// <summary>
51 /// Deserialize a scene object from the original xml format 54 /// Deserialize a scene object from the original xml format
@@ -270,6 +273,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
270 #region SOPXmlProcessors initialization 273 #region SOPXmlProcessors initialization
271 m_SOPXmlProcessors.Add("AllowedDrop", ProcessAllowedDrop); 274 m_SOPXmlProcessors.Add("AllowedDrop", ProcessAllowedDrop);
272 m_SOPXmlProcessors.Add("CreatorID", ProcessCreatorID); 275 m_SOPXmlProcessors.Add("CreatorID", ProcessCreatorID);
276 m_SOPXmlProcessors.Add("CreatorData", ProcessCreatorData);
273 m_SOPXmlProcessors.Add("FolderID", ProcessFolderID); 277 m_SOPXmlProcessors.Add("FolderID", ProcessFolderID);
274 m_SOPXmlProcessors.Add("InventorySerial", ProcessInventorySerial); 278 m_SOPXmlProcessors.Add("InventorySerial", ProcessInventorySerial);
275 m_SOPXmlProcessors.Add("TaskInventory", ProcessTaskInventory); 279 m_SOPXmlProcessors.Add("TaskInventory", ProcessTaskInventory);
@@ -327,6 +331,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
327 m_TaskInventoryXmlProcessors.Add("BasePermissions", ProcessTIBasePermissions); 331 m_TaskInventoryXmlProcessors.Add("BasePermissions", ProcessTIBasePermissions);
328 m_TaskInventoryXmlProcessors.Add("CreationDate", ProcessTICreationDate); 332 m_TaskInventoryXmlProcessors.Add("CreationDate", ProcessTICreationDate);
329 m_TaskInventoryXmlProcessors.Add("CreatorID", ProcessTICreatorID); 333 m_TaskInventoryXmlProcessors.Add("CreatorID", ProcessTICreatorID);
334 m_TaskInventoryXmlProcessors.Add("CreatorData", ProcessTICreatorData);
330 m_TaskInventoryXmlProcessors.Add("Description", ProcessTIDescription); 335 m_TaskInventoryXmlProcessors.Add("Description", ProcessTIDescription);
331 m_TaskInventoryXmlProcessors.Add("EveryonePermissions", ProcessTIEveryonePermissions); 336 m_TaskInventoryXmlProcessors.Add("EveryonePermissions", ProcessTIEveryonePermissions);
332 m_TaskInventoryXmlProcessors.Add("Flags", ProcessTIFlags); 337 m_TaskInventoryXmlProcessors.Add("Flags", ProcessTIFlags);
@@ -412,6 +417,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
412 obj.CreatorID = ReadUUID(reader, "CreatorID"); 417 obj.CreatorID = ReadUUID(reader, "CreatorID");
413 } 418 }
414 419
420 private static void ProcessCreatorData(SceneObjectPart obj, XmlTextReader reader)
421 {
422 obj.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty);
423 }
424
415 private static void ProcessFolderID(SceneObjectPart obj, XmlTextReader reader) 425 private static void ProcessFolderID(SceneObjectPart obj, XmlTextReader reader)
416 { 426 {
417 obj.FolderID = ReadUUID(reader, "FolderID"); 427 obj.FolderID = ReadUUID(reader, "FolderID");
@@ -698,6 +708,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
698 item.CreatorID = ReadUUID(reader, "CreatorID"); 708 item.CreatorID = ReadUUID(reader, "CreatorID");
699 } 709 }
700 710
711 private static void ProcessTICreatorData(TaskInventoryItem item, XmlTextReader reader)
712 {
713 item.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty);
714 }
715
701 private static void ProcessTIDescription(TaskInventoryItem item, XmlTextReader reader) 716 private static void ProcessTIDescription(TaskInventoryItem item, XmlTextReader reader)
702 { 717 {
703 item.Description = reader.ReadElementContentAsString("Description", String.Empty); 718 item.Description = reader.ReadElementContentAsString("Description", String.Empty);
@@ -735,7 +750,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
735 750
736 private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader) 751 private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader)
737 { 752 {
738 item.OldItemID = ReadUUID(reader, "OldItemID"); 753 ReadUUID(reader, "OldItemID");
754 // On deserialization, the old item id MUST BE UUID.Zero!!!!!
755 // Setting this to the saved value will BREAK script persistence!
756 // item.OldItemID = ReadUUID(reader, "OldItemID");
739 } 757 }
740 758
741 private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader) 759 private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader)
@@ -1074,11 +1092,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1074 writer.WriteAttributeString("xmlns:xsd", "http://www.w3.org/2001/XMLSchema"); 1092 writer.WriteAttributeString("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
1075 1093
1076 writer.WriteElementString("AllowedDrop", sop.AllowedDrop.ToString().ToLower()); 1094 writer.WriteElementString("AllowedDrop", sop.AllowedDrop.ToString().ToLower());
1095
1077 WriteUUID(writer, "CreatorID", sop.CreatorID, options); 1096 WriteUUID(writer, "CreatorID", sop.CreatorID, options);
1097
1098 if (sop.CreatorData != null && sop.CreatorData != string.Empty)
1099 writer.WriteElementString("CreatorData", sop.CreatorData);
1100 else if (options.ContainsKey("profile"))
1101 {
1102 if (m_UserManagement == null)
1103 m_UserManagement = sop.ParentGroup.Scene.RequestModuleInterface<IUserManagement>();
1104 string name = m_UserManagement.GetUserName(sop.CreatorID);
1105 writer.WriteElementString("CreatorData", (string)options["profile"] + "/" + sop.CreatorID + ";" + name);
1106 }
1107
1078 WriteUUID(writer, "FolderID", sop.FolderID, options); 1108 WriteUUID(writer, "FolderID", sop.FolderID, options);
1079 writer.WriteElementString("InventorySerial", sop.InventorySerial.ToString()); 1109 writer.WriteElementString("InventorySerial", sop.InventorySerial.ToString());
1080 1110
1081 WriteTaskInventory(writer, sop.TaskInventory, options); 1111 WriteTaskInventory(writer, sop.TaskInventory, options, sop.ParentGroup.Scene);
1082 1112
1083 WriteUUID(writer, "UUID", sop.UUID, options); 1113 WriteUUID(writer, "UUID", sop.UUID, options);
1084 writer.WriteElementString("LocalId", sop.LocalId.ToString()); 1114 writer.WriteElementString("LocalId", sop.LocalId.ToString());
@@ -1202,7 +1232,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1202 writer.WriteElementString(name, flagsStr); 1232 writer.WriteElementString(name, flagsStr);
1203 } 1233 }
1204 1234
1205 static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options) 1235 static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary<string, object> options, Scene scene)
1206 { 1236 {
1207 if (tinv.Count > 0) // otherwise skip this 1237 if (tinv.Count > 0) // otherwise skip this
1208 { 1238 {
@@ -1215,7 +1245,20 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1215 WriteUUID(writer, "AssetID", item.AssetID, options); 1245 WriteUUID(writer, "AssetID", item.AssetID, options);
1216 writer.WriteElementString("BasePermissions", item.BasePermissions.ToString()); 1246 writer.WriteElementString("BasePermissions", item.BasePermissions.ToString());
1217 writer.WriteElementString("CreationDate", item.CreationDate.ToString()); 1247 writer.WriteElementString("CreationDate", item.CreationDate.ToString());
1248
1249
1218 WriteUUID(writer, "CreatorID", item.CreatorID, options); 1250 WriteUUID(writer, "CreatorID", item.CreatorID, options);
1251
1252 if (item.CreatorData != null && item.CreatorData != string.Empty)
1253 writer.WriteElementString("CreatorData", item.CreatorData);
1254 else if (options.ContainsKey("profile"))
1255 {
1256 if (m_UserManagement == null)
1257 m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
1258 string name = m_UserManagement.GetUserName(item.CreatorID);
1259 writer.WriteElementString("CreatorData", (string)options["profile"] + "/" + item.CreatorID + ";" + name);
1260 }
1261
1219 writer.WriteElementString("Description", item.Description); 1262 writer.WriteElementString("Description", item.Description);
1220 writer.WriteElementString("EveryonePermissions", item.EveryonePermissions.ToString()); 1263 writer.WriteElementString("EveryonePermissions", item.EveryonePermissions.ToString());
1221 writer.WriteElementString("Flags", item.Flags.ToString()); 1264 writer.WriteElementString("Flags", item.Flags.ToString());
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs
deleted file mode 100644
index 46ad30f..0000000
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDialplan.cs
+++ /dev/null
@@ -1,104 +0,0 @@
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
28using log4net;
29using System;
30using System.Reflection;
31using System.Text;
32using System.Collections;
33
34namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
35{
36 public class FreeSwitchDialplan
37 {
38 private static readonly ILog m_log =
39 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40
41
42 public Hashtable HandleDialplanRequest(string Context, string Realm, Hashtable request)
43 {
44 m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString());
45
46 Hashtable response = new Hashtable();
47
48 foreach (DictionaryEntry item in request)
49 {
50 m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value);
51 }
52
53 string requestcontext = (string) request["Hunt-Context"];
54 response["content_type"] = "text/xml";
55 response["keepalive"] = false;
56 response["int_response_code"] = 200;
57 if (Context != String.Empty && Context != requestcontext)
58 {
59 m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context");
60 response["str_response_string"] = "";
61 } else {
62 response["str_response_string"] = String.Format(@"<?xml version=""1.0"" encoding=""utf-8""?>
63 <document type=""freeswitch/xml"">
64 <section name=""dialplan"">
65 <context name=""{0}"">" +
66
67/* <!-- dial via SIP uri -->
68 <extension name=""sip_uri"">
69 <condition field=""destination_number"" expression=""^sip:(.*)$"">
70 <action application=""bridge"" data=""sofia/${use_profile}/$1""/>
71 <!--<action application=""bridge"" data=""$1""/>-->
72 </condition>
73 </extension>*/
74
75 @"<extension name=""opensim_conferences"">
76 <condition field=""destination_number"" expression=""^confctl-(.*)$"">
77 <action application=""answer""/>
78 <action application=""conference"" data=""$1-{1}@{0}""/>
79 </condition>
80 </extension>
81
82 <extension name=""opensim_conf"">
83 <condition field=""destination_number"" expression=""^conf-(.*)$"">
84 <action application=""answer""/>
85 <action application=""conference"" data=""$1-{1}@{0}""/>
86 </condition>
87 </extension>
88
89 <extension name=""avatar"">
90 <condition field=""destination_number"" expression=""^(x.*)$"">
91 <action application=""bridge"" data=""user/$1""/>
92 </condition>
93 </extension>
94
95 </context>
96 </section>
97 </document>", Context, Realm);
98 }
99
100 return response;
101 }
102 }
103
104}
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs
deleted file mode 100644
index 17cdf74..0000000
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchDirectory.cs
+++ /dev/null
@@ -1,348 +0,0 @@
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
28using log4net;
29using System;
30using System.Reflection;
31using System.Text;
32using System.Collections;
33
34namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
35{
36 public class FreeSwitchDirectory
37 {
38 private static readonly ILog m_log =
39 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40
41 public Hashtable HandleDirectoryRequest(string Context, string Realm, Hashtable request)
42 {
43 Hashtable response = new Hashtable();
44 string domain = (string) request["domain"];
45 if (domain != Realm) {
46 response["content_type"] = "text/xml";
47 response["keepalive"] = false;
48 response["int_response_code"] = 200;
49 response["str_response_string"] = "";
50 } else {
51 m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString());
52
53 // information in the request we might be interested in
54
55 // Request 1 sip_auth for users account
56
57 //Event-Calling-Function=sofia_reg_parse_auth
58 //Event-Calling-Line-Number=1494
59 //action=sip_auth
60 //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41)
61 //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
62 //sip_auth_realm=9.20.151.43
63 //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==)
64 //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers
65 //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
66 //sip_to_host=9.20.151.43
67 //sip_auth_method=REGISTER
68 //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D
69 //domain=9.20.151.43
70 //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup
71
72 foreach (DictionaryEntry item in request)
73 {
74 m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value);
75 }
76
77 string eventCallingFunction = (string) request["Event-Calling-Function"];
78 if (eventCallingFunction == null)
79 {
80 eventCallingFunction = "sofia_reg_parse_auth";
81 }
82
83 if (eventCallingFunction.Length == 0)
84 {
85 eventCallingFunction = "sofia_reg_parse_auth";
86 }
87
88 if (eventCallingFunction == "sofia_reg_parse_auth")
89 {
90 string sipAuthMethod = (string)request["sip_auth_method"];
91
92 if (sipAuthMethod == "REGISTER")
93 {
94 response = HandleRegister(Context, Realm, request);
95 }
96 else if (sipAuthMethod == "INVITE")
97 {
98 response = HandleInvite(Context, Realm, request);
99 }
100 else
101 {
102 m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod);
103 response["int_response_code"] = 404;
104 response["content_type"] = "text/xml";
105 response["str_response_string"] = "";
106 }
107 }
108 else if (eventCallingFunction == "switch_xml_locate_user")
109 {
110 response = HandleLocateUser(Realm, request);
111 }
112 else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made
113 {
114 response = HandleLocateUser(Realm, request);
115 }
116 else if (eventCallingFunction == "user_outgoing_channel")
117 {
118 response = HandleRegister(Context, Realm, request);
119 }
120 else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup
121 {
122 response = HandleConfigSofia(Context, Realm, request);
123 }
124 else if (eventCallingFunction == "switch_load_network_lists")
125 {
126 //response = HandleLoadNetworkLists(request);
127 response["int_response_code"] = 404;
128 response["keepalive"] = false;
129 response["content_type"] = "text/xml";
130 response["str_response_string"] = "";
131 }
132 else
133 {
134 m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction);
135 response["int_response_code"] = 404;
136 response["keepalive"] = false;
137 response["content_type"] = "text/xml";
138 response["str_response_string"] = "";
139 }
140 }
141 return response;
142 }
143
144 private Hashtable HandleRegister(string Context, string Realm, Hashtable request)
145 {
146 m_log.Info("[FreeSwitchDirectory] HandleRegister called");
147
148 // TODO the password we return needs to match that sent in the request, this is hard coded for now
149 string password = "1234";
150 string domain = (string) request["domain"];
151 string user = (string) request["user"];
152
153 Hashtable response = new Hashtable();
154 response["content_type"] = "text/xml";
155 response["keepalive"] = false;
156 response["int_response_code"] = 200;
157
158 response["str_response_string"] = String.Format(
159 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
160 "<document type=\"freeswitch/xml\">\r\n" +
161 "<section name=\"directory\" description=\"User Directory\">\r\n" +
162 "<domain name=\"{0}\">\r\n" +
163 "<user id=\"{1}\">\r\n" +
164 "<params>\r\n" +
165 "<param name=\"password\" value=\"{2}\" />\r\n" +
166 "<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
167 "</params>\r\n" +
168 "<variables>\r\n" +
169 "<variable name=\"user_context\" value=\"{3}\" />\r\n" +
170 "<variable name=\"presence_id\" value=\"{1}@{0}\"/>"+
171 "</variables>\r\n" +
172 "</user>\r\n" +
173 "</domain>\r\n" +
174 "</section>\r\n" +
175 "</document>\r\n",
176 domain , user, password, Context);
177
178 return response;
179 }
180
181 private Hashtable HandleInvite(string Context, string Realm, Hashtable request)
182 {
183 m_log.Info("[FreeSwitchDirectory] HandleInvite called");
184
185 // TODO the password we return needs to match that sent in the request, this is hard coded for now
186 string password = "1234";
187 string domain = (string) request["domain"];
188 string user = (string) request["user"];
189 string sipRequestUser = (string) request["sip_request_user"];
190
191 Hashtable response = new Hashtable();
192 response["content_type"] = "text/xml";
193 response["keepalive"] = false;
194 response["int_response_code"] = 200;
195 response["str_response_string"] = String.Format(
196 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
197 "<document type=\"freeswitch/xml\">\r\n" +
198 "<section name=\"directory\" description=\"User Directory\">\r\n" +
199 "<domain name=\"{0}\">\r\n" +
200 "<user id=\"{1}\">\r\n" +
201 "<params>\r\n" +
202 "<param name=\"password\" value=\"{2}\" />\r\n" +
203 "<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${1}@${{dialed_domain}}}}${{sofia_contact(${1}@${{dialed_domain}})}}\"/>\r\n" +
204 "</params>\r\n" +
205 "<variables>\r\n" +
206 "<variable name=\"user_context\" value=\"{4}\" />\r\n" +
207 "<variable name=\"presence_id\" value=\"{1}@$${{domain}}\"/>"+
208 "</variables>\r\n" +
209 "</user>\r\n" +
210 "<user id=\"{3}\">\r\n" +
211 "<params>\r\n" +
212 "<param name=\"password\" value=\"{2}\" />\r\n" +
213 "<param name=\"dial-string\" value=\"{{sip_contact_user={1}}}{{presence_id=${3}@${{dialed_domain}}}}${{sofia_contact(${3}@${{dialed_domain}})}}\"/>\r\n" +
214 "</params>\r\n" +
215 "<variables>\r\n" +
216 "<variable name=\"user_context\" value=\"{4}\" />\r\n" +
217 "<variable name=\"presence_id\" value=\"{3}@$${{domain}}\"/>"+
218 "</variables>\r\n" +
219 "</user>\r\n" +
220 "</domain>\r\n" +
221 "</section>\r\n" +
222 "</document>\r\n",
223 domain , user, password,sipRequestUser, Context);
224
225 return response;
226 }
227
228 private Hashtable HandleLocateUser(String Realm, Hashtable request)
229 {
230 m_log.Info("[FreeSwitchDirectory] HandleLocateUser called");
231
232 // TODO the password we return needs to match that sent in the request, this is hard coded for now
233 string domain = (string) request["domain"];
234 string user = (string) request["user"];
235
236 Hashtable response = new Hashtable();
237 response["content_type"] = "text/xml";
238 response["keepalive"] = false;
239 response["int_response_code"] = 200;
240 response["str_response_string"] = String.Format(
241 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
242 "<document type=\"freeswitch/xml\">\r\n" +
243 "<section name=\"directory\" description=\"User Directory\">\r\n" +
244 "<domain name=\"{0}\">\r\n" +
245 "<params>\r\n" +
246 "<param name=\"dial-string\" value=\"{{sip_contact_user=${{dialed_user}}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
247 "</params>\r\n" +
248 "<user id=\"{1}\">\r\n" +
249 "<variables>\r\n"+
250 "<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
251 "<variable name=\"presence_id\" value=\"{1}@$${{domain}}\"/>"+
252 "</variables>\r\n"+
253 "</user>\r\n" +
254 "</domain>\r\n" +
255 "</section>\r\n" +
256 "</document>\r\n",
257 domain , user);
258
259 return response;
260 }
261
262 private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request)
263 {
264 m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called");
265
266 // TODO the password we return needs to match that sent in the request, this is hard coded for now
267 string domain = (string) request["domain"];
268
269 Hashtable response = new Hashtable();
270 response["content_type"] = "text/xml";
271 response["keepalive"] = false;
272 response["int_response_code"] = 200;
273 response["str_response_string"] = String.Format(
274 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
275 "<document type=\"freeswitch/xml\">\r\n" +
276 "<section name=\"directory\" description=\"User Directory\">\r\n" +
277 "<domain name=\"{0}\">\r\n" +
278 "<params>\r\n" +
279 "<param name=\"dial-string\" value=\"{{sip_contact_user=${{dialed_user}}}}{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
280 "</params>\r\n" +
281 "<groups name=\"default\">\r\n"+
282 "<users>\r\n"+
283 "<user id=\"$${{default_provider}}\">\r\n"+
284 "<gateways>\r\n"+
285 "<gateway name=\"$${{default_provider}}\">\r\n"+
286 "<param name=\"username\" value=\"$${{default_provider_username}}\"/>\r\n"+
287 "<param name=\"password\" value=\"$${{default_provider_password}}\"/>\r\n"+
288 "<param name=\"from-user\" value=\"$${{default_provider_username}}\"/>\r\n"+
289 "<param name=\"from-domain\" value=\"$${{default_provider_from_domain}}\"/>\r\n"+
290 "<param name=\"expire-seconds\" value=\"600\"/>\r\n"+
291 "<param name=\"register\" value=\"$${{default_provider_register}}\"/>\r\n"+
292 "<param name=\"retry-seconds\" value=\"30\"/>\r\n"+
293 "<param name=\"extension\" value=\"$${{default_provider_contact}}\"/>\r\n"+
294 "<param name=\"contact-params\" value=\"domain_name=$${{domain}}\"/>\r\n"+
295 "<param name=\"context\" value=\"{1}\"/>\r\n"+
296 "</gateway>\r\n"+
297 "</gateways>\r\n"+
298 "<params>\r\n"+
299 "<param name=\"password\" value=\"$${{default_provider_password}}\"/>\r\n"+
300 "</params>\r\n"+
301 "</user>\r\n"+
302 "</users>"+
303 "</groups>\r\n" +
304 "<variables>\r\n"+
305 "<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
306 "</variables>\r\n"+
307 "</domain>\r\n" +
308 "</section>\r\n" +
309 "</document>\r\n",
310 domain, Context);
311
312 return response;
313 }
314
315
316// private Hashtable HandleLoadNetworkLists(Hashtable request)
317// {
318// m_log.Info("[FreeSwitchDirectory] HandleLoadNetworkLists called");
319//
320// // TODO the password we return needs to match that sent in the request, this is hard coded for now
321// string domain = (string) request["domain"];
322//
323// Hashtable response = new Hashtable();
324// response["content_type"] = "text/xml";
325// response["keepalive"] = false;
326// response["int_response_code"] = 200;
327// response["str_response_string"] = String.Format(
328// "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
329// "<document type=\"freeswitch/xml\">\r\n" +
330// "<section name=\"directory\" description=\"User Directory\">\r\n" +
331// "<domain name=\"{0}\">\r\n" +
332// "<params>\r\n" +
333// "<param name=\"dial-string\" value=\"{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}\"/>\r\n" +
334// "</params>\r\n" +
335// "<groups name=\"default\"><users/></groups>\r\n" +
336// "<variables>\r\n"+
337// "<variable name=\"default_gateway\" value=\"$${{default_provider}}\"/>\r\n"+
338// "</variables>\r\n"+
339// "</domain>\r\n" +
340// "</section>\r\n" +
341// "</document>\r\n",
342// domain);
343//
344//
345// return response;
346// }
347 }
348}
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 242bc3f..294d4f0 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -37,10 +37,12 @@ using System.Collections;
37using System.Collections.Generic; 37using System.Collections.Generic;
38using System.Reflection; 38using System.Reflection;
39using OpenMetaverse; 39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
40using log4net; 41using log4net;
41using Nini.Config; 42using Nini.Config;
42using Nwc.XmlRpc; 43using Nwc.XmlRpc;
43using OpenSim.Framework; 44using OpenSim.Framework;
45using Mono.Addins;
44 46
45using OpenSim.Framework.Capabilities; 47using OpenSim.Framework.Capabilities;
46using OpenSim.Framework.Servers; 48using OpenSim.Framework.Servers;
@@ -49,28 +51,27 @@ using OpenSim.Region.Framework.Interfaces;
49using OpenSim.Region.Framework.Scenes; 51using OpenSim.Region.Framework.Scenes;
50using Caps = OpenSim.Framework.Capabilities.Caps; 52using Caps = OpenSim.Framework.Capabilities.Caps;
51using System.Text.RegularExpressions; 53using System.Text.RegularExpressions;
54using OpenSim.Server.Base;
55using OpenSim.Services.Interfaces;
56using OSDMap = OpenMetaverse.StructuredData.OSDMap;
52 57
53namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice 58namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
54{ 59{
55 public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule 60 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FreeSwitchVoiceModule")]
61 public class FreeSwitchVoiceModule : INonSharedRegionModule, IVoiceModule
56 { 62 {
57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 63 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58 64
59 private bool UseProxy = false;
60
61 // Capability string prefixes 65 // Capability string prefixes
62 private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; 66 private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
63 private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; 67 private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
64 private static readonly string m_chatSessionRequestPath = "0009/"; 68 private static readonly string m_chatSessionRequestPath = "0009/";
65 69
66 // Control info 70 // Control info
67 private static bool m_WOF = true; 71 private static bool m_Enabled = false;
68 private static bool m_pluginEnabled = false;
69 72
70 // FreeSwitch server is going to contact us and ask us all 73 // FreeSwitch server is going to contact us and ask us all
71 // sorts of things. 74 // sorts of things.
72 private static string m_freeSwitchServerUser;
73 private static string m_freeSwitchServerPass;
74 75
75 // SLVoice client will do a GET on this prefix 76 // SLVoice client will do a GET on this prefix
76 private static string m_freeSwitchAPIPrefix; 77 private static string m_freeSwitchAPIPrefix;
@@ -84,143 +85,147 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
84 private static string m_freeSwitchRealm; 85 private static string m_freeSwitchRealm;
85 private static string m_freeSwitchSIPProxy; 86 private static string m_freeSwitchSIPProxy;
86 private static bool m_freeSwitchAttemptUseSTUN; 87 private static bool m_freeSwitchAttemptUseSTUN;
87 // private static string m_freeSwitchSTUNServer;
88 private static string m_freeSwitchEchoServer; 88 private static string m_freeSwitchEchoServer;
89 private static int m_freeSwitchEchoPort; 89 private static int m_freeSwitchEchoPort;
90 private static string m_freeSwitchDefaultWellKnownIP; 90 private static string m_freeSwitchDefaultWellKnownIP;
91 private static int m_freeSwitchDefaultTimeout; 91 private static int m_freeSwitchDefaultTimeout;
92 // private static int m_freeSwitchSubscribeRetry;
93 private static string m_freeSwitchUrlResetPassword; 92 private static string m_freeSwitchUrlResetPassword;
94 // private static IPEndPoint m_FreeSwitchServiceIP; 93 private uint m_freeSwitchServicePort;
95 private int m_freeSwitchServicePort;
96 private string m_openSimWellKnownHTTPAddress; 94 private string m_openSimWellKnownHTTPAddress;
97 private string m_freeSwitchContext; 95 private string m_freeSwitchContext;
98 96
99 private FreeSwitchDirectory m_FreeSwitchDirectory;
100 private FreeSwitchDialplan m_FreeSwitchDialplan;
101
102 private readonly Dictionary<string, string> m_UUIDName = new Dictionary<string, string>(); 97 private readonly Dictionary<string, string> m_UUIDName = new Dictionary<string, string>();
103 private Dictionary<string, string> m_ParcelAddress = new Dictionary<string, string>(); 98 private Dictionary<string, string> m_ParcelAddress = new Dictionary<string, string>();
104 99
105 private Scene m_scene; 100 private Scene m_Scene;
106 101
102 private IConfig m_Config;
107 103
108 private IConfig m_config; 104 private IFreeswitchService m_FreeswitchService;
109 105
110 public void Initialise(Scene scene, IConfigSource config) 106 public void Initialise(IConfigSource config)
111 { 107 {
112 m_scene = scene; 108 m_Config = config.Configs["FreeSwitchVoice"];
113 m_config = config.Configs["FreeSwitchVoice"];
114 109
115 if (null == m_config) 110 if (m_Config == null)
116 { 111 {
117 m_log.Info("[FreeSwitchVoice] no config found, plugin disabled"); 112 m_log.Info("[FreeSwitchVoice] no config found, plugin disabled");
118 return; 113 return;
119 } 114 }
120 115
121 if (!m_config.GetBoolean("enabled", false)) 116 if (!m_Config.GetBoolean("Enabled", false))
122 { 117 {
123 m_log.Info("[FreeSwitchVoice] plugin disabled by configuration"); 118 m_log.Info("[FreeSwitchVoice] plugin disabled by configuration");
124 return; 119 return;
125 } 120 }
126 121
127 // This is only done the FIRST time this method is invoked. 122 try
128 if (m_WOF)
129 { 123 {
130 m_pluginEnabled = true; 124 string serviceDll = m_Config.GetString("LocalServiceModule",
131 m_WOF = false; 125 String.Empty);
132 126
133 try 127 if (serviceDll == String.Empty)
134 { 128 {
135 m_freeSwitchServerUser = m_config.GetString("freeswitch_server_user", String.Empty); 129 m_log.Error("[FreeSwitchVoice]: No LocalServiceModule named in section FreeSwitchVoice");
136 m_freeSwitchServerPass = m_config.GetString("freeswitch_server_pass", String.Empty); 130 return;
137 m_freeSwitchAPIPrefix = m_config.GetString("freeswitch_api_prefix", String.Empty); 131 }
138
139 // XXX: get IP address of HTTP server. (This can be this OpenSim server or another, or could be a dedicated grid service or may live on the freeswitch server)
140
141 string serviceIP = m_config.GetString("freeswitch_service_server", String.Empty);
142 int servicePort = m_config.GetInt("freeswitch_service_port", 80);
143 IPAddress serviceIPAddress = IPAddress.Parse(serviceIP);
144 // m_FreeSwitchServiceIP = new IPEndPoint(serviceIPAddress, servicePort);
145 m_freeSwitchServicePort = servicePort;
146 m_freeSwitchRealm = m_config.GetString("freeswitch_realm", String.Empty);
147 m_freeSwitchSIPProxy = m_config.GetString("freeswitch_sip_proxy", m_freeSwitchRealm);
148 m_freeSwitchAttemptUseSTUN = m_config.GetBoolean("freeswitch_attempt_stun", true);
149 // m_freeSwitchSTUNServer = m_config.GetString("freeswitch_stun_server", m_freeSwitchRealm);
150 m_freeSwitchEchoServer = m_config.GetString("freeswitch_echo_server", m_freeSwitchRealm);
151 m_freeSwitchEchoPort = m_config.GetInt("freeswitch_echo_port", 50505);
152 m_freeSwitchDefaultWellKnownIP = m_config.GetString("freeswitch_well_known_ip", m_freeSwitchRealm);
153 m_openSimWellKnownHTTPAddress = m_config.GetString("opensim_well_known_http_address", serviceIPAddress.ToString());
154 m_freeSwitchDefaultTimeout = m_config.GetInt("freeswitch_default_timeout", 5000);
155 // m_freeSwitchSubscribeRetry = m_config.GetInt("freeswitch_subscribe_retry", 120);
156 m_freeSwitchUrlResetPassword = m_config.GetString("freeswitch_password_reset_url", String.Empty);
157 m_freeSwitchContext = m_config.GetString("freeswitch_context", "default");
158
159 if (String.IsNullOrEmpty(m_freeSwitchServerUser) ||
160 String.IsNullOrEmpty(m_freeSwitchServerPass) ||
161 String.IsNullOrEmpty(m_freeSwitchRealm) ||
162 String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
163 {
164 m_log.Error("[FreeSwitchVoice] plugin mis-configured");
165 m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration");
166 return;
167 }
168 132
169 // set up http request handlers for 133 Object[] args = new Object[] { config };
170 // - prelogin: viv_get_prelogin.php 134 m_FreeswitchService = ServerUtils.LoadPlugin<IFreeswitchService>(serviceDll, args);
171 // - signin: viv_signin.php 135
172 // - buddies: viv_buddy.php 136 string jsonConfig = m_FreeswitchService.GetJsonConfig();
173 // - ???: viv_watcher.php 137 m_log.Debug("[FreeSwitchVoice]: Configuration string: " + jsonConfig);
174 // - signout: viv_signout.php 138 OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig);
175 if (UseProxy) 139
176 { 140 m_freeSwitchAPIPrefix = map["APIPrefix"].AsString();
177 MainServer.Instance.AddHTTPHandler(String.Format("{0}/", m_freeSwitchAPIPrefix), 141 m_freeSwitchRealm = map["Realm"].AsString();
178 ForwardProxyRequest); 142 m_freeSwitchSIPProxy = map["SIPProxy"].AsString();
179 } 143 m_freeSwitchAttemptUseSTUN = map["AttemptUseSTUN"].AsBoolean();
180 else 144 m_freeSwitchEchoServer = map["EchoServer"].AsString();
181 { 145 m_freeSwitchEchoPort = map["EchoPort"].AsInteger();
182 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), 146 m_freeSwitchDefaultWellKnownIP = map["DefaultWellKnownIP"].AsString();
183 FreeSwitchSLVoiceGetPreloginHTTPHandler); 147 m_freeSwitchDefaultTimeout = map["DefaultTimeout"].AsInteger();
148 m_freeSwitchUrlResetPassword = String.Empty;
149 m_freeSwitchContext = map["Context"].AsString();
150
151 if (String.IsNullOrEmpty(m_freeSwitchRealm) ||
152 String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
153 {
154 m_log.Error("[FreeSwitchVoice] plugin mis-configured");
155 m_log.Info("[FreeSwitchVoice] plugin disabled: incomplete configuration");
156 return;
157 }
184 158
185 // RestStreamHandler h = new 159 // set up http request handlers for
186 // RestStreamHandler("GET", 160 // - prelogin: viv_get_prelogin.php
187 // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); 161 // - signin: viv_signin.php
188 // MainServer.Instance.AddStreamHandler(h); 162 // - buddies: viv_buddy.php
163 // - ???: viv_watcher.php
164 // - signout: viv_signout.php
165 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix),
166 FreeSwitchSLVoiceGetPreloginHTTPHandler);
189 167
168 // RestStreamHandler h = new
169 // RestStreamHandler("GET",
170 // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler);
171 // MainServer.Instance.AddStreamHandler(h);
190 172
191 173
192 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix),
193 FreeSwitchSLVoiceSigninHTTPHandler);
194 174
195 // set up http request handlers to provide 175 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix),
196 // on-demand FreeSwitch configuration to 176 FreeSwitchSLVoiceSigninHTTPHandler);
197 // FreeSwitch's mod_curl_xml
198 MainServer.Instance.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix),
199 FreeSwitchConfigHTTPHandler);
200 177
201 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), 178 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix),
202 FreeSwitchSLVoiceBuddyHTTPHandler); 179 FreeSwitchSLVoiceBuddyHTTPHandler);
203 }
204 180
205 m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); 181 m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm);
206 182
207 m_FreeSwitchDirectory = new FreeSwitchDirectory(); 183 m_Enabled = true;
208 m_FreeSwitchDialplan = new FreeSwitchDialplan();
209 184
210 m_pluginEnabled = true; 185 m_log.Info("[FreeSwitchVoice] plugin enabled");
211 m_WOF = false; 186 }
187 catch (Exception e)
188 {
189 m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message);
190 m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString());
191 return;
192 }
212 193
213 m_log.Info("[FreeSwitchVoice] plugin enabled"); 194 // This here is a region module trying to make a global setting.
195 // Not really a good idea but it's Windows only, so I can't test.
196 try
197 {
198 ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation;
199 }
200 catch (NotImplementedException)
201 {
202 try
203 {
204#pragma warning disable 0612, 0618
205 // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this!
206 ServicePointManager.CertificatePolicy = new MonoCert();
207#pragma warning restore 0612, 0618
214 } 208 }
215 catch (Exception e) 209 catch (Exception)
216 { 210 {
217 m_log.ErrorFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.Message); 211 // COmmented multiline spam log message
218 m_log.DebugFormat("[FreeSwitchVoice] plugin initialization failed: {0}", e.ToString()); 212 //m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions.");
219 return;
220 } 213 }
221 } 214 }
215 }
222 216
223 if (m_pluginEnabled) 217 public void AddRegion(Scene scene)
218 {
219 m_Scene = scene;
220
221 // We generate these like this: The region's external host name
222 // as defined in Regions.ini is a good address to use. It's a
223 // dotted quad (or should be!) and it can reach this host from
224 // a client. The port is grabbed from the region's HTTP server.
225 m_openSimWellKnownHTTPAddress = m_Scene.RegionInfo.ExternalHostName;
226 m_freeSwitchServicePort = MainServer.Instance.Port;
227
228 if (m_Enabled)
224 { 229 {
225 // we need to capture scene in an anonymous method 230 // we need to capture scene in an anonymous method
226 // here as we need it later in the callbacks 231 // here as we need it later in the callbacks
@@ -228,36 +233,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
228 { 233 {
229 OnRegisterCaps(scene, agentID, caps); 234 OnRegisterCaps(scene, agentID, caps);
230 }; 235 };
231
232 try
233 {
234 ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation;
235 }
236 catch (NotImplementedException)
237 {
238 try
239 {
240#pragma warning disable 0612, 0618
241 // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this!
242 ServicePointManager.CertificatePolicy = new MonoCert();
243#pragma warning restore 0612, 0618
244 }
245 catch (Exception)
246 {
247 m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions.");
248 }
249 }
250 } 236 }
251 } 237 }
252 238
253 public void PostInitialise() 239 public void RemoveRegion(Scene scene)
254 { 240 {
255 if (m_pluginEnabled) 241 }
242
243 public void RegionLoaded(Scene scene)
244 {
245 if (m_Enabled)
256 { 246 {
257 m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); 247 m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene");
258 248
259 // register the voice interface for this module, so the script engine can call us 249 // register the voice interface for this module, so the script engine can call us
260 m_scene.RegisterModuleInterface<IVoiceModule>(this); 250 scene.RegisterModuleInterface<IVoiceModule>(this);
261 } 251 }
262 } 252 }
263 253
@@ -270,9 +260,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
270 get { return "FreeSwitchVoiceModule"; } 260 get { return "FreeSwitchVoiceModule"; }
271 } 261 }
272 262
273 public bool IsSharedModule 263 public Type ReplaceableInterface
274 { 264 {
275 get { return true; } 265 get { return null; }
276 } 266 }
277 267
278 // <summary> 268 // <summary>
@@ -725,46 +715,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
725 715
726 response["int_response_code"] = 200; 716 response["int_response_code"] = 200;
727 return response; 717 return response;
728 /*
729 <level0>
730 <status>OK</status><body><status>Ok</status><cookie_name>lib_session</cookie_name>
731 * <cookie>xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::</cookie>
732 * <auth_token>xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::</auth_token>
733 * <primary>1</primary>
734 * <account_id>7449</account_id>
735 * <displayname>Teravus Ousley</displayname></body></level0>
736 */
737 }
738
739 public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request)
740 {
741 m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler called with {0}", (string)request["body"]);
742
743 Hashtable response = new Hashtable();
744 response["str_response_string"] = string.Empty;
745 // all the params come as NVPs in the request body
746 Hashtable requestBody = parseRequestBody((string) request["body"]);
747
748 // is this a dialplan or directory request
749 string section = (string) requestBody["section"];
750
751 if (section == "directory")
752 response = m_FreeSwitchDirectory.HandleDirectoryRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody);
753 else if (section == "dialplan")
754 response = m_FreeSwitchDialplan.HandleDialplanRequest(m_freeSwitchContext, m_freeSwitchRealm, requestBody);
755 else
756 m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section);
757
758 // XXX: re-generate dialplan:
759 // - conf == region UUID
760 // - conf number = region port
761 // -> TODO Initialise(): keep track of regions via events
762 // re-generate accounts for all avatars
763 // -> TODO Initialise(): keep track of avatars via events
764 Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
765
766 m_log.DebugFormat("[FreeSwitchVoice] FreeSwitchConfigHTTPHandler return {0}",normalizeEndLines.Replace(((string)response["str_response_string"]), ""));
767 return response;
768 } 718 }
769 719
770 public Hashtable parseRequestBody(string body) 720 public Hashtable parseRequestBody(string body)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index c251a49..d06b134 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2983,17 +2983,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2983 2983
2984 if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) 2984 if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
2985 { 2985 {
2986 SceneObjectGroup grp = m_host.ParentGroup;
2987 UUID itemID = grp.GetFromItemID();
2988
2989 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2990
2991 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 2986 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
2992 if (attachmentsModule != null) 2987 if (attachmentsModule != null)
2993 attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient); 2988 Util.FireAndForget(DetachWrapper, m_host);
2994 } 2989 }
2995 } 2990 }
2996 2991
2992 private void DetachWrapper(object o)
2993 {
2994 SceneObjectPart host = (SceneObjectPart)o;
2995
2996 SceneObjectGroup grp = host.ParentGroup;
2997 UUID itemID = grp.GetFromItemID();
2998 ScenePresence presence = World.GetScenePresence(host.OwnerID);
2999
3000 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3001 if (attachmentsModule != null)
3002 attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient);
3003 }
3004
2997 public void llTakeCamera(string avatar) 3005 public void llTakeCamera(string avatar)
2998 { 3006 {
2999 m_host.AddScriptLPS(1); 3007 m_host.AddScriptLPS(1);
@@ -8742,24 +8750,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8742 8750
8743 switch (data) 8751 switch (data)
8744 { 8752 {
8745 case 5: // DATA_SIM_POS 8753 case ScriptBaseClass.DATA_SIM_POS:
8746 if (info == null) 8754 if (info == null)
8747 { 8755 {
8748 ScriptSleep(1000); 8756 ScriptSleep(1000);
8749 return UUID.Zero.ToString(); 8757 return UUID.Zero.ToString();
8750 } 8758 }
8751 reply = new LSL_Vector( 8759 reply = new LSL_Vector(
8752 info.RegionLocX * Constants.RegionSize, 8760 info.RegionLocX,
8753 info.RegionLocY * Constants.RegionSize, 8761 info.RegionLocY,
8754 0).ToString(); 8762 0).ToString();
8755 break; 8763 break;
8756 case 6: // DATA_SIM_STATUS 8764 case ScriptBaseClass.DATA_SIM_STATUS:
8757 if (info != null) 8765 if (info != null)
8758 reply = "up"; // Duh! 8766 reply = "up"; // Duh!
8759 else 8767 else
8760 reply = "unknown"; 8768 reply = "unknown";
8761 break; 8769 break;
8762 case 7: // DATA_SIM_RATING 8770 case ScriptBaseClass.DATA_SIM_RATING:
8763 if (info == null) 8771 if (info == null)
8764 { 8772 {
8765 ScriptSleep(1000); 8773 ScriptSleep(1000);
@@ -8775,7 +8783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8775 else 8783 else
8776 reply = "UNKNOWN"; 8784 reply = "UNKNOWN";
8777 break; 8785 break;
8778 case 128: 8786 case ScriptBaseClass.DATA_SIM_RELEASE:
8779 if (ossl != null) 8787 if (ossl != null)
8780 ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData"); 8788 ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData");
8781 reply = "OpenSim"; 8789 reply = "OpenSim";
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 8a98be7..fc92f23 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -639,6 +639,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
639 // 639 //
640 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent"); 640 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent");
641 641
642 TeleportAgent(agent, regionName, position, lookat);
643 }
644
645 private void TeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
646 {
642 m_host.AddScriptLPS(1); 647 m_host.AddScriptLPS(1);
643 UUID agentId = new UUID(); 648 UUID agentId = new UUID();
644 if (UUID.TryParse(agent, out agentId)) 649 if (UUID.TryParse(agent, out agentId))
@@ -651,7 +656,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
651 == World.LandChannel.GetLandObject( 656 == World.LandChannel.GetLandObject(
652 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 657 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
653 { 658 {
654
655 // Check for hostname , attempt to make a hglink 659 // Check for hostname , attempt to make a hglink
656 // and convert the regionName to the target region 660 // and convert the regionName to the target region
657 if (regionName.Contains(".") && regionName.Contains(":")) 661 if (regionName.Contains(".") && regionName.Contains(":"))
@@ -661,7 +665,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
661 if (regions != null && regions.Count > 0) 665 if (regions != null && regions.Count > 0)
662 { 666 {
663 GridRegion regInfo = regions[0]; 667 GridRegion regInfo = regions[0];
664 regionName = regInfo.RegionName; 668 string[] parts = regInfo.RegionName.Split(new char[] { ':' });
669 if (parts.Length > 2)
670 regionName = parts[2];
671 else
672 regionName = parts[0];
665 } 673 }
666 } 674 }
667 World.RequestTeleportLocation(presence.ControllingClient, regionName, 675 World.RequestTeleportLocation(presence.ControllingClient, regionName,
@@ -674,13 +682,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
674 } 682 }
675 } 683 }
676 684
677 // Teleport functions
678 public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 685 public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
679 { 686 {
680 // High because there is no security check. High griefer potential 687 // High because there is no security check. High griefer potential
681 // 688 //
682 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent"); 689 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent");
683 690
691 TeleportAgent(agent, regionX, regionY, position, lookat);
692 }
693
694 private void TeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
695 {
684 ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize)); 696 ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize));
685 697
686 m_host.AddScriptLPS(1); 698 m_host.AddScriptLPS(1);
@@ -709,6 +721,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
709 osTeleportAgent(agent, World.RegionInfo.RegionName, position, lookat); 721 osTeleportAgent(agent, World.RegionInfo.RegionName, position, lookat);
710 } 722 }
711 723
724 public void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
725 {
726 // Threat level None because this is what can already be done with the World Map in the viewer
727 CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
728
729 TeleportAgent(m_host.OwnerID.ToString(), regionName, position, lookat);
730 }
731
732 public void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
733 {
734 osTeleportOwner(World.RegionInfo.RegionName, position, lookat);
735 }
736
737 public void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
738 {
739 CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
740
741 TeleportAgent(m_host.OwnerID.ToString(), regionX, regionY, position, lookat);
742 }
743
712 // Functions that get information from the agent itself. 744 // Functions that get information from the agent itself.
713 // 745 //
714 // osGetAgentIP - this is used to determine the IP address of 746 // osGetAgentIP - this is used to determine the IP address of
@@ -2266,5 +2298,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2266 }); 2298 });
2267 return result; 2299 return result;
2268 } 2300 }
2301
2302 /// <summary>
2303 /// Convert a unix time to a llGetTimestamp() like string
2304 /// </summary>
2305 /// <param name="unixTime"></param>
2306 /// <returns></returns>
2307 public LSL_String osUnixTimeToTimestamp(long time)
2308 {
2309 CheckThreatLevel(ThreatLevel.VeryLow, "osUnixTimeToTimestamp");
2310 long baseTicks = 621355968000000000;
2311 long tickResolution = 10000000;
2312 long epochTicks = (time * tickResolution) + baseTicks;
2313 DateTime date = new DateTime(epochTicks);
2314
2315 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
2316 }
2269 } 2317 }
2270} 2318} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 630821b..10d61ca 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -86,6 +86,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
88 void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
90 void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 92
90 // Animation commands 93 // Animation commands
91 void osAvatarPlayAnimation(string avatar, string animation); 94 void osAvatarPlayAnimation(string avatar, string animation);
@@ -181,5 +184,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
181 184
182 LSL_List osGetAvatarList(); 185 LSL_List osGetAvatarList();
183 186
187 LSL_String osUnixTimeToTimestamp(long time);
184 } 188 }
185} 189}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index e289554..f3142e6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -227,6 +227,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
227 m_OSSL_Functions.osTeleportAgent(agent, position, lookat); 227 m_OSSL_Functions.osTeleportAgent(agent, position, lookat);
228 } 228 }
229 229
230 public void osTeleportOwner(string regionName, vector position, vector lookat)
231 {
232 m_OSSL_Functions.osTeleportOwner(regionName, position, lookat);
233 }
234
235 public void osTeleportOwner(int regionX, int regionY, vector position, vector lookat)
236 {
237 m_OSSL_Functions.osTeleportOwner(regionX, regionY, position, lookat);
238 }
239
240 public void osTeleportOwner(vector position, vector lookat)
241 {
242 m_OSSL_Functions.osTeleportOwner(position, lookat);
243 }
244
230 // Avatar info functions 245 // Avatar info functions
231 public string osGetAgentIP(string agent) 246 public string osGetAgentIP(string agent)
232 { 247 {
@@ -663,26 +678,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
663 { 678 {
664 return m_OSSL_Functions.osGetSimulatorMemory(); 679 return m_OSSL_Functions.osGetSimulatorMemory();
665 } 680 }
681
666 public void osKickAvatar(string FirstName,string SurName,string alert) 682 public void osKickAvatar(string FirstName,string SurName,string alert)
667 { 683 {
668 m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert); 684 m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert);
669 } 685 }
686
670 public void osSetSpeed(string UUID, float SpeedModifier) 687 public void osSetSpeed(string UUID, float SpeedModifier)
671 { 688 {
672 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier); 689 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
673 } 690 }
691
674 public void osCauseDamage(string avatar, double damage) 692 public void osCauseDamage(string avatar, double damage)
675 { 693 {
676 m_OSSL_Functions.osCauseDamage(avatar, damage); 694 m_OSSL_Functions.osCauseDamage(avatar, damage);
677 } 695 }
696
678 public void osCauseHealing(string avatar, double healing) 697 public void osCauseHealing(string avatar, double healing)
679 { 698 {
680 m_OSSL_Functions.osCauseHealing(avatar, healing); 699 m_OSSL_Functions.osCauseHealing(avatar, healing);
681 } 700 }
701
682 public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules) 702 public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules)
683 { 703 {
684 return m_OSSL_Functions.osGetPrimitiveParams(prim, rules); 704 return m_OSSL_Functions.osGetPrimitiveParams(prim, rules);
685 } 705 }
706
686 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) 707 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
687 { 708 {
688 m_OSSL_Functions.osSetPrimitiveParams(prim, rules); 709 m_OSSL_Functions.osSetPrimitiveParams(prim, rules);
@@ -702,5 +723,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
702 { 723 {
703 return m_OSSL_Functions.osGetAvatarList(); 724 return m_OSSL_Functions.osGetAvatarList();
704 } 725 }
726
727 public LSL_String osUnixTimeToTimestamp(long time)
728 {
729 return m_OSSL_Functions.osUnixTimeToTimestamp(time);
730 }
705 } 731 }
706} 732} \ No newline at end of file