aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2010-03-03 22:48:41 +0000
committerJustin Clark-Casey (justincc)2010-03-03 22:48:41 +0000
commita0b22a9adc428e27dce86a2bf18ec66f5cee3b3c (patch)
treefd0a1e23d79624f9c17cde1aed59ac454af1fcff /OpenSim
parentreset the accidental local configuration changes (diff)
parent* Added three new helper utility files to OpenSim.Framework. MultipartForm is... (diff)
downloadopensim-SC-a0b22a9adc428e27dce86a2bf18ec66f5cee3b3c.zip
opensim-SC-a0b22a9adc428e27dce86a2bf18ec66f5cee3b3c.tar.gz
opensim-SC-a0b22a9adc428e27dce86a2bf18ec66f5cee3b3c.tar.bz2
opensim-SC-a0b22a9adc428e27dce86a2bf18ec66f5cee3b3c.tar.xz
Merge branch 'master' of ssh://justincc@opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs13
-rw-r--r--OpenSim/Framework/MultipartForm.cs117
-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/Framework/Scenes/ScenePresence.cs53
6 files changed, 672 insertions, 95 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/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/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index f83a4d2..465e916 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -830,41 +830,15 @@ namespace OpenSim.Region.Framework.Scenes
830 pos.Y = crossedBorder.BorderLine.Z - 1; 830 pos.Y = crossedBorder.BorderLine.Z - 1;
831 } 831 }
832 832
833 833 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
834 if (pos.X < 0 || pos.Y < 0 || pos.Z < 0)
835 { 834 {
836 Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128);
837
838 if (pos.X < 0)
839 {
840 emergencyPos.X = (int)Constants.RegionSize + pos.X;
841 if (!(pos.Y < 0))
842 emergencyPos.Y = pos.Y;
843 if (!(pos.Z < 0))
844 emergencyPos.X = pos.X;
845 }
846 if (pos.Y < 0)
847 {
848 emergencyPos.Y = (int)Constants.RegionSize + pos.Y;
849 if (!(pos.X < 0))
850 emergencyPos.X = pos.X;
851 if (!(pos.Z < 0))
852 emergencyPos.Z = pos.Z;
853 }
854 if (pos.Z < 0)
855 {
856 if (!(pos.X < 0))
857 emergencyPos.X = pos.X;
858 if (!(pos.Y < 0))
859 emergencyPos.Y = pos.Y;
860 //Leave as 128
861 }
862
863 m_log.WarnFormat( 835 m_log.WarnFormat(
864 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", 836 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
865 pos, Name, UUID, emergencyPos); 837 pos, Name, UUID);
866 838
867 pos = emergencyPos; 839 if (pos.X < 0f) pos.X = 0f;
840 if (pos.Y < 0f) pos.Y = 0f;
841 if (pos.Z < 0f) pos.Z = 0f;
868 } 842 }
869 843
870 float localAVHeight = 1.56f; 844 float localAVHeight = 1.56f;
@@ -875,7 +849,7 @@ namespace OpenSim.Region.Framework.Scenes
875 849
876 float posZLimit = 0; 850 float posZLimit = 0;
877 851
878 if (pos.X <Constants.RegionSize && pos.Y < Constants.RegionSize) 852 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
879 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 853 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
880 854
881 float newPosZ = posZLimit + localAVHeight / 2; 855 float newPosZ = posZLimit + localAVHeight / 2;
@@ -2685,7 +2659,12 @@ namespace OpenSim.Region.Framework.Scenes
2685 /// </summary> 2659 /// </summary>
2686 protected void CheckForSignificantMovement() 2660 protected void CheckForSignificantMovement()
2687 { 2661 {
2688 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > 0.5) 2662 // Movement updates for agents in neighboring regions are sent directly to clients.
2663 // This value only affects how often agent positions are sent to neighbor regions
2664 // for things such as distance-based update prioritization
2665 const float SIGNIFICANT_MOVEMENT = 2.0f;
2666
2667 if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT)
2689 { 2668 {
2690 posLastSignificantMove = AbsolutePosition; 2669 posLastSignificantMove = AbsolutePosition;
2691 m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); 2670 m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient);
@@ -2701,13 +2680,13 @@ namespace OpenSim.Region.Framework.Scenes
2701 cadu.AgentID = UUID.Guid; 2680 cadu.AgentID = UUID.Guid;
2702 cadu.alwaysrun = m_setAlwaysRun; 2681 cadu.alwaysrun = m_setAlwaysRun;
2703 cadu.AVHeight = m_avHeight; 2682 cadu.AVHeight = m_avHeight;
2704 sLLVector3 tempCameraCenter = new sLLVector3(new Vector3(m_CameraCenter.X, m_CameraCenter.Y, m_CameraCenter.Z)); 2683 Vector3 tempCameraCenter = m_CameraCenter;
2705 cadu.cameraPosition = tempCameraCenter; 2684 cadu.cameraPosition = tempCameraCenter;
2706 cadu.drawdistance = m_DrawDistance; 2685 cadu.drawdistance = m_DrawDistance;
2707 if (m_scene.Permissions.IsGod(new UUID(cadu.AgentID))) 2686 if (m_scene.Permissions.IsGod(new UUID(cadu.AgentID)))
2708 cadu.godlevel = m_godlevel; 2687 cadu.godlevel = m_godlevel;
2709 cadu.GroupAccess = 0; 2688 cadu.GroupAccess = 0;
2710 cadu.Position = new sLLVector3(AbsolutePosition); 2689 cadu.Position = AbsolutePosition;
2711 cadu.regionHandle = m_rootRegionHandle; 2690 cadu.regionHandle = m_rootRegionHandle;
2712 float multiplier = 1; 2691 float multiplier = 1;
2713 int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); 2692 int innacurateNeighbors = m_scene.GetInaccurateNeighborCount();
@@ -2722,7 +2701,7 @@ namespace OpenSim.Region.Framework.Scenes
2722 2701
2723 //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); 2702 //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString());
2724 cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); 2703 cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier);
2725 cadu.Velocity = new sLLVector3(Velocity); 2704 cadu.Velocity = Velocity;
2726 2705
2727 AgentPosition agentpos = new AgentPosition(); 2706 AgentPosition agentpos = new AgentPosition();
2728 agentpos.CopyFrom(cadu); 2707 agentpos.CopyFrom(cadu);