aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs13
-rw-r--r--OpenSim/Framework/MultipartForm.cs117
-rw-r--r--OpenSim/Framework/RegionCommsListener.cs2
-rw-r--r--OpenSim/Framework/RegionInfo.cs18
-rw-r--r--OpenSim/Framework/UntrustedWebRequest.cs203
-rw-r--r--OpenSim/Framework/WebUtil.cs330
-rw-r--r--OpenSim/Framework/sLLVector3.cs51
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs16
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs44
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs40
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs46
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs95
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs55
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs1
-rw-r--r--OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs32
-rw-r--r--OpenSim/Services/Base/ServiceBase.cs20
-rw-r--r--OpenSim/Services/Friends/FriendsServiceBase.cs9
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs1
-rw-r--r--OpenSim/Services/UserAccountService/UserAccountService.cs9
23 files changed, 945 insertions, 241 deletions
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index fee71f0..a1ac84c 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -41,14 +41,14 @@ namespace OpenSim.Framework
41 public Guid AgentID; 41 public Guid AgentID;
42 public bool alwaysrun; 42 public bool alwaysrun;
43 public float AVHeight; 43 public float AVHeight;
44 public sLLVector3 cameraPosition; 44 public Vector3 cameraPosition;
45 public float drawdistance; 45 public float drawdistance;
46 public float godlevel; 46 public float godlevel;
47 public uint GroupAccess; 47 public uint GroupAccess;
48 public sLLVector3 Position; 48 public Vector3 Position;
49 public ulong regionHandle; 49 public ulong regionHandle;
50 public byte[] throttles; 50 public byte[] throttles;
51 public sLLVector3 Velocity; 51 public Vector3 Velocity;
52 52
53 public ChildAgentDataUpdate() 53 public ChildAgentDataUpdate()
54 { 54 {
@@ -177,14 +177,13 @@ namespace OpenSim.Framework
177 Size = new Vector3(); 177 Size = new Vector3();
178 Size.Z = cAgent.AVHeight; 178 Size.Z = cAgent.AVHeight;
179 179
180 Center = new Vector3(cAgent.cameraPosition.x, cAgent.cameraPosition.y, cAgent.cameraPosition.z); 180 Center = cAgent.cameraPosition;
181 Far = cAgent.drawdistance; 181 Far = cAgent.drawdistance;
182 Position = new Vector3(cAgent.Position.x, cAgent.Position.y, cAgent.Position.z); 182 Position = cAgent.Position;
183 RegionHandle = cAgent.regionHandle; 183 RegionHandle = cAgent.regionHandle;
184 Throttles = cAgent.throttles; 184 Throttles = cAgent.throttles;
185 Velocity = new Vector3(cAgent.Velocity.x, cAgent.Velocity.y, cAgent.Velocity.z); 185 Velocity = cAgent.Velocity;
186 } 186 }
187
188 } 187 }
189 188
190 public class AgentGroupData 189 public class AgentGroupData
diff --git a/OpenSim/Framework/MultipartForm.cs b/OpenSim/Framework/MultipartForm.cs
new file mode 100644
index 0000000..8ba6d22
--- /dev/null
+++ b/OpenSim/Framework/MultipartForm.cs
@@ -0,0 +1,117 @@
1using System;
2using System.Collections.Generic;
3using System.Net;
4using System.IO;
5using System.Text;
6
7namespace OpenSim.Framework
8{
9 public static class MultipartForm
10 {
11 #region Helper Classes
12
13 public abstract class Element
14 {
15 public string Name;
16 }
17
18 public class File : Element
19 {
20 public string Filename;
21 public string ContentType;
22 public byte[] Data;
23
24 public File(string name, string filename, string contentType, byte[] data)
25 {
26 Name = name;
27 Filename = filename;
28 ContentType = contentType;
29 Data = data;
30 }
31 }
32
33 public class Parameter : Element
34 {
35 public string Value;
36
37 public Parameter(string name, string value)
38 {
39 Name = name;
40 Value = value;
41 }
42 }
43
44 #endregion Helper Classes
45
46 public static HttpWebResponse Post(HttpWebRequest request, List<Element> postParameters)
47 {
48 string boundary = Boundary();
49
50 // Set up the request properties
51 request.Method = "POST";
52 request.ContentType = "multipart/form-data; boundary=" + boundary;
53
54 #region Stream Writing
55
56 using (MemoryStream formDataStream = new MemoryStream())
57 {
58 foreach (var param in postParameters)
59 {
60 if (param is File)
61 {
62 File file = (File)param;
63
64 // Add just the first part of this param, since we will write the file data directly to the Stream
65 string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
66 boundary,
67 file.Name,
68 !String.IsNullOrEmpty(file.Filename) ? file.Filename : "tempfile",
69 file.ContentType);
70
71 formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, header.Length);
72 formDataStream.Write(file.Data, 0, file.Data.Length);
73 }
74 else
75 {
76 Parameter parameter = (Parameter)param;
77
78 string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n",
79 boundary,
80 parameter.Name,
81 parameter.Value);
82 formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, postData.Length);
83 }
84 }
85
86 // Add the end of the request
87 byte[] footer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
88 formDataStream.Write(footer, 0, footer.Length);
89
90 request.ContentLength = formDataStream.Length;
91
92 // Copy the temporary stream to the network stream
93 formDataStream.Seek(0, SeekOrigin.Begin);
94 using (Stream requestStream = request.GetRequestStream())
95 formDataStream.CopyTo(requestStream, (int)formDataStream.Length);
96 }
97
98 #endregion Stream Writing
99
100 return request.GetResponse() as HttpWebResponse;
101 }
102
103 private static string Boundary()
104 {
105 Random rnd = new Random();
106 string formDataBoundary = String.Empty;
107
108 while (formDataBoundary.Length < 15)
109 formDataBoundary = formDataBoundary + rnd.Next();
110
111 formDataBoundary = formDataBoundary.Substring(0, 15);
112 formDataBoundary = "-----------------------------" + formDataBoundary;
113
114 return formDataBoundary;
115 }
116 }
117}
diff --git a/OpenSim/Framework/RegionCommsListener.cs b/OpenSim/Framework/RegionCommsListener.cs
index 718a556..3e0955d 100644
--- a/OpenSim/Framework/RegionCommsListener.cs
+++ b/OpenSim/Framework/RegionCommsListener.cs
@@ -45,7 +45,7 @@ namespace OpenSim.Framework
45 private GenericCall2 handlerExpectChildAgent = null; // OnExpectChildAgent; 45 private GenericCall2 handlerExpectChildAgent = null; // OnExpectChildAgent;
46 private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser 46 private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser
47 private UpdateNeighbours handlerNeighboursUpdate = null; // OnNeighboursUpdate; 47 private UpdateNeighbours handlerNeighboursUpdate = null; // OnNeighboursUpdate;
48 private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; 48// private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion;
49 private LogOffUser handlerLogOffUser = null; 49 private LogOffUser handlerLogOffUser = null;
50 private GetLandData handlerGetLandData = null; 50 private GetLandData handlerGetLandData = null;
51 51
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index 828bbfc..05f9cf9 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -654,7 +654,7 @@ namespace OpenSim.Framework
654 654
655 private void ReadNiniConfig(IConfigSource source, string name) 655 private void ReadNiniConfig(IConfigSource source, string name)
656 { 656 {
657 bool creatingNew = false; 657// bool creatingNew = false;
658 658
659 if (source.Configs.Count == 0) 659 if (source.Configs.Count == 0)
660 { 660 {
@@ -671,7 +671,7 @@ namespace OpenSim.Framework
671 671
672 source.AddConfig(name); 672 source.AddConfig(name);
673 673
674 creatingNew = true; 674// creatingNew = true;
675 } 675 }
676 676
677 if (name == String.Empty) 677 if (name == String.Empty)
@@ -681,7 +681,7 @@ namespace OpenSim.Framework
681 { 681 {
682 source.AddConfig(name); 682 source.AddConfig(name);
683 683
684 creatingNew = true; 684// creatingNew = true;
685 } 685 }
686 686
687 IConfig config = source.Configs[name]; 687 IConfig config = source.Configs[name];
@@ -700,15 +700,8 @@ namespace OpenSim.Framework
700 700
701 RegionID = new UUID(regionUUID); 701 RegionID = new UUID(regionUUID);
702 originRegionID = RegionID; // What IS this?! 702 originRegionID = RegionID; // What IS this?!
703 703
704
705 // Region name
706 //
707 RegionName = name; 704 RegionName = name;
708
709
710 // Region location
711 //
712 string location = config.GetString("Location", String.Empty); 705 string location = config.GetString("Location", String.Empty);
713 706
714 if (location == String.Empty) 707 if (location == String.Empty)
@@ -724,12 +717,9 @@ namespace OpenSim.Framework
724 717
725 718
726 // Datastore (is this implemented? Omitted from example!) 719 // Datastore (is this implemented? Omitted from example!)
727 //
728 DataStore = config.GetString("Datastore", String.Empty); 720 DataStore = config.GetString("Datastore", String.Empty);
729 721
730
731 // Internal IP 722 // Internal IP
732 //
733 IPAddress address; 723 IPAddress address;
734 724
735 if (config.Contains("InternalAddress")) 725 if (config.Contains("InternalAddress"))
diff --git a/OpenSim/Framework/UntrustedWebRequest.cs b/OpenSim/Framework/UntrustedWebRequest.cs
new file mode 100644
index 0000000..1af7c41
--- /dev/null
+++ b/OpenSim/Framework/UntrustedWebRequest.cs
@@ -0,0 +1,203 @@
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Net;
5using System.Net.Security;
6using System.Text;
7using log4net;
8
9namespace OpenSim.Framework
10{
11 /// <summary>
12 /// Used for requests to untrusted endpoints that may potentially be
13 /// malicious
14 /// </summary>
15 public static class UntrustedHttpWebRequest
16 {
17 /// <summary>Setting this to true will allow HTTP connections to localhost</summary>
18 private const bool DEBUG = true;
19
20 private static readonly ILog m_log =
21 LogManager.GetLogger(
22 System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
23
24 private static readonly ICollection<string> allowableSchemes = new List<string> { "http", "https" };
25
26 /// <summary>
27 /// Creates an HttpWebRequest that is hardened against malicious
28 /// endpoints after ensuring the given Uri is safe to retrieve
29 /// </summary>
30 /// <param name="uri">Web location to request</param>
31 /// <returns>A hardened HttpWebRequest if the uri was determined to be safe</returns>
32 /// <exception cref="ArgumentNullException">If uri is null</exception>
33 /// <exception cref="ArgumentException">If uri is unsafe</exception>
34 public static HttpWebRequest Create(Uri uri)
35 {
36 return Create(uri, DEBUG, 1000 * 5, 1000 * 20, 10);
37 }
38
39 /// <summary>
40 /// Creates an HttpWebRequest that is hardened against malicious
41 /// endpoints after ensuring the given Uri is safe to retrieve
42 /// </summary>
43 /// <param name="uri">Web location to request</param>
44 /// <param name="allowLoopback">True to allow connections to localhost, otherwise false</param>
45 /// <param name="readWriteTimeoutMS">Read write timeout, in milliseconds</param>
46 /// <param name="timeoutMS">Connection timeout, in milliseconds</param>
47 /// <param name="maximumRedirects">Maximum number of allowed redirects</param>
48 /// <returns>A hardened HttpWebRequest if the uri was determined to be safe</returns>
49 /// <exception cref="ArgumentNullException">If uri is null</exception>
50 /// <exception cref="ArgumentException">If uri is unsafe</exception>
51 public static HttpWebRequest Create(Uri uri, bool allowLoopback, int readWriteTimeoutMS, int timeoutMS, int maximumRedirects)
52 {
53 if (uri == null)
54 throw new ArgumentNullException("uri");
55
56 if (!IsUriAllowable(uri, allowLoopback))
57 throw new ArgumentException("Uri " + uri + " was rejected");
58
59 HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(uri);
60 httpWebRequest.MaximumAutomaticRedirections = maximumRedirects;
61 httpWebRequest.ReadWriteTimeout = readWriteTimeoutMS;
62 httpWebRequest.Timeout = timeoutMS;
63 httpWebRequest.KeepAlive = false;
64
65 return httpWebRequest;
66 }
67
68 public static string PostToUntrustedUrl(Uri url, string data)
69 {
70 try
71 {
72 byte[] requestData = System.Text.Encoding.UTF8.GetBytes(data);
73
74 HttpWebRequest request = Create(url);
75 request.Method = "POST";
76 request.ContentLength = requestData.Length;
77 request.ContentType = "application/x-www-form-urlencoded";
78
79 using (Stream requestStream = request.GetRequestStream())
80 requestStream.Write(requestData, 0, requestData.Length);
81
82 using (WebResponse response = request.GetResponse())
83 {
84 using (Stream responseStream = response.GetResponseStream())
85 return responseStream.GetStreamString();
86 }
87 }
88 catch (Exception ex)
89 {
90 m_log.Warn("POST to untrusted URL " + url + " failed: " + ex.Message);
91 return null;
92 }
93 }
94
95 public static string GetUntrustedUrl(Uri url)
96 {
97 try
98 {
99 HttpWebRequest request = Create(url);
100
101 using (WebResponse response = request.GetResponse())
102 {
103 using (Stream responseStream = response.GetResponseStream())
104 return responseStream.GetStreamString();
105 }
106 }
107 catch (Exception ex)
108 {
109 m_log.Warn("GET from untrusted URL " + url + " failed: " + ex.Message);
110 return null;
111 }
112 }
113
114 /// <summary>
115 /// Determines whether a URI is allowed based on scheme and host name.
116 /// No requireSSL check is done here
117 /// </summary>
118 /// <param name="allowLoopback">True to allow loopback addresses to be used</param>
119 /// <param name="uri">The URI to test for whether it should be allowed.</param>
120 /// <returns>
121 /// <c>true</c> if [is URI allowable] [the specified URI]; otherwise, <c>false</c>.
122 /// </returns>
123 private static bool IsUriAllowable(Uri uri, bool allowLoopback)
124 {
125 if (!allowableSchemes.Contains(uri.Scheme))
126 {
127 m_log.WarnFormat("Rejecting URL {0} because it uses a disallowed scheme.", uri);
128 return false;
129 }
130
131 // Try to interpret the hostname as an IP address so we can test for internal
132 // IP address ranges. Note that IP addresses can appear in many forms
133 // (e.g. http://127.0.0.1, http://2130706433, http://0x0100007f, http://::1
134 // So we convert them to a canonical IPAddress instance, and test for all
135 // non-routable IP ranges: 10.*.*.*, 127.*.*.*, ::1
136 // Note that Uri.IsLoopback is very unreliable, not catching many of these variants.
137 IPAddress hostIPAddress;
138 if (IPAddress.TryParse(uri.DnsSafeHost, out hostIPAddress))
139 {
140 byte[] addressBytes = hostIPAddress.GetAddressBytes();
141
142 // The host is actually an IP address.
143 switch (hostIPAddress.AddressFamily)
144 {
145 case System.Net.Sockets.AddressFamily.InterNetwork:
146 if (!allowLoopback && (addressBytes[0] == 127 || addressBytes[0] == 10))
147 {
148 m_log.WarnFormat("Rejecting URL {0} because it is a loopback address.", uri);
149 return false;
150 }
151 break;
152 case System.Net.Sockets.AddressFamily.InterNetworkV6:
153 if (!allowLoopback && IsIPv6Loopback(hostIPAddress))
154 {
155 m_log.WarnFormat("Rejecting URL {0} because it is a loopback address.", uri);
156 return false;
157 }
158 break;
159 default:
160 m_log.WarnFormat("Rejecting URL {0} because it does not use an IPv4 or IPv6 address.", uri);
161 return false;
162 }
163 }
164 else
165 {
166 // The host is given by name. We require names to contain periods to
167 // help make sure it's not an internal address.
168 if (!allowLoopback && !uri.Host.Contains("."))
169 {
170 m_log.WarnFormat("Rejecting URL {0} because it does not contain a period in the host name.", uri);
171 return false;
172 }
173 }
174
175 return true;
176 }
177
178 /// <summary>
179 /// Determines whether an IP address is the IPv6 equivalent of "localhost/127.0.0.1".
180 /// </summary>
181 /// <param name="ip">The ip address to check.</param>
182 /// <returns>
183 /// <c>true</c> if this is a loopback IP address; <c>false</c> otherwise.
184 /// </returns>
185 private static bool IsIPv6Loopback(IPAddress ip)
186 {
187 if (ip == null)
188 throw new ArgumentNullException("ip");
189
190 byte[] addressBytes = ip.GetAddressBytes();
191 for (int i = 0; i < addressBytes.Length - 1; i++)
192 {
193 if (addressBytes[i] != 0)
194 return false;
195 }
196
197 if (addressBytes[addressBytes.Length - 1] != 1)
198 return false;
199
200 return true;
201 }
202 }
203}
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
new file mode 100644
index 0000000..d9782ff
--- /dev/null
+++ b/OpenSim/Framework/WebUtil.cs
@@ -0,0 +1,330 @@
1using System;
2using System.Collections.Generic;
3using System.Collections.Specialized;
4using System.IO;
5using System.Net;
6using System.Net.Security;
7using System.Reflection;
8using System.Text;
9using System.Web;
10using log4net;
11using OpenSim.Framework.Servers.HttpServer;
12using OpenMetaverse.StructuredData;
13
14namespace OpenSim.Framework
15{
16 /// <summary>
17 /// Miscellaneous static methods and extension methods related to the web
18 /// </summary>
19 public static class WebUtil
20 {
21 private static readonly ILog m_log =
22 LogManager.GetLogger(
23 MethodBase.GetCurrentMethod().DeclaringType);
24
25 /// <summary>
26 /// Send LLSD to an HTTP client in application/llsd+json form
27 /// </summary>
28 /// <param name="response">HTTP response to send the data in</param>
29 /// <param name="body">LLSD to send to the client</param>
30 public static void SendJSONResponse(OSHttpResponse response, OSDMap body)
31 {
32 byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body));
33
34 response.ContentEncoding = Encoding.UTF8;
35 response.ContentLength = responseData.Length;
36 response.ContentType = "application/llsd+json";
37 response.Body.Write(responseData, 0, responseData.Length);
38 }
39
40 /// <summary>
41 /// Send LLSD to an HTTP client in application/llsd+xml form
42 /// </summary>
43 /// <param name="response">HTTP response to send the data in</param>
44 /// <param name="body">LLSD to send to the client</param>
45 public static void SendXMLResponse(OSHttpResponse response, OSDMap body)
46 {
47 byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body);
48
49 response.ContentEncoding = Encoding.UTF8;
50 response.ContentLength = responseData.Length;
51 response.ContentType = "application/llsd+xml";
52 response.Body.Write(responseData, 0, responseData.Length);
53 }
54
55 /// <summary>
56 /// Make a GET or GET-like request to a web service that returns LLSD
57 /// or JSON data
58 /// </summary>
59 public static OSDMap ServiceRequest(string url, string httpVerb)
60 {
61 string errorMessage;
62
63 try
64 {
65 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
66 request.Method = httpVerb;
67
68 using (WebResponse response = request.GetResponse())
69 {
70 using (Stream responseStream = response.GetResponseStream())
71 {
72 try
73 {
74 string responseStr = responseStream.GetStreamString();
75 OSD responseOSD = OSDParser.Deserialize(responseStr);
76 if (responseOSD.Type == OSDType.Map)
77 return (OSDMap)responseOSD;
78 else
79 errorMessage = "Response format was invalid.";
80 }
81 catch
82 {
83 errorMessage = "Failed to parse the response.";
84 }
85 }
86 }
87 }
88 catch (Exception ex)
89 {
90 m_log.Warn("GET from URL " + url + " failed: " + ex.Message);
91 errorMessage = ex.Message;
92 }
93
94 return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } };
95 }
96
97 /// <summary>
98 /// POST URL-encoded form data to a web service that returns LLSD or
99 /// JSON data
100 /// </summary>
101 public static OSDMap PostToService(string url, NameValueCollection data)
102 {
103 string errorMessage;
104
105 try
106 {
107 string queryString = BuildQueryString(data);
108 byte[] requestData = System.Text.Encoding.UTF8.GetBytes(queryString);
109
110 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
111 request.Method = "POST";
112 request.ContentLength = requestData.Length;
113 request.ContentType = "application/x-www-form-urlencoded";
114
115 using (Stream requestStream = request.GetRequestStream())
116 requestStream.Write(requestData, 0, requestData.Length);
117
118 using (WebResponse response = request.GetResponse())
119 {
120 using (Stream responseStream = response.GetResponseStream())
121 {
122 try
123 {
124 string responseStr = responseStream.GetStreamString();
125 OSD responseOSD = OSDParser.Deserialize(responseStr);
126 if (responseOSD.Type == OSDType.Map)
127 return (OSDMap)responseOSD;
128 else
129 errorMessage = "Response format was invalid.";
130 }
131 catch
132 {
133 errorMessage = "Failed to parse the response.";
134 }
135 }
136 }
137 }
138 catch (Exception ex)
139 {
140 m_log.Warn("POST to URL " + url + " failed: " + ex.Message);
141 errorMessage = ex.Message;
142 }
143
144 return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } };
145 }
146
147 #region Uri
148
149 /// <summary>
150 /// Combines a Uri that can contain both a base Uri and relative path
151 /// with a second relative path fragment
152 /// </summary>
153 /// <param name="uri">Starting (base) Uri</param>
154 /// <param name="fragment">Relative path fragment to append to the end
155 /// of the Uri</param>
156 /// <returns>The combined Uri</returns>
157 /// <remarks>This is similar to the Uri constructor that takes a base
158 /// Uri and the relative path, except this method can append a relative
159 /// path fragment on to an existing relative path</remarks>
160 public static Uri Combine(this Uri uri, string fragment)
161 {
162 string fragment1 = uri.Fragment;
163 string fragment2 = fragment;
164
165 if (!fragment1.EndsWith("/"))
166 fragment1 = fragment1 + '/';
167 if (fragment2.StartsWith("/"))
168 fragment2 = fragment2.Substring(1);
169
170 return new Uri(uri, fragment1 + fragment2);
171 }
172
173 /// <summary>
174 /// Combines a Uri that can contain both a base Uri and relative path
175 /// with a second relative path fragment. If the fragment is absolute,
176 /// it will be returned without modification
177 /// </summary>
178 /// <param name="uri">Starting (base) Uri</param>
179 /// <param name="fragment">Relative path fragment to append to the end
180 /// of the Uri, or an absolute Uri to return unmodified</param>
181 /// <returns>The combined Uri</returns>
182 public static Uri Combine(this Uri uri, Uri fragment)
183 {
184 if (fragment.IsAbsoluteUri)
185 return fragment;
186
187 string fragment1 = uri.Fragment;
188 string fragment2 = fragment.ToString();
189
190 if (!fragment1.EndsWith("/"))
191 fragment1 = fragment1 + '/';
192 if (fragment2.StartsWith("/"))
193 fragment2 = fragment2.Substring(1);
194
195 return new Uri(uri, fragment1 + fragment2);
196 }
197
198 /// <summary>
199 /// Appends a query string to a Uri that may or may not have existing
200 /// query parameters
201 /// </summary>
202 /// <param name="uri">Uri to append the query to</param>
203 /// <param name="query">Query string to append. Can either start with ?
204 /// or just containg key/value pairs</param>
205 /// <returns>String representation of the Uri with the query string
206 /// appended</returns>
207 public static string AppendQuery(this Uri uri, string query)
208 {
209 if (String.IsNullOrEmpty(query))
210 return uri.ToString();
211
212 if (query[0] == '?' || query[0] == '&')
213 query = query.Substring(1);
214
215 string uriStr = uri.ToString();
216
217 if (uriStr.Contains("?"))
218 return uriStr + '&' + query;
219 else
220 return uriStr + '?' + query;
221 }
222
223 #endregion Uri
224
225 #region NameValueCollection
226
227 /// <summary>
228 /// Convert a NameValueCollection into a query string. This is the
229 /// inverse of HttpUtility.ParseQueryString()
230 /// </summary>
231 /// <param name="parameters">Collection of key/value pairs to convert</param>
232 /// <returns>A query string with URL-escaped values</returns>
233 public static string BuildQueryString(NameValueCollection parameters)
234 {
235 List<string> items = new List<string>(parameters.Count);
236
237 foreach (string key in parameters.Keys)
238 {
239 foreach (string value in parameters.GetValues(key))
240 items.Add(String.Concat(key, "=", HttpUtility.UrlEncode(value ?? String.Empty)));
241 }
242
243 return String.Join("&", items.ToArray());
244 }
245
246 /// <summary>
247 ///
248 /// </summary>
249 /// <param name="collection"></param>
250 /// <param name="key"></param>
251 /// <returns></returns>
252 public static string GetOne(this NameValueCollection collection, string key)
253 {
254 string[] values = collection.GetValues(key);
255 if (values != null && values.Length > 0)
256 return values[0];
257
258 return null;
259 }
260
261 #endregion NameValueCollection
262
263 #region Stream
264
265 /// <summary>
266 /// Copies the contents of one stream to another, starting at the
267 /// current position of each stream
268 /// </summary>
269 /// <param name="copyFrom">The stream to copy from, at the position
270 /// where copying should begin</param>
271 /// <param name="copyTo">The stream to copy to, at the position where
272 /// bytes should be written</param>
273 /// <param name="maximumBytesToCopy">The maximum bytes to copy</param>
274 /// <returns>The total number of bytes copied</returns>
275 /// <remarks>
276 /// Copying begins at the streams' current positions. The positions are
277 /// NOT reset after copying is complete.
278 /// </remarks>
279 public static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy)
280 {
281 byte[] buffer = new byte[4096];
282 int readBytes;
283 int totalCopiedBytes = 0;
284
285 while ((readBytes = copyFrom.Read(buffer, 0, Math.Min(4096, maximumBytesToCopy))) > 0)
286 {
287 int writeBytes = Math.Min(maximumBytesToCopy, readBytes);
288 copyTo.Write(buffer, 0, writeBytes);
289 totalCopiedBytes += writeBytes;
290 maximumBytesToCopy -= writeBytes;
291 }
292
293 return totalCopiedBytes;
294 }
295
296 /// <summary>
297 /// Converts an entire stream to a string, regardless of current stream
298 /// position
299 /// </summary>
300 /// <param name="stream">The stream to convert to a string</param>
301 /// <returns></returns>
302 /// <remarks>When this method is done, the stream position will be
303 /// reset to its previous position before this method was called</remarks>
304 public static string GetStreamString(this Stream stream)
305 {
306 string value = null;
307
308 if (stream != null && stream.CanRead)
309 {
310 long rewindPos = -1;
311
312 if (stream.CanSeek)
313 {
314 rewindPos = stream.Position;
315 stream.Seek(0, SeekOrigin.Begin);
316 }
317
318 StreamReader reader = new StreamReader(stream);
319 value = reader.ReadToEnd();
320
321 if (rewindPos >= 0)
322 stream.Seek(rewindPos, SeekOrigin.Begin);
323 }
324
325 return value;
326 }
327
328 #endregion Stream
329 }
330}
diff --git a/OpenSim/Framework/sLLVector3.cs b/OpenSim/Framework/sLLVector3.cs
deleted file mode 100644
index 49940c4..0000000
--- a/OpenSim/Framework/sLLVector3.cs
+++ /dev/null
@@ -1,51 +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 System;
29using OpenMetaverse;
30
31namespace OpenSim.Framework
32{
33 [Serializable]
34 public class sLLVector3
35 {
36 public float x = 0;
37 public float y = 0;
38 public float z = 0;
39
40 public sLLVector3()
41 {
42 }
43
44 public sLLVector3(Vector3 v)
45 {
46 x = v.X;
47 y = v.Y;
48 z = v.Z;
49 }
50 }
51} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 1696037..2c8d88b 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -97,6 +97,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
97 /// </summary> 97 /// </summary>
98 public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector 98 public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector
99 { 99 {
100 /// <value>
101 /// Debug packet level. At the moment, only 255 does anything (prints out all in and out packets).
102 /// </value>
103 protected int m_debugPacketLevel = 0;
104
100 #region Events 105 #region Events
101 106
102 public event GenericMessage OnGenericMessage; 107 public event GenericMessage OnGenericMessage;
@@ -472,6 +477,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
472 477
473 public void SetDebugPacketLevel(int newDebug) 478 public void SetDebugPacketLevel(int newDebug)
474 { 479 {
480 m_debugPacketLevel = newDebug;
475 } 481 }
476 482
477 #region Client Methods 483 #region Client Methods
@@ -10939,7 +10945,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10939 LLUDPServer.LogPacketHeader(false, m_circuitCode, 0, packet.Type, (ushort)packet.Length); 10945 LLUDPServer.LogPacketHeader(false, m_circuitCode, 0, packet.Type, (ushort)packet.Length);
10940 #endregion BinaryStats 10946 #endregion BinaryStats
10941 10947
10942 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); 10948 OutPacket(packet, throttlePacketType, true);
10943 } 10949 }
10944 10950
10945 /// <summary> 10951 /// <summary>
@@ -10952,6 +10958,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10952 /// handles splitting manually</param> 10958 /// handles splitting manually</param>
10953 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) 10959 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting)
10954 { 10960 {
10961 if (m_debugPacketLevel >= 255)
10962 m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type);
10963
10955 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); 10964 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting);
10956 } 10965 }
10957 10966
@@ -11023,10 +11032,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11023 /// <param name="Pack">OpenMetaverse.packet</param> 11032 /// <param name="Pack">OpenMetaverse.packet</param>
11024 public void ProcessInPacket(Packet Pack) 11033 public void ProcessInPacket(Packet Pack)
11025 { 11034 {
11026// m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack); 11035 if (m_debugPacketLevel >= 255)
11036 m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type);
11027 11037
11028 if (!ProcessPacketMethod(Pack)) 11038 if (!ProcessPacketMethod(Pack))
11029 m_log.Warn("[CLIENT]: unhandled packet " + Pack); 11039 m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type);
11030 11040
11031 PacketPool.Instance.ReturnPacket(Pack); 11041 PacketPool.Instance.ReturnPacket(Pack);
11032 } 11042 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index e0df288..0fc467b 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -411,6 +411,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
411 /// <summary> 411 /// <summary>
412 /// Rez an object into the scene from the user's inventory 412 /// Rez an object into the scene from the user's inventory
413 /// </summary> 413 /// </summary>
414 /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing
415 /// things to the scene. The caller should be doing that, I think.
414 /// <param name="remoteClient"></param> 416 /// <param name="remoteClient"></param>
415 /// <param name="itemID"></param> 417 /// <param name="itemID"></param>
416 /// <param name="RayEnd"></param> 418 /// <param name="RayEnd"></param>
@@ -500,13 +502,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
500 group.RootPart.IsAttachment = true; 502 group.RootPart.IsAttachment = true;
501 } 503 }
502 504
503 m_Scene.AddNewSceneObject(group, true); 505 // For attachments, we must make sure that only a single object update occurs after we've finished
506 // all the necessary operations.
507 m_Scene.AddNewSceneObject(group, true, false);
504 508
505 // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); 509 // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
506 // if attachment we set it's asset id so object updates can reflect that 510 // if attachment we set it's asset id so object updates can reflect that
507 // if not, we set it's position in world. 511 // if not, we set it's position in world.
508 if (!attachment) 512 if (!attachment)
509 { 513 {
514 group.ScheduleGroupForFullUpdate();
515
510 float offsetHeight = 0; 516 float offsetHeight = 0;
511 pos = m_Scene.GetNewRezLocation( 517 pos = m_Scene.GetNewRezLocation(
512 RayStart, RayEnd, RayTargetID, Quaternion.Identity, 518 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
@@ -562,6 +568,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
562 part.GroupMask = 0; // DO NOT propagate here 568 part.GroupMask = 0; // DO NOT propagate here
563 } 569 }
564 } 570 }
571
565 group.ApplyNextOwnerPermissions(); 572 group.ApplyNextOwnerPermissions();
566 } 573 }
567 } 574 }
@@ -569,7 +576,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
569 foreach (SceneObjectPart part in partList) 576 foreach (SceneObjectPart part in partList)
570 { 577 {
571 if (part.OwnerID != item.Owner) 578 if (part.OwnerID != item.Owner)
572 { 579 {
573 part.LastOwnerID = part.OwnerID; 580 part.LastOwnerID = part.OwnerID;
574 part.OwnerID = item.Owner; 581 part.OwnerID = item.Owner;
575 part.Inventory.ChangeInventoryOwner(item.Owner); 582 part.Inventory.ChangeInventoryOwner(item.Owner);
@@ -591,10 +598,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
591 { 598 {
592 group.ClearPartAttachmentData(); 599 group.ClearPartAttachmentData();
593 } 600 }
594 } 601
595
596 if (!attachment)
597 {
598 // Fire on_rez 602 // Fire on_rez
599 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0); 603 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0);
600 604
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index e458ecf..9cbaffc 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1846,9 +1846,18 @@ namespace OpenSim.Region.Framework.Scenes
1846 EventManager.TriggerOnAttach(localID, itemID, avatarID); 1846 EventManager.TriggerOnAttach(localID, itemID, avatarID);
1847 } 1847 }
1848 1848
1849 public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, 1849 /// <summary>
1850 uint AttachmentPt) 1850 /// Called when the client receives a request to rez a single attachment on to the avatar from inventory
1851 /// (RezSingleAttachmentFromInv packet).
1852 /// </summary>
1853 /// <param name="remoteClient"></param>
1854 /// <param name="itemID"></param>
1855 /// <param name="AttachmentPt"></param>
1856 /// <returns></returns>
1857 public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
1851 { 1858 {
1859 m_log.DebugFormat("[USER INVENTORY]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name);
1860
1852 SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt); 1861 SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt);
1853 1862
1854 if (att == null) 1863 if (att == null)
@@ -1860,9 +1869,20 @@ namespace OpenSim.Region.Framework.Scenes
1860 return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt); 1869 return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt);
1861 } 1870 }
1862 1871
1863 public UUID RezSingleAttachment(SceneObjectGroup att, 1872 /// <summary>
1864 IClientAPI remoteClient, UUID itemID, uint AttachmentPt) 1873 /// Update the user inventory to reflect an attachment
1874 /// </summary>
1875 /// <param name="att"></param>
1876 /// <param name="remoteClient"></param>
1877 /// <param name="itemID"></param>
1878 /// <param name="AttachmentPt"></param>
1879 /// <returns></returns>
1880 public UUID RezSingleAttachment(SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
1865 { 1881 {
1882 m_log.DebugFormat(
1883 "[USER INVENTORY]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
1884 remoteClient.Name, att.Name, itemID);
1885
1866 if (!att.IsDeleted) 1886 if (!att.IsDeleted)
1867 AttachmentPt = att.RootPart.AttachmentPoint; 1887 AttachmentPt = att.RootPart.AttachmentPoint;
1868 1888
@@ -1901,8 +1921,19 @@ namespace OpenSim.Region.Framework.Scenes
1901 return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent); 1921 return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
1902 } 1922 }
1903 1923
1924 /// <summary>
1925 /// This registers the item as attached in a user's inventory
1926 /// </summary>
1927 /// <param name="remoteClient"></param>
1928 /// <param name="AttachmentPt"></param>
1929 /// <param name="itemID"></param>
1930 /// <param name="att"></param>
1904 public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 1931 public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
1905 { 1932 {
1933// m_log.DebugFormat(
1934// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
1935// att.Name, remoteClient.Name, AttachmentPt, itemID);
1936
1906 if (UUID.Zero == itemID) 1937 if (UUID.Zero == itemID)
1907 { 1938 {
1908 m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error inventory item ID."); 1939 m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error inventory item ID.");
@@ -1930,10 +1961,7 @@ namespace OpenSim.Region.Framework.Scenes
1930 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); 1961 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */);
1931 1962
1932 if (m_AvatarFactory != null) 1963 if (m_AvatarFactory != null)
1933 {
1934 m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); 1964 m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
1935 }
1936
1937 } 1965 }
1938 } 1966 }
1939 1967
@@ -2016,6 +2044,7 @@ namespace OpenSim.Region.Framework.Scenes
2016 { 2044 {
2017 sog.SetOwnerId(ownerID); 2045 sog.SetOwnerId(ownerID);
2018 sog.SetGroup(groupID, remoteClient); 2046 sog.SetGroup(groupID, remoteClient);
2047 sog.ScheduleGroupForFullUpdate();
2019 2048
2020 foreach (SceneObjectPart child in sog.Children.Values) 2049 foreach (SceneObjectPart child in sog.Children.Values)
2021 child.Inventory.ChangeInventoryOwner(ownerID); 2050 child.Inventory.ChangeInventoryOwner(ownerID);
@@ -2037,6 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes
2037 sog.SetOwnerId(groupID); 2066 sog.SetOwnerId(groupID);
2038 sog.ApplyNextOwnerPermissions(); 2067 sog.ApplyNextOwnerPermissions();
2039 } 2068 }
2069
2040 } 2070 }
2041 2071
2042 foreach (uint localID in localIDs) 2072 foreach (uint localID in localIDs)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 181b7c5..a84f966 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1933,14 +1933,22 @@ namespace OpenSim.Region.Framework.Scenes
1933 //m_log.DebugFormat( 1933 //m_log.DebugFormat(
1934 // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName); 1934 // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);
1935 1935
1936 SceneObjectGroup sceneObject = null;
1937
1936 // If an entity creator has been registered for this prim type then use that 1938 // If an entity creator has been registered for this prim type then use that
1937 if (m_entityCreators.ContainsKey((PCode)shape.PCode)) 1939 if (m_entityCreators.ContainsKey((PCode)shape.PCode))
1938 return m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape); 1940 {
1941 sceneObject = m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape);
1942 }
1943 else
1944 {
1945 // Otherwise, use this default creation code;
1946 sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
1947 AddNewSceneObject(sceneObject, true);
1948 sceneObject.SetGroup(groupID, null);
1949 }
1939 1950
1940 // Otherwise, use this default creation code; 1951 sceneObject.ScheduleGroupForFullUpdate();
1941 SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
1942 AddNewSceneObject(sceneObject, true);
1943 sceneObject.SetGroup(groupID, null);
1944 1952
1945 return sceneObject; 1953 return sceneObject;
1946 } 1954 }
@@ -1968,7 +1976,7 @@ namespace OpenSim.Region.Framework.Scenes
1968 } 1976 }
1969 1977
1970 /// <summary> 1978 /// <summary>
1971 /// Add a newly created object to the scene 1979 /// Add a newly created object to the scene. Updates are also sent to viewers.
1972 /// </summary> 1980 /// </summary>
1973 /// <param name="sceneObject"></param> 1981 /// <param name="sceneObject"></param>
1974 /// <param name="attachToBackup"> 1982 /// <param name="attachToBackup">
@@ -1977,8 +1985,25 @@ namespace OpenSim.Region.Framework.Scenes
1977 /// </param> 1985 /// </param>
1978 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) 1986 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
1979 { 1987 {
1980 return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup); 1988 return AddNewSceneObject(sceneObject, attachToBackup, true);
1981 } 1989 }
1990
1991 /// <summary>
1992 /// Add a newly created object to the scene
1993 /// </summary>
1994 /// <param name="sceneObject"></param>
1995 /// <param name="attachToBackup">
1996 /// If true, the object is made persistent into the scene.
1997 /// If false, the object will not persist over server restarts
1998 /// </param>
1999 /// <param name="sendClientUpdates">
2000 /// If true, updates for the new scene object are sent to all viewers in range.
2001 /// If false, it is left to the caller to schedule the update
2002 /// </param>
2003 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
2004 {
2005 return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates);
2006 }
1982 2007
1983 /// <summary> 2008 /// <summary>
1984 /// Delete every object from the scene 2009 /// Delete every object from the scene
@@ -3170,7 +3195,6 @@ namespace OpenSim.Region.Framework.Scenes
3170 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3195 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3171 m_sceneGridService.KiPrimitive += SendKillObject; 3196 m_sceneGridService.KiPrimitive += SendKillObject;
3172 m_sceneGridService.OnGetLandData += GetLandData; 3197 m_sceneGridService.OnGetLandData += GetLandData;
3173
3174 } 3198 }
3175 3199
3176 /// <summary> 3200 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 8a74d7b..9d0e6f4 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -103,15 +103,15 @@ namespace OpenSim.Region.Framework.Scenes
103 /// </summary> 103 /// </summary>
104 public event GetLandData OnGetLandData; 104 public event GetLandData OnGetLandData;
105 105
106 private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion; 106// private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion;
107 private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser; 107// private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser;
108 private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection; 108// private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection;
109 private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; 109// private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion;
110 //private RegionUp handlerRegionUp = null; // OnRegionUp; 110 //private RegionUp handlerRegionUp = null; // OnRegionUp;
111 private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate; 111// private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate;
112 //private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar = null; // OnRemoveKnownRegionFromAvatar; 112 //private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar = null; // OnRemoveKnownRegionFromAvatar;
113 private LogOffUser handlerLogOffUser = null; 113// private LogOffUser handlerLogOffUser = null;
114 private GetLandData handlerGetLandData = null; // OnGetLandData 114// private GetLandData handlerGetLandData = null; // OnGetLandData
115 115
116 public KiPrimitiveDelegate KiPrimitive; 116 public KiPrimitiveDelegate KiPrimitive;
117 117
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 928dc97..cac768e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -253,7 +253,7 @@ namespace OpenSim.Region.Framework.Scenes
253 sceneObject.HasGroupChanged = true; 253 sceneObject.HasGroupChanged = true;
254 } 254 }
255 255
256 return AddSceneObject(sceneObject, attachToBackup); 256 return AddSceneObject(sceneObject, attachToBackup, true);
257 } 257 }
258 258
259 /// <summary> 259 /// <summary>
@@ -268,12 +268,12 @@ namespace OpenSim.Region.Framework.Scenes
268 /// <returns> 268 /// <returns>
269 /// true if the object was added, false if an object with the same uuid was already in the scene 269 /// true if the object was added, false if an object with the same uuid was already in the scene
270 /// </returns> 270 /// </returns>
271 protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) 271 protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
272 { 272 {
273 // Ensure that we persist this new scene object 273 // Ensure that we persist this new scene object
274 sceneObject.HasGroupChanged = true; 274 sceneObject.HasGroupChanged = true;
275 275
276 return AddSceneObject(sceneObject, attachToBackup); 276 return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
277 } 277 }
278 278
279 /// <summary> 279 /// <summary>
@@ -285,12 +285,19 @@ namespace OpenSim.Region.Framework.Scenes
285 /// If true, the object is made persistent into the scene. 285 /// If true, the object is made persistent into the scene.
286 /// If false, the object will not persist over server restarts 286 /// If false, the object will not persist over server restarts
287 /// </param> 287 /// </param>
288 /// <returns>true if the object was added, false if an object with the same uuid was already in the scene 288 /// <param name="sendClientUpdates">
289 /// If true, updates for the new scene object are sent to all viewers in range.
290 /// If false, it is left to the caller to schedule the update
291 /// </param>
292 /// <returns>
293 /// true if the object was added, false if an object with the same uuid was already in the scene
289 /// </returns> 294 /// </returns>
290 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) 295 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
291 { 296 {
292 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) 297 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
293 return false; 298 return false;
299
300 bool alreadyExisted = false;
294 301
295 if (m_parentScene.m_clampPrimSize) 302 if (m_parentScene.m_clampPrimSize)
296 { 303 {
@@ -311,6 +318,9 @@ namespace OpenSim.Region.Framework.Scenes
311 318
312 sceneObject.AttachToScene(m_parentScene); 319 sceneObject.AttachToScene(m_parentScene);
313 320
321 if (sendClientUpdates)
322 sceneObject.ScheduleGroupForFullUpdate();
323
314 lock (sceneObject) 324 lock (sceneObject)
315 { 325 {
316 if (!Entities.ContainsKey(sceneObject.UUID)) 326 if (!Entities.ContainsKey(sceneObject.UUID))
@@ -334,12 +344,14 @@ namespace OpenSim.Region.Framework.Scenes
334 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; 344 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
335 } 345 }
336 } 346 }
337 347 }
338 return true; 348 else
349 {
350 alreadyExisted = true;
339 } 351 }
340 } 352 }
341 353
342 return false; 354 return alreadyExisted;
343 } 355 }
344 356
345 /// <summary> 357 /// <summary>
@@ -549,7 +561,10 @@ namespace OpenSim.Region.Framework.Scenes
549 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, 561 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
550 false, false, remoteClient.AgentId, true); 562 false, false, remoteClient.AgentId, true);
551 563
552 564// m_log.DebugFormat(
565// "[SCENE GRAPH]: Retrieved single object {0} for attachment to {1} on point {2}",
566// objatt.Name, remoteClient.Name, AttachmentPt);
567
553 if (objatt != null) 568 if (objatt != null)
554 { 569 {
555 bool tainted = false; 570 bool tainted = false;
@@ -557,16 +572,27 @@ namespace OpenSim.Region.Framework.Scenes
557 tainted = true; 572 tainted = true;
558 573
559 AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); 574 AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
560 objatt.ScheduleGroupForFullUpdate(); 575 //objatt.ScheduleGroupForFullUpdate();
561 if (tainted) 576 if (tainted)
562 objatt.HasGroupChanged = true; 577 objatt.HasGroupChanged = true;
563 578
564 // Fire after attach, so we don't get messy perms dialogs 579 // Fire after attach, so we don't get messy perms dialogs
565 // 3 == AttachedRez 580 // 3 == AttachedRez
566 objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); 581 objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3);
582
583 // Do this last so that event listeners have access to all the effects of the attachment
584 m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId);
567 } 585 }
586 else
587 {
588 m_log.WarnFormat(
589 "[SCENE GRAPH]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
590 itemID, remoteClient.Name, AttachmentPt);
591 }
592
568 return objatt; 593 return objatt;
569 } 594 }
595
570 return null; 596 return null;
571 } 597 }
572 598
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index 6395d98..680c39a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -422,7 +422,7 @@ namespace OpenSim.Region.Framework.Scenes
422 422
423 if (!scenePresence.IsChildAgent) 423 if (!scenePresence.IsChildAgent)
424 { 424 {
425 m_log.ErrorFormat("Packet debug for {0} {1} set to {2}", 425 m_log.DebugFormat("Packet debug for {0} {1} set to {2}",
426 scenePresence.Firstname, 426 scenePresence.Firstname,
427 scenePresence.Lastname, 427 scenePresence.Lastname,
428 newDebug); 428 newDebug);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 2a4e5a2..8c5a9a6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -488,8 +488,8 @@ namespace OpenSim.Region.Framework.Scenes
488 private List<SceneObjectPart> m_PlaySoundSlavePrims = new List<SceneObjectPart>(); 488 private List<SceneObjectPart> m_PlaySoundSlavePrims = new List<SceneObjectPart>();
489 public List<SceneObjectPart> PlaySoundSlavePrims 489 public List<SceneObjectPart> PlaySoundSlavePrims
490 { 490 {
491 get { return m_LoopSoundSlavePrims; } 491 get { return m_PlaySoundSlavePrims; }
492 set { m_LoopSoundSlavePrims = value; } 492 set { m_PlaySoundSlavePrims = value; }
493 } 493 }
494 494
495 private SceneObjectPart m_LoopSoundMasterPrim = null; 495 private SceneObjectPart m_LoopSoundMasterPrim = null;
@@ -641,8 +641,10 @@ namespace OpenSim.Region.Framework.Scenes
641 } 641 }
642 642
643 ApplyPhysics(m_scene.m_physicalPrim); 643 ApplyPhysics(m_scene.m_physicalPrim);
644 644
645 ScheduleGroupForFullUpdate(); 645 // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
646 // for the same object with very different properties. The caller must schedule the update.
647 //ScheduleGroupForFullUpdate();
646 } 648 }
647 649
648 public Vector3 GroupScale() 650 public Vector3 GroupScale()
@@ -1044,10 +1046,11 @@ namespace OpenSim.Region.Framework.Scenes
1044 // don't attach attachments to child agents 1046 // don't attach attachments to child agents
1045 if (avatar.IsChildAgent) return; 1047 if (avatar.IsChildAgent) return;
1046 1048
1049// m_log.DebugFormat("[SOG]: Adding attachment {0} to avatar {1}", Name, avatar.Name);
1050
1047 DetachFromBackup(); 1051 DetachFromBackup();
1048 1052
1049 // Remove from database and parcel prim count 1053 // Remove from database and parcel prim count
1050 //
1051 m_scene.DeleteFromStorage(UUID); 1054 m_scene.DeleteFromStorage(UUID);
1052 m_scene.EventManager.TriggerParcelPrimCountTainted(); 1055 m_scene.EventManager.TriggerParcelPrimCountTainted();
1053 1056
@@ -1073,7 +1076,6 @@ namespace OpenSim.Region.Framework.Scenes
1073 SetAttachmentPoint(Convert.ToByte(attachmentpoint)); 1076 SetAttachmentPoint(Convert.ToByte(attachmentpoint));
1074 1077
1075 avatar.AddAttachment(this); 1078 avatar.AddAttachment(this);
1076 m_log.Debug("[SOG]: Added attachment " + UUID + " to avatar " + avatar.UUID);
1077 1079
1078 if (!silent) 1080 if (!silent)
1079 { 1081 {
@@ -1090,6 +1092,12 @@ namespace OpenSim.Region.Framework.Scenes
1090 ScheduleGroupForFullUpdate(); 1092 ScheduleGroupForFullUpdate();
1091 } 1093 }
1092 } 1094 }
1095 else
1096 {
1097 m_log.WarnFormat(
1098 "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present",
1099 UUID, agentID, Scene.RegionInfo.RegionName);
1100 }
1093 } 1101 }
1094 1102
1095 public byte GetAttachmentPoint() 1103 public byte GetAttachmentPoint()
@@ -1596,11 +1604,10 @@ namespace OpenSim.Region.Framework.Scenes
1596 1604
1597 #endregion 1605 #endregion
1598 1606
1599 #region Client Updating
1600
1601 public void SendFullUpdateToClient(IClientAPI remoteClient) 1607 public void SendFullUpdateToClient(IClientAPI remoteClient)
1602 { 1608 {
1603 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1609 RootPart.SendFullUpdate(
1610 remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1604 1611
1605 lockPartsForRead(true); 1612 lockPartsForRead(true);
1606 { 1613 {
@@ -1608,42 +1615,12 @@ namespace OpenSim.Region.Framework.Scenes
1608 { 1615 {
1609 1616
1610 if (part != RootPart) 1617 if (part != RootPart)
1611 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1618 part.SendFullUpdate(
1612 1619 remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1613 } 1620 }
1614 } 1621 }
1615 lockPartsForRead(false);
1616 } 1622 }
1617 1623
1618 /// <summary>
1619 /// Send a full update to the client for the given part
1620 /// </summary>
1621 /// <param name="remoteClient"></param>
1622 /// <param name="part"></param>
1623 internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags)
1624 {
1625// m_log.DebugFormat(
1626// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId);
1627
1628 if (m_rootPart.UUID == part.UUID)
1629 {
1630 if (IsAttachment)
1631 {
1632 part.SendFullUpdateToClient(remoteClient, m_rootPart.AttachedPos, clientFlags);
1633 }
1634 else
1635 {
1636 part.SendFullUpdateToClient(remoteClient, AbsolutePosition, clientFlags);
1637 }
1638 }
1639 else
1640 {
1641 part.SendFullUpdateToClient(remoteClient, clientFlags);
1642 }
1643 }
1644
1645 #endregion
1646
1647 #region Copying 1624 #region Copying
1648 1625
1649 /// <summary> 1626 /// <summary>
@@ -2108,6 +2085,8 @@ namespace OpenSim.Region.Framework.Scenes
2108 2085
2109 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2086 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
2110 { 2087 {
2088// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name);
2089
2111 RootPart.AddFullUpdateToAvatar(presence); 2090 RootPart.AddFullUpdateToAvatar(presence);
2112 2091
2113 lockPartsForRead(true); 2092 lockPartsForRead(true);
@@ -2126,14 +2105,12 @@ namespace OpenSim.Region.Framework.Scenes
2126 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2105 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
2127 { 2106 {
2128 lockPartsForRead(true); 2107 lockPartsForRead(true);
2108
2109 foreach (SceneObjectPart part in m_parts.Values)
2129 { 2110 {
2130 foreach (SceneObjectPart part in m_parts.Values) 2111 part.AddTerseUpdateToAvatar(presence);
2131 {
2132
2133 part.AddTerseUpdateToAvatar(presence);
2134
2135 }
2136 } 2112 }
2113
2137 lockPartsForRead(false); 2114 lockPartsForRead(false);
2138 } 2115 }
2139 2116
@@ -2142,6 +2119,8 @@ namespace OpenSim.Region.Framework.Scenes
2142 /// </summary> 2119 /// </summary>
2143 public void ScheduleGroupForFullUpdate() 2120 public void ScheduleGroupForFullUpdate()
2144 { 2121 {
2122// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID);
2123
2145 checkAtTargets(); 2124 checkAtTargets();
2146 RootPart.ScheduleFullUpdate(); 2125 RootPart.ScheduleFullUpdate();
2147 2126
@@ -2164,14 +2143,12 @@ namespace OpenSim.Region.Framework.Scenes
2164 public void ScheduleGroupForTerseUpdate() 2143 public void ScheduleGroupForTerseUpdate()
2165 { 2144 {
2166 lockPartsForRead(true); 2145 lockPartsForRead(true);
2146
2147 foreach (SceneObjectPart part in m_parts.Values)
2167 { 2148 {
2168 foreach (SceneObjectPart part in m_parts.Values) 2149 part.ScheduleTerseUpdate();
2169 {
2170
2171 part.ScheduleTerseUpdate();
2172
2173 }
2174 } 2150 }
2151
2175 lockPartsForRead(false); 2152 lockPartsForRead(false);
2176 } 2153 }
2177 2154
@@ -2179,9 +2156,11 @@ namespace OpenSim.Region.Framework.Scenes
2179 /// Immediately send a full update for this scene object. 2156 /// Immediately send a full update for this scene object.
2180 /// </summary> 2157 /// </summary>
2181 public void SendGroupFullUpdate() 2158 public void SendGroupFullUpdate()
2182 { 2159 {
2183 if (IsDeleted) 2160 if (IsDeleted)
2184 return; 2161 return;
2162
2163// m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID);
2185 2164
2186 RootPart.SendFullUpdateToAllClients(); 2165 RootPart.SendFullUpdateToAllClients();
2187 2166
@@ -2201,7 +2180,7 @@ namespace OpenSim.Region.Framework.Scenes
2201 /// <summary> 2180 /// <summary>
2202 /// Immediately send an update for this scene object's root prim only. 2181 /// Immediately send an update for this scene object's root prim only.
2203 /// This is for updates regarding the object as a whole, and none of its parts in particular. 2182 /// This is for updates regarding the object as a whole, and none of its parts in particular.
2204 /// Note: this may not be cused by opensim (it probably should) but it's used by 2183 /// Note: this may not be used by opensim (it probably should) but it's used by
2205 /// external modules. 2184 /// external modules.
2206 /// </summary> 2185 /// </summary>
2207 public void SendGroupRootTerseUpdate() 2186 public void SendGroupRootTerseUpdate()
@@ -2216,6 +2195,7 @@ namespace OpenSim.Region.Framework.Scenes
2216 { 2195 {
2217 if (m_scene == null) // Need to check here as it's null during object creation 2196 if (m_scene == null) // Need to check here as it's null during object creation
2218 return; 2197 return;
2198
2219 m_scene.SceneGraph.AddToUpdateList(this); 2199 m_scene.SceneGraph.AddToUpdateList(this);
2220 } 2200 }
2221 2201
@@ -3718,7 +3698,10 @@ namespace OpenSim.Region.Framework.Scenes
3718 HasGroupChanged = true; 3698 HasGroupChanged = true;
3719 } 3699 }
3720 lockPartsForRead(false); 3700 lockPartsForRead(false);
3721 ScheduleGroupForFullUpdate(); 3701
3702 // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled
3703 // for the same object with very different properties. The caller must schedule the update.
3704 //ScheduleGroupForFullUpdate();
3722 } 3705 }
3723 3706
3724 public void TriggerScriptChangedEvent(Changed val) 3707 public void TriggerScriptChangedEvent(Changed val)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 57635f5..badf782 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -573,8 +573,8 @@ namespace OpenSim.Region.Framework.Scenes
573 private List<SceneObjectPart> m_PlaySoundSlavePrims = new List<SceneObjectPart>(); 573 private List<SceneObjectPart> m_PlaySoundSlavePrims = new List<SceneObjectPart>();
574 public List<SceneObjectPart> PlaySoundSlavePrims 574 public List<SceneObjectPart> PlaySoundSlavePrims
575 { 575 {
576 get { return m_LoopSoundSlavePrims; } 576 get { return m_PlaySoundSlavePrims; }
577 set { m_LoopSoundSlavePrims = value; } 577 set { m_PlaySoundSlavePrims = value; }
578 } 578 }
579 579
580 private SceneObjectPart m_LoopSoundMasterPrim = null; 580 private SceneObjectPart m_LoopSoundMasterPrim = null;
@@ -2842,29 +2842,59 @@ namespace OpenSim.Region.Framework.Scenes
2842 } 2842 }
2843 } 2843 }
2844 2844
2845// /// <summary>
2846// ///
2847// /// </summary>
2848// /// <param name="remoteClient"></param>
2849// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
2850// {
2851// m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags);
2852// }
2853
2854
2845 /// <summary> 2855 /// <summary>
2846 /// 2856 /// Send a full update to the client for the given part
2847 /// </summary> 2857 /// </summary>
2848 /// <param name="remoteClient"></param> 2858 /// <param name="remoteClient"></param>
2849 public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) 2859 /// <param name="clientFlags"></param>
2860 protected internal void SendFullUpdate(IClientAPI remoteClient, uint clientFlags)
2850 { 2861 {
2851 m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); 2862// m_log.DebugFormat(
2852 } 2863// "[SOG]: Sendinging part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId);
2864
2865 if (IsRoot)
2866 {
2867 if (IsAttachment)
2868 {
2869 SendFullUpdateToClient(remoteClient, AttachedPos, clientFlags);
2870 }
2871 else
2872 {
2873 SendFullUpdateToClient(remoteClient, AbsolutePosition, clientFlags);
2874 }
2875 }
2876 else
2877 {
2878 SendFullUpdateToClient(remoteClient, clientFlags);
2879 }
2880 }
2853 2881
2854 /// <summary> 2882 /// <summary>
2855 /// 2883 /// Send a full update for this part to all clients.
2856 /// </summary> 2884 /// </summary>
2857 public void SendFullUpdateToAllClients() 2885 public void SendFullUpdateToAllClients()
2858 { 2886 {
2859 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 2887 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
2860 for (int i = 0; i < avatars.Length; i++) 2888 for (int i = 0; i < avatars.Length; i++)
2861 { 2889 {
2862 // Ugly reference :( 2890 SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID));
2863 m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this,
2864 avatars[i].GenerateClientFlags(UUID));
2865 } 2891 }
2866 } 2892 }
2867 2893
2894 /// <summary>
2895 /// Send a full update to all clients except the one nominated.
2896 /// </summary>
2897 /// <param name="agentID"></param>
2868 public void SendFullUpdateToAllClientsExcept(UUID agentID) 2898 public void SendFullUpdateToAllClientsExcept(UUID agentID)
2869 { 2899 {
2870 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); 2900 ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences();
@@ -2872,10 +2902,7 @@ namespace OpenSim.Region.Framework.Scenes
2872 { 2902 {
2873 // Ugly reference :( 2903 // Ugly reference :(
2874 if (avatars[i].UUID != agentID) 2904 if (avatars[i].UUID != agentID)
2875 { 2905 SendFullUpdate(avatars[i].ControllingClient, avatars[i].GenerateClientFlags(UUID));
2876 m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this,
2877 avatars[i].GenerateClientFlags(UUID));
2878 }
2879 } 2906 }
2880 } 2907 }
2881 2908
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 453523a..9dbe332 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -875,40 +875,15 @@ namespace OpenSim.Region.Framework.Scenes
875 } 875 }
876 } 876 }
877 877
878 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) 878 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
879 { 879 {
880 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
881
882 if (pos.X < 0)
883 {
884 emergencyPos.X = (int)Constants.RegionSize + pos.X;
885 if (!(pos.Y < 0))
886 emergencyPos.Y = pos.Y;
887 if (!(pos.Z < 0))
888 emergencyPos.X = pos.X;
889 }
890 if (pos.Y < 0)
891 {
892 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
893 if (!(pos.X < 0))
894 emergencyPos.X = pos.X;
895 if (!(pos.Z < 0))
896 emergencyPos.Z = pos.Z;
897 }
898 if (pos.Z < 0)
899 {
900 if (!(pos.X < 0))
901 emergencyPos.X = pos.X;
902 if (!(pos.Y < 0))
903 emergencyPos.Y = pos.Y;
904 //Leave as 128
905 }
906
907 m_log.WarnFormat( 880 m_log.WarnFormat(
908 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", 881 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
909 pos, Name, UUID, emergencyPos); 882 pos, Name, UUID);
910 883
911 pos = emergencyPos; 884 if (pos.X < 0f) pos.X = 0f;
885 if (pos.Y < 0f) pos.Y = 0f;
886 if (pos.Z < 0f) pos.Z = 0f;
912 } 887 }
913 888
914 float localAVHeight = 1.56f; 889 float localAVHeight = 1.56f;
@@ -919,7 +894,7 @@ namespace OpenSim.Region.Framework.Scenes
919 894
920 float posZLimit = 0; 895 float posZLimit = 0;
921 896
922 if (pos.X <Constants.RegionSize && pos.Y < Constants.RegionSize) 897 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
923 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 898 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
924 899
925 float newPosZ = posZLimit + localAVHeight / 2; 900 float newPosZ = posZLimit + localAVHeight / 2;
@@ -2881,7 +2856,12 @@ namespace OpenSim.Region.Framework.Scenes
2881 /// </summary> 2856 /// </summary>
2882 protected void CheckForSignificantMovement() 2857 protected void CheckForSignificantMovement()
2883 { 2858 {
2884 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > 0.5) 2859 // Movement updates for agents in neighboring regions are sent directly to clients.
2860 // This value only affects how often agent positions are sent to neighbor regions
2861 // for things such as distance-based update prioritization
2862 const float SIGNIFICANT_MOVEMENT = 2.0f;
2863
2864 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT)
2885 { 2865 {
2886 posLastSignificantMove = AbsolutePosition; 2866 posLastSignificantMove = AbsolutePosition;
2887 m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); 2867 m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient);
@@ -2897,13 +2877,13 @@ namespace OpenSim.Region.Framework.Scenes
2897 cadu.AgentID = UUID.Guid; 2877 cadu.AgentID = UUID.Guid;
2898 cadu.alwaysrun = m_setAlwaysRun; 2878 cadu.alwaysrun = m_setAlwaysRun;
2899 cadu.AVHeight = m_avHeight; 2879 cadu.AVHeight = m_avHeight;
2900 sLLVector3 tempCameraCenter = new sLLVector3(new Vector3(m_CameraCenter.X, m_CameraCenter.Y, m_CameraCenter.Z)); 2880 Vector3 tempCameraCenter = m_CameraCenter;
2901 cadu.cameraPosition = tempCameraCenter; 2881 cadu.cameraPosition = tempCameraCenter;
2902 cadu.drawdistance = m_DrawDistance; 2882 cadu.drawdistance = m_DrawDistance;
2903 if (m_scene.Permissions.IsGod(new UUID(cadu.AgentID))) 2883 if (m_scene.Permissions.IsGod(new UUID(cadu.AgentID)))
2904 cadu.godlevel = m_godlevel; 2884 cadu.godlevel = m_godlevel;
2905 cadu.GroupAccess = 0; 2885 cadu.GroupAccess = 0;
2906 cadu.Position = new sLLVector3(AbsolutePosition); 2886 cadu.Position = AbsolutePosition;
2907 cadu.regionHandle = m_rootRegionHandle; 2887 cadu.regionHandle = m_rootRegionHandle;
2908 float multiplier = 1; 2888 float multiplier = 1;
2909 int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); 2889 int innacurateNeighbors = m_scene.GetInaccurateNeighborCount();
@@ -2918,7 +2898,7 @@ namespace OpenSim.Region.Framework.Scenes
2918 2898
2919 //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); 2899 //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString());
2920 cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); 2900 cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier);
2921 cadu.Velocity = new sLLVector3(Velocity); 2901 cadu.Velocity = Velocity;
2922 2902
2923 AgentPosition agentpos = new AgentPosition(); 2903 AgentPosition agentpos = new AgentPosition();
2924 agentpos.CopyFrom(cadu); 2904 agentpos.CopyFrom(cadu);
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index e87b1f4..1ea52c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -416,7 +416,6 @@ namespace OpenSim.Region.ScriptEngine.Shared
416 416
417 public list(params object[] args) 417 public list(params object[] args)
418 { 418 {
419 m_data = new object[args.Length];
420 m_data = args; 419 m_data = args;
421 } 420 }
422 421
diff --git a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs
index 021dcf3..2fc9248 100644
--- a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs
+++ b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs
@@ -47,9 +47,9 @@ namespace OpenSim.Services.AuthenticationService
47 public class PasswordAuthenticationService : 47 public class PasswordAuthenticationService :
48 AuthenticationServiceBase, IAuthenticationService 48 AuthenticationServiceBase, IAuthenticationService
49 { 49 {
50 //private static readonly ILog m_log = 50 private static readonly ILog m_log =
51 // LogManager.GetLogger( 51 LogManager.GetLogger(
52 // MethodBase.GetCurrentMethod().DeclaringType); 52 MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 public PasswordAuthenticationService(IConfigSource config) : 54 public PasswordAuthenticationService(IConfigSource config) :
55 base(config) 55 base(config)
@@ -59,23 +59,27 @@ namespace OpenSim.Services.AuthenticationService
59 public string Authenticate(UUID principalID, string password, int lifetime) 59 public string Authenticate(UUID principalID, string password, int lifetime)
60 { 60 {
61 AuthenticationData data = m_Database.Get(principalID); 61 AuthenticationData data = m_Database.Get(principalID);
62 62
63 if (!data.Data.ContainsKey("passwordHash") || 63 if (data != null && data.Data != null)
64 !data.Data.ContainsKey("passwordSalt"))
65 { 64 {
66 return String.Empty; 65 if (!data.Data.ContainsKey("passwordHash") ||
67 } 66 !data.Data.ContainsKey("passwordSalt"))
67 {
68 return String.Empty;
69 }
68 70
69 string hashed = Util.Md5Hash(password + ":" + 71 string hashed = Util.Md5Hash(password + ":" +
70 data.Data["passwordSalt"].ToString()); 72 data.Data["passwordSalt"].ToString());
71 73
72 //m_log.DebugFormat("[PASS AUTH]: got {0}; hashed = {1}; stored = {2}", password, hashed, data.Data["passwordHash"].ToString()); 74 //m_log.DebugFormat("[PASS AUTH]: got {0}; hashed = {1}; stored = {2}", password, hashed, data.Data["passwordHash"].ToString());
73 75
74 if (data.Data["passwordHash"].ToString() == hashed) 76 if (data.Data["passwordHash"].ToString() == hashed)
75 { 77 {
76 return GetToken(principalID, lifetime); 78 return GetToken(principalID, lifetime);
79 }
77 } 80 }
78 81
82 m_log.DebugFormat("[AUTH SERVICE]: PrincipalID {0} or its data not found", principalID);
79 return String.Empty; 83 return String.Empty;
80 } 84 }
81 } 85 }
diff --git a/OpenSim/Services/Base/ServiceBase.cs b/OpenSim/Services/Base/ServiceBase.cs
index 8e24d85..91d5c56 100644
--- a/OpenSim/Services/Base/ServiceBase.cs
+++ b/OpenSim/Services/Base/ServiceBase.cs
@@ -26,7 +26,9 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
31using log4net;
30using Nini.Config; 32using Nini.Config;
31using OpenSim.Services.Interfaces; 33using OpenSim.Services.Interfaces;
32 34
@@ -34,6 +36,8 @@ namespace OpenSim.Services.Base
34{ 36{
35 public class ServiceBase 37 public class ServiceBase
36 { 38 {
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40
37 public T LoadPlugin<T>(string dllName) where T:class 41 public T LoadPlugin<T>(string dllName) where T:class
38 { 42 {
39 return LoadPlugin<T>(dllName, new Object[0]); 43 return LoadPlugin<T>(dllName, new Object[0]);
@@ -61,8 +65,12 @@ namespace OpenSim.Services.Base
61 { 65 {
62 Assembly pluginAssembly = Assembly.LoadFrom(dllName); 66 Assembly pluginAssembly = Assembly.LoadFrom(dllName);
63 67
68// m_log.DebugFormat("[SERVICE BASE]: Found assembly {0}", dllName);
69
64 foreach (Type pluginType in pluginAssembly.GetTypes()) 70 foreach (Type pluginType in pluginAssembly.GetTypes())
65 { 71 {
72// m_log.DebugFormat("[SERVICE BASE]: Found type {0}", pluginType);
73
66 if (pluginType.IsPublic) 74 if (pluginType.IsPublic)
67 { 75 {
68 if (className != String.Empty && 76 if (className != String.Empty &&
@@ -86,7 +94,15 @@ namespace OpenSim.Services.Base
86 } 94 }
87 catch (Exception e) 95 catch (Exception e)
88 { 96 {
89 Console.WriteLine("XXX Exception " + e.StackTrace); 97 List<string> strArgs = new List<string>();
98 foreach (Object arg in args)
99 strArgs.Add(arg.ToString());
100
101 m_log.Error(
102 string.Format(
103 "[SERVICE BASE]: Failed to load plugin {0} from {1} with args {2}",
104 interfaceName, dllName, string.Join(", ", strArgs.ToArray())), e);
105
90 return null; 106 return null;
91 } 107 }
92 } 108 }
@@ -95,4 +111,4 @@ namespace OpenSim.Services.Base
95 { 111 {
96 } 112 }
97 } 113 }
98} 114} \ No newline at end of file
diff --git a/OpenSim/Services/Friends/FriendsServiceBase.cs b/OpenSim/Services/Friends/FriendsServiceBase.cs
index 9858972..6ab0bff 100644
--- a/OpenSim/Services/Friends/FriendsServiceBase.cs
+++ b/OpenSim/Services/Friends/FriendsServiceBase.cs
@@ -27,13 +27,12 @@
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using log4net;
30using Nini.Config; 31using Nini.Config;
31using OpenSim.Framework; 32using OpenSim.Framework;
32using OpenSim.Data; 33using OpenSim.Data;
33using OpenSim.Services.Interfaces; 34using OpenSim.Services.Interfaces;
34using OpenSim.Services.Base; 35using OpenSim.Services.Base;
35using Nini.Config;
36using log4net;
37 36
38namespace OpenSim.Services.Friends 37namespace OpenSim.Services.Friends
39{ 38{
@@ -80,7 +79,11 @@ namespace OpenSim.Services.Friends
80 79
81 m_Database = LoadPlugin<IFriendsData>(dllName, new Object[] { connString, realm }); 80 m_Database = LoadPlugin<IFriendsData>(dllName, new Object[] { connString, realm });
82 if (m_Database == null) 81 if (m_Database == null)
83 throw new Exception("Could not find a storage interface in the given module"); 82 {
83 throw new Exception(
84 string.Format(
85 "Could not find a storage interface {0} in the given StorageProvider {1}", "IFriendsData", dllName));
86 }
84 } 87 }
85 } 88 }
86} 89}
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index 1d734eb..ee93f73 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -247,6 +247,7 @@ namespace OpenSim.Services.LLLoginService
247 LLLoginResponse response = new LLLoginResponse(account, aCircuit, presence, destination, inventorySkel, friendsList, m_LibraryService, 247 LLLoginResponse response = new LLLoginResponse(account, aCircuit, presence, destination, inventorySkel, friendsList, m_LibraryService,
248 where, startLocation, position, lookAt, m_WelcomeMessage, home, clientIP); 248 where, startLocation, position, lookAt, m_WelcomeMessage, home, clientIP);
249 249
250 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client.");
250 return response; 251 return response;
251 } 252 }
252 catch (Exception e) 253 catch (Exception e)
diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs
index e498bd5..ca6e44a 100644
--- a/OpenSim/Services/UserAccountService/UserAccountService.cs
+++ b/OpenSim/Services/UserAccountService/UserAccountService.cs
@@ -280,6 +280,15 @@ namespace OpenSim.Services.UserAccountService
280 if (null == account) 280 if (null == account)
281 { 281 {
282 account = new UserAccount(UUID.Zero, firstName, lastName, email); 282 account = new UserAccount(UUID.Zero, firstName, lastName, email);
283 if (account.ServiceURLs == null)
284 {
285 account.ServiceURLs = new Dictionary<string, object>();
286 account.ServiceURLs["HomeURI"] = string.Empty;
287 account.ServiceURLs["GatekeeperURI"] = string.Empty;
288 account.ServiceURLs["InventoryServerURI"] = string.Empty;
289 account.ServiceURLs["AssetServerURI"] = string.Empty;
290 }
291
283 if (StoreUserAccount(account)) 292 if (StoreUserAccount(account))
284 { 293 {
285 bool success = false; 294 bool success = false;