aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorUbitUmarov2016-11-19 15:45:41 +0000
committerUbitUmarov2016-11-19 15:45:41 +0000
commit7cb3d583a97ac36f0c2ef5d6eadae28f26378fc4 (patch)
treea2ab69bce5eda122b119da082625449f92b4c3d3
parentMerge branch 'master' into httptests (diff)
parentREST console v2. This is an incompatible protocol change. It degrades gracefu... (diff)
downloadopensim-SC-7cb3d583a97ac36f0c2ef5d6eadae28f26378fc4.zip
opensim-SC-7cb3d583a97ac36f0c2ef5d6eadae28f26378fc4.tar.gz
opensim-SC-7cb3d583a97ac36f0c2ef5d6eadae28f26378fc4.tar.bz2
opensim-SC-7cb3d583a97ac36f0c2ef5d6eadae28f26378fc4.tar.xz
merge conflits
Diffstat (limited to '')
-rw-r--r--OpenSim/Capabilities/Caps.cs5
-rw-r--r--OpenSim/Framework/AgentUpdateArgs.cs1
-rw-r--r--OpenSim/Framework/Console/RemoteConsole.cs332
-rw-r--r--OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs5
-rw-r--r--OpenSim/Framework/LocklessQueue.cs6
-rw-r--r--OpenSim/Framework/TaskInventoryDictionary.cs7
-rw-r--r--OpenSim/Framework/WebUtil.cs8
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs173
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs22
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs12
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs9
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs33
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs2
-rwxr-xr-xOpenSim/Region/Framework/Scenes/Scene.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs62
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs131
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs14
-rw-r--r--OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs4
-rw-r--r--OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs53
-rw-r--r--ThirdParty/SmartThreadPool/WorkItemsQueue.cs1
21 files changed, 618 insertions, 267 deletions
diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs
index 3efab8e..5e89c38 100644
--- a/OpenSim/Capabilities/Caps.cs
+++ b/OpenSim/Capabilities/Caps.cs
@@ -141,6 +141,11 @@ namespace OpenSim.Framework.Capabilities
141 m_capsActive.Reset(); 141 m_capsActive.Reset();
142 } 142 }
143 143
144 ~Caps()
145 {
146 m_capsActive.Dispose();
147 }
148
144 /// <summary> 149 /// <summary>
145 /// Register a handler. This allows modules to register handlers. 150 /// Register a handler. This allows modules to register handlers.
146 /// </summary> 151 /// </summary>
diff --git a/OpenSim/Framework/AgentUpdateArgs.cs b/OpenSim/Framework/AgentUpdateArgs.cs
index eaa7902..f04d692 100644
--- a/OpenSim/Framework/AgentUpdateArgs.cs
+++ b/OpenSim/Framework/AgentUpdateArgs.cs
@@ -82,6 +82,7 @@ namespace OpenSim.Framework
82 public Vector3 ClientAgentPosition; 82 public Vector3 ClientAgentPosition;
83 public bool UseClientAgentPosition; 83 public bool UseClientAgentPosition;
84 public bool NeedsCameraCollision; 84 public bool NeedsCameraCollision;
85 public uint lastpacketSequence;
85 86
86 public AgentUpdateArgs() 87 public AgentUpdateArgs()
87 { 88 {
diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs
index 4b88923..9049b4b 100644
--- a/OpenSim/Framework/Console/RemoteConsole.cs
+++ b/OpenSim/Framework/Console/RemoteConsole.cs
@@ -34,6 +34,7 @@ using System.Reflection;
34using System.Text; 34using System.Text;
35using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Threading; 36using System.Threading;
37using System.Timers;
37using OpenMetaverse; 38using OpenMetaverse;
38using Nini.Config; 39using Nini.Config;
39using OpenSim.Framework.Servers.HttpServer; 40using OpenSim.Framework.Servers.HttpServer;
@@ -41,90 +42,232 @@ using log4net;
41 42
42namespace OpenSim.Framework.Console 43namespace OpenSim.Framework.Console
43{ 44{
44 public class ConsoleConnection
45 {
46 public int last;
47 public long lastLineSeen;
48 public bool newConnection = true;
49 }
50
51 // A console that uses REST interfaces 45 // A console that uses REST interfaces
52 // 46 //
53 public class RemoteConsole : CommandConsole 47 public class RemoteConsole : CommandConsole
54 { 48 {
55 private IHttpServer m_Server = null; 49 // Connection specific data, indexed by a session ID
56 private IConfigSource m_Config = null; 50 // we create when a client connects.
57 51 protected class ConsoleConnection
58 private List<string> m_Scrollback = new List<string>(); 52 {
59 private ManualResetEvent m_DataEvent = new ManualResetEvent(false); 53 // Last activity from the client
60 private List<string> m_InputData = new List<string>(); 54 public int last;
61 private long m_LineNumber = 0; 55
62 private Dictionary<UUID, ConsoleConnection> m_Connections = 56 // Last line of scrollback posted to this client
57 public long lastLineSeen;
58
59 // True if this is a new connection, e.g. has never
60 // displayed a prompt to the user.
61 public bool newConnection = true;
62 }
63
64 // A line in the scrollback buffer.
65 protected class ScrollbackEntry
66 {
67 // The line number of this entry
68 public long lineNumber;
69
70 // The text to send to the client
71 public string text;
72
73 // The level this should be logged as. Omitted for
74 // prompts and input echo.
75 public string level;
76
77 // True if the text above is a prompt, e.g. the
78 // client should turn on the cursor / accept input
79 public bool isPrompt;
80
81 // True if the requested input is a command. A
82 // client may offer help or validate input if
83 // this is set. If false, input should be sent
84 // as typed.
85 public bool isCommand;
86
87 // True if this text represents a line of text that
88 // was input in response to a prompt. A client should
89 // turn off the cursor and refrain from sending commands
90 // until a new prompt is received.
91 public bool isInput;
92 }
93
94 // Data that is relevant to all connections
95
96 // The scrollback buffer
97 protected List<ScrollbackEntry> m_Scrollback = new List<ScrollbackEntry>();
98
99 // Monotonously incrementing line number. This may eventually
100 // wrap. No provision is made for that case because 64 bits
101 // is a long, long time.
102 protected long m_lineNumber = 0;
103
104 // These two variables allow us to send the correct
105 // information about the prompt status to the client,
106 // irrespective of what may have run off the top of the
107 // scrollback buffer;
108 protected bool m_expectingInput = false;
109 protected bool m_expectingCommand = true;
110 protected string m_lastPromptUsed;
111
112 // This is the list of things received from clients.
113 // Note: Race conditions can happen. If a client sends
114 // something while nothing is expected, it will be
115 // intepreted as input to the next prompt. For
116 // commands this is largely correct. For other prompts,
117 // YMMV.
118 // TODO: Find a better way to fix this
119 protected List<string> m_InputData = new List<string>();
120
121 // Event to allow ReadLine to wait synchronously even though
122 // everthing else is asynchronous here.
123 protected ManualResetEvent m_DataEvent = new ManualResetEvent(false);
124
125 // The list of sessions we maintain. Unlike other console types,
126 // multiple users on the same console are explicitly allowed.
127 protected Dictionary<UUID, ConsoleConnection> m_Connections =
63 new Dictionary<UUID, ConsoleConnection>(); 128 new Dictionary<UUID, ConsoleConnection>();
64 private string m_UserName = String.Empty; 129
65 private string m_Password = String.Empty; 130 // Timer to control expiration of sessions that have been
66 private string m_AllowedOrigin = String.Empty; 131 // disconnected.
132 protected System.Timers.Timer m_expireTimer = new System.Timers.Timer(5000);
133
134 // The less interesting stuff that makes the actual server
135 // work.
136 protected IHttpServer m_Server = null;
137 protected IConfigSource m_Config = null;
138
139 protected string m_UserName = String.Empty;
140 protected string m_Password = String.Empty;
141 protected string m_AllowedOrigin = String.Empty;
142
67 143
68 public RemoteConsole(string defaultPrompt) : base(defaultPrompt) 144 public RemoteConsole(string defaultPrompt) : base(defaultPrompt)
69 { 145 {
146 // There is something wrong with this architecture.
147 // A prompt is sent on every single input, so why have this?
148 // TODO: Investigate and fix.
149 m_lastPromptUsed = defaultPrompt;
150
151 // Start expiration of sesssions.
152 m_expireTimer.Elapsed += DoExpire;
153 m_expireTimer.Start();
70 } 154 }
71 155
72 public void ReadConfig(IConfigSource config) 156 public void ReadConfig(IConfigSource config)
73 { 157 {
74 m_Config = config; 158 m_Config = config;
75 159
160 // We're pulling this from the 'Network' section for legacy
161 // compatibility. However, this is so essentially insecure
162 // that TLS and client certs should be used instead of
163 // a username / password.
76 IConfig netConfig = m_Config.Configs["Network"]; 164 IConfig netConfig = m_Config.Configs["Network"];
165
77 if (netConfig == null) 166 if (netConfig == null)
78 return; 167 return;
79 168
169 // Get the username and password.
80 m_UserName = netConfig.GetString("ConsoleUser", String.Empty); 170 m_UserName = netConfig.GetString("ConsoleUser", String.Empty);
81 m_Password = netConfig.GetString("ConsolePass", String.Empty); 171 m_Password = netConfig.GetString("ConsolePass", String.Empty);
172
173 // Woefully underdocumented, this is what makes javascript
174 // console clients work. Set to "*" for anywhere or (better)
175 // to specific addresses.
82 m_AllowedOrigin = netConfig.GetString("ConsoleAllowedOrigin", String.Empty); 176 m_AllowedOrigin = netConfig.GetString("ConsoleAllowedOrigin", String.Empty);
83 } 177 }
84 178
85 public void SetServer(IHttpServer server) 179 public void SetServer(IHttpServer server)
86 { 180 {
181 // This is called by the framework to give us the server
182 // instance (means: port) to work with.
87 m_Server = server; 183 m_Server = server;
88 184
185 // Add our handlers
89 m_Server.AddHTTPHandler("/StartSession/", HandleHttpStartSession); 186 m_Server.AddHTTPHandler("/StartSession/", HandleHttpStartSession);
90 m_Server.AddHTTPHandler("/CloseSession/", HandleHttpCloseSession); 187 m_Server.AddHTTPHandler("/CloseSession/", HandleHttpCloseSession);
91 m_Server.AddHTTPHandler("/SessionCommand/", HandleHttpSessionCommand); 188 m_Server.AddHTTPHandler("/SessionCommand/", HandleHttpSessionCommand);
92 } 189 }
93 190
94 public override void Output(string text, string level) 191 public override void Output(string text, string level)
192 {
193 Output(text, level, false, false, false);
194 }
195
196 protected void Output(string text, string level, bool isPrompt, bool isCommand, bool isInput)
95 { 197 {
198 // Increment the line number. It was 0 and they start at 1
199 // so we need to pre-increment.
200 m_lineNumber++;
201
202 // Create and populate the new entry.
203 ScrollbackEntry newEntry = new ScrollbackEntry();
204
205 newEntry.lineNumber = m_lineNumber;
206 newEntry.text = text;
207 newEntry.level = level;
208 newEntry.isPrompt = isPrompt;
209 newEntry.isCommand = isCommand;
210 newEntry.isInput = isInput;
211
212 // Add a line to the scrollback. In some cases, that may not
213 // actually be a line of text.
96 lock (m_Scrollback) 214 lock (m_Scrollback)
97 { 215 {
216 // Prune the scrollback to the length se send as connect
217 // burst to give the user some context.
98 while (m_Scrollback.Count >= 1000) 218 while (m_Scrollback.Count >= 1000)
99 m_Scrollback.RemoveAt(0); 219 m_Scrollback.RemoveAt(0);
100 m_LineNumber++; 220
101 m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text); 221 m_Scrollback.Add(newEntry);
102 } 222 }
223
224 // Let the rest of the system know we have output something.
103 FireOnOutput(text.Trim()); 225 FireOnOutput(text.Trim());
226
227 // Also display it for debugging.
104 System.Console.WriteLine(text.Trim()); 228 System.Console.WriteLine(text.Trim());
105 } 229 }
106 230
107 public override void Output(string text) 231 public override void Output(string text)
108 { 232 {
109 Output(text, "normal"); 233 // Output plain (non-logging style) text.
234 Output(text, String.Empty, false, false, false);
110 } 235 }
111 236
112 public override string ReadLine(string p, bool isCommand, bool e) 237 public override string ReadLine(string p, bool isCommand, bool e)
113 { 238 {
114 if (isCommand) 239 // Output the prompt an prepare to wait. This
115 Output("+++"+p); 240 // is called on a dedicated console thread and
116 else 241 // needs to be synchronous. Old architecture but
117 Output("-++"+p); 242 // not worth upgrading.
118 243 if (isCommand)
244 {
245 m_expectingInput = true;
246 m_expectingCommand = true;
247 Output(p, String.Empty, true, true, false);
248 m_lastPromptUsed = p;
249 }
250 else
251 {
252 m_expectingInput = true;
253 Output(p, String.Empty, true, false, false);
254 }
255
256
257 // Here is where we wait for the user to input something.
119 m_DataEvent.WaitOne(); 258 m_DataEvent.WaitOne();
120 259
121 string cmdinput; 260 string cmdinput;
122 261
262 // Check for empty input. Read input if not empty.
123 lock (m_InputData) 263 lock (m_InputData)
124 { 264 {
125 if (m_InputData.Count == 0) 265 if (m_InputData.Count == 0)
126 { 266 {
127 m_DataEvent.Reset(); 267 m_DataEvent.Reset();
268 m_expectingInput = false;
269 m_expectingCommand = false;
270
128 return ""; 271 return "";
129 } 272 }
130 273
@@ -135,8 +278,19 @@ namespace OpenSim.Framework.Console
135 278
136 } 279 }
137 280
281 m_expectingInput = false;
282 m_expectingCommand = false;
283
284 // Echo to all the other users what we have done. This
285 // will also go to ourselves.
286 Output (cmdinput, String.Empty, false, false, true);
287
288 // If this is a command, we need to resolve and execute it.
138 if (isCommand) 289 if (isCommand)
139 { 290 {
291 // This call will actually execute the command and create
292 // any output associated with it. The core just gets an
293 // empty string so it will call again immediately.
140 string[] cmd = Commands.Resolve(Parser.Parse(cmdinput)); 294 string[] cmd = Commands.Resolve(Parser.Parse(cmdinput));
141 295
142 if (cmd.Length != 0) 296 if (cmd.Length != 0)
@@ -151,18 +305,23 @@ namespace OpenSim.Framework.Console
151 return String.Empty; 305 return String.Empty;
152 } 306 }
153 } 307 }
308
309 // Return the raw input string if not a command.
154 return cmdinput; 310 return cmdinput;
155 } 311 }
156 312
157 private Hashtable CheckOrigin(Hashtable result) 313 // Very simplistic static access control header.
314 protected Hashtable CheckOrigin(Hashtable result)
158 { 315 {
159 if (!string.IsNullOrEmpty(m_AllowedOrigin)) 316 if (!string.IsNullOrEmpty(m_AllowedOrigin))
160 result["access_control_allow_origin"] = m_AllowedOrigin; 317 result["access_control_allow_origin"] = m_AllowedOrigin;
318
161 return result; 319 return result;
162 } 320 }
321
163 /* TODO: Figure out how PollServiceHTTPHandler can access the request headers 322 /* TODO: Figure out how PollServiceHTTPHandler can access the request headers
164 * in order to use m_AllowedOrigin as a regular expression 323 * in order to use m_AllowedOrigin as a regular expression
165 private Hashtable CheckOrigin(Hashtable headers, Hashtable result) 324 protected Hashtable CheckOrigin(Hashtable headers, Hashtable result)
166 { 325 {
167 if (!string.IsNullOrEmpty(m_AllowedOrigin)) 326 if (!string.IsNullOrEmpty(m_AllowedOrigin))
168 { 327 {
@@ -177,18 +336,23 @@ namespace OpenSim.Framework.Console
177 } 336 }
178 */ 337 */
179 338
180 private void DoExpire() 339 protected void DoExpire(Object sender, ElapsedEventArgs e)
181 { 340 {
341 // Iterate the list of console connections and find those we
342 // haven't heard from for longer then the longpoll interval.
343 // Remove them.
182 List<UUID> expired = new List<UUID>(); 344 List<UUID> expired = new List<UUID>();
183 345
184 lock (m_Connections) 346 lock (m_Connections)
185 { 347 {
348 // Mark the expired ones
186 foreach (KeyValuePair<UUID, ConsoleConnection> kvp in m_Connections) 349 foreach (KeyValuePair<UUID, ConsoleConnection> kvp in m_Connections)
187 { 350 {
188 if (System.Environment.TickCount - kvp.Value.last > 500000) 351 if (System.Environment.TickCount - kvp.Value.last > 500000)
189 expired.Add(kvp.Key); 352 expired.Add(kvp.Key);
190 } 353 }
191 354
355 // Delete them
192 foreach (UUID id in expired) 356 foreach (UUID id in expired)
193 { 357 {
194 m_Connections.Remove(id); 358 m_Connections.Remove(id);
@@ -197,10 +361,10 @@ namespace OpenSim.Framework.Console
197 } 361 }
198 } 362 }
199 363
200 private Hashtable HandleHttpStartSession(Hashtable request) 364 // Start a new session.
365 protected Hashtable HandleHttpStartSession(Hashtable request)
201 { 366 {
202 DoExpire(); 367 // The login is in the form of a http form post
203
204 Hashtable post = DecodePostString(request["body"].ToString()); 368 Hashtable post = DecodePostString(request["body"].ToString());
205 Hashtable reply = new Hashtable(); 369 Hashtable reply = new Hashtable();
206 370
@@ -208,6 +372,7 @@ namespace OpenSim.Framework.Console
208 reply["int_response_code"] = 401; 372 reply["int_response_code"] = 401;
209 reply["content_type"] = "text/plain"; 373 reply["content_type"] = "text/plain";
210 374
375 // Check user name and password
211 if (m_UserName == String.Empty) 376 if (m_UserName == String.Empty)
212 return reply; 377 return reply;
213 378
@@ -220,22 +385,28 @@ namespace OpenSim.Framework.Console
220 return reply; 385 return reply;
221 } 386 }
222 387
388 // Set up the new console connection record
223 ConsoleConnection c = new ConsoleConnection(); 389 ConsoleConnection c = new ConsoleConnection();
224 c.last = System.Environment.TickCount; 390 c.last = System.Environment.TickCount;
225 c.lastLineSeen = 0; 391 c.lastLineSeen = 0;
226 392
393 // Assign session ID
227 UUID sessionID = UUID.Random(); 394 UUID sessionID = UUID.Random();
228 395
396 // Add connection to list.
229 lock (m_Connections) 397 lock (m_Connections)
230 { 398 {
231 m_Connections[sessionID] = c; 399 m_Connections[sessionID] = c;
232 } 400 }
233 401
402 // This call is a CAP. The URL is the authentication.
234 string uri = "/ReadResponses/" + sessionID.ToString() + "/"; 403 string uri = "/ReadResponses/" + sessionID.ToString() + "/";
235 404
236 m_Server.AddPollServiceHTTPHandler( 405 m_Server.AddPollServiceHTTPHandler(
237 uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, Drop, sessionID, 25000)); // 25 secs timeout 406 uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout
238 407
408 // Our reply is an XML document.
409 // TODO: Change this to Linq.Xml
239 XmlDocument xmldoc = new XmlDocument(); 410 XmlDocument xmldoc = new XmlDocument();
240 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, 411 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
241 "", ""); 412 "", "");
@@ -252,12 +423,13 @@ namespace OpenSim.Framework.Console
252 rootElement.AppendChild(id); 423 rootElement.AppendChild(id);
253 424
254 XmlElement prompt = xmldoc.CreateElement("", "Prompt", ""); 425 XmlElement prompt = xmldoc.CreateElement("", "Prompt", "");
255 prompt.AppendChild(xmldoc.CreateTextNode(DefaultPrompt)); 426 prompt.AppendChild(xmldoc.CreateTextNode(m_lastPromptUsed));
256 427
257 rootElement.AppendChild(prompt); 428 rootElement.AppendChild(prompt);
258 429
259 rootElement.AppendChild(MainConsole.Instance.Commands.GetXml(xmldoc)); 430 rootElement.AppendChild(MainConsole.Instance.Commands.GetXml(xmldoc));
260 431
432 // Set up the response and check origin
261 reply["str_response_string"] = xmldoc.InnerXml; 433 reply["str_response_string"] = xmldoc.InnerXml;
262 reply["int_response_code"] = 200; 434 reply["int_response_code"] = 200;
263 reply["content_type"] = "text/xml"; 435 reply["content_type"] = "text/xml";
@@ -266,10 +438,9 @@ namespace OpenSim.Framework.Console
266 return reply; 438 return reply;
267 } 439 }
268 440
269 private Hashtable HandleHttpCloseSession(Hashtable request) 441 // Client closes session. Clean up.
442 protected Hashtable HandleHttpCloseSession(Hashtable request)
270 { 443 {
271 DoExpire();
272
273 Hashtable post = DecodePostString(request["body"].ToString()); 444 Hashtable post = DecodePostString(request["body"].ToString());
274 Hashtable reply = new Hashtable(); 445 Hashtable reply = new Hashtable();
275 446
@@ -316,10 +487,9 @@ namespace OpenSim.Framework.Console
316 return reply; 487 return reply;
317 } 488 }
318 489
319 private Hashtable HandleHttpSessionCommand(Hashtable request) 490 // Command received from the client.
491 protected Hashtable HandleHttpSessionCommand(Hashtable request)
320 { 492 {
321 DoExpire();
322
323 Hashtable post = DecodePostString(request["body"].ToString()); 493 Hashtable post = DecodePostString(request["body"].ToString());
324 Hashtable reply = new Hashtable(); 494 Hashtable reply = new Hashtable();
325 495
@@ -327,6 +497,7 @@ namespace OpenSim.Framework.Console
327 reply["int_response_code"] = 404; 497 reply["int_response_code"] = 404;
328 reply["content_type"] = "text/plain"; 498 reply["content_type"] = "text/plain";
329 499
500 // Check the ID
330 if (post["ID"] == null) 501 if (post["ID"] == null)
331 return reply; 502 return reply;
332 503
@@ -334,21 +505,25 @@ namespace OpenSim.Framework.Console
334 if (!UUID.TryParse(post["ID"].ToString(), out id)) 505 if (!UUID.TryParse(post["ID"].ToString(), out id))
335 return reply; 506 return reply;
336 507
508 // Find the connection for that ID.
337 lock (m_Connections) 509 lock (m_Connections)
338 { 510 {
339 if (!m_Connections.ContainsKey(id)) 511 if (!m_Connections.ContainsKey(id))
340 return reply; 512 return reply;
341 } 513 }
342 514
515 // Empty post. Just error out.
343 if (post["COMMAND"] == null) 516 if (post["COMMAND"] == null)
344 return reply; 517 return reply;
345 518
519 // Place the input data in the buffer.
346 lock (m_InputData) 520 lock (m_InputData)
347 { 521 {
348 m_DataEvent.Set(); 522 m_DataEvent.Set();
349 m_InputData.Add(post["COMMAND"].ToString()); 523 m_InputData.Add(post["COMMAND"].ToString());
350 } 524 }
351 525
526 // Create the XML reply document.
352 XmlDocument xmldoc = new XmlDocument(); 527 XmlDocument xmldoc = new XmlDocument();
353 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, 528 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
354 "", ""); 529 "", "");
@@ -372,7 +547,8 @@ namespace OpenSim.Framework.Console
372 return reply; 547 return reply;
373 } 548 }
374 549
375 private Hashtable DecodePostString(string data) 550 // Decode a HTTP form post to a Hashtable
551 protected Hashtable DecodePostString(string data)
376 { 552 {
377 Hashtable result = new Hashtable(); 553 Hashtable result = new Hashtable();
378 554
@@ -396,6 +572,7 @@ namespace OpenSim.Framework.Console
396 return result; 572 return result;
397 } 573 }
398 574
575 // Close the CAP receiver for the responses for a given client.
399 public void CloseConnection(UUID id) 576 public void CloseConnection(UUID id)
400 { 577 {
401 try 578 try
@@ -409,7 +586,9 @@ namespace OpenSim.Framework.Console
409 } 586 }
410 } 587 }
411 588
412 private bool HasEvents(UUID RequestID, UUID sessionID) 589 // Check if there is anything to send. Return true if this client has
590 // lines pending.
591 protected bool HasEvents(UUID RequestID, UUID sessionID)
413 { 592 {
414 ConsoleConnection c = null; 593 ConsoleConnection c = null;
415 594
@@ -420,22 +599,15 @@ namespace OpenSim.Framework.Console
420 c = m_Connections[sessionID]; 599 c = m_Connections[sessionID];
421 } 600 }
422 c.last = System.Environment.TickCount; 601 c.last = System.Environment.TickCount;
423 if (c.lastLineSeen < m_LineNumber) 602 if (c.lastLineSeen < m_lineNumber)
424 return true; 603 return true;
425 return false; 604 return false;
426 } 605 }
427 606
428 private void Drop(UUID RequestID, UUID sessionID) 607 // Send all pending output to the client.
429 { 608 protected Hashtable GetEvents(UUID RequestID, UUID sessionID)
430 lock (m_Connections)
431 {
432 if (m_Connections.ContainsKey(sessionID))
433 m_Connections.Remove(sessionID);
434 }
435 }
436
437 private Hashtable GetEvents(UUID RequestID, UUID sessionID)
438 { 609 {
610 // Find the connection that goes with this client.
439 ConsoleConnection c = null; 611 ConsoleConnection c = null;
440 612
441 lock (m_Connections) 613 lock (m_Connections)
@@ -444,12 +616,15 @@ namespace OpenSim.Framework.Console
444 return NoEvents(RequestID, UUID.Zero); 616 return NoEvents(RequestID, UUID.Zero);
445 c = m_Connections[sessionID]; 617 c = m_Connections[sessionID];
446 } 618 }
619
620 // If we have nothing to send, send the no events response.
447 c.last = System.Environment.TickCount; 621 c.last = System.Environment.TickCount;
448 if (c.lastLineSeen >= m_LineNumber) 622 if (c.lastLineSeen >= m_lineNumber)
449 return NoEvents(RequestID, UUID.Zero); 623 return NoEvents(RequestID, UUID.Zero);
450 624
451 Hashtable result = new Hashtable(); 625 Hashtable result = new Hashtable();
452 626
627 // Create the response document.
453 XmlDocument xmldoc = new XmlDocument(); 628 XmlDocument xmldoc = new XmlDocument();
454 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, 629 XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
455 "", ""); 630 "", "");
@@ -458,30 +633,53 @@ namespace OpenSim.Framework.Console
458 XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession", 633 XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession",
459 ""); 634 "");
460 635
461 if (c.newConnection) 636 //if (c.newConnection)
462 { 637 //{
463 c.newConnection = false; 638 // c.newConnection = false;
464 Output("+++" + DefaultPrompt); 639 // Output("+++" + DefaultPrompt);
465 } 640 //}
466 641
467 lock (m_Scrollback) 642 lock (m_Scrollback)
468 { 643 {
469 long startLine = m_LineNumber - m_Scrollback.Count; 644 long startLine = m_lineNumber - m_Scrollback.Count;
470 long sendStart = startLine; 645 long sendStart = startLine;
471 if (sendStart < c.lastLineSeen) 646 if (sendStart < c.lastLineSeen)
472 sendStart = c.lastLineSeen; 647 sendStart = c.lastLineSeen;
473 648
474 for (long i = sendStart ; i < m_LineNumber ; i++) 649 for (long i = sendStart ; i < m_lineNumber ; i++)
475 { 650 {
651 ScrollbackEntry e = m_Scrollback[(int)(i - startLine)];
652
476 XmlElement res = xmldoc.CreateElement("", "Line", ""); 653 XmlElement res = xmldoc.CreateElement("", "Line", "");
477 long line = i + 1; 654 res.SetAttribute("Number", e.lineNumber.ToString());
478 res.SetAttribute("Number", line.ToString()); 655 res.SetAttribute("Level", e.level);
479 res.AppendChild(xmldoc.CreateTextNode(m_Scrollback[(int)(i - startLine)])); 656 // Don't include these for the scrollback, we'll send the
657 // real state later.
658 if (!c.newConnection)
659 {
660 res.SetAttribute("Prompt", e.isPrompt ? "true" : "false");
661 res.SetAttribute("Command", e.isCommand ? "true" : "false");
662 res.SetAttribute("Input", e.isInput ? "true" : "false");
663 }
664 else if (i == m_lineNumber - 1) // Last line for a new connection
665 {
666 res.SetAttribute("Prompt", m_expectingInput ? "true" : "false");
667 res.SetAttribute("Command", m_expectingCommand ? "true" : "false");
668 res.SetAttribute("Input", (!m_expectingInput) ? "true" : "false");
669 }
670 else
671 {
672 res.SetAttribute("Input", e.isInput ? "true" : "false");
673 }
674
675 res.AppendChild(xmldoc.CreateTextNode(e.text));
480 676
481 rootElement.AppendChild(res); 677 rootElement.AppendChild(res);
482 } 678 }
483 } 679 }
484 c.lastLineSeen = m_LineNumber; 680
681 c.lastLineSeen = m_lineNumber;
682 c.newConnection = false;
485 683
486 xmldoc.AppendChild(rootElement); 684 xmldoc.AppendChild(rootElement);
487 685
@@ -495,7 +693,9 @@ namespace OpenSim.Framework.Console
495 return result; 693 return result;
496 } 694 }
497 695
498 private Hashtable NoEvents(UUID RequestID, UUID id) 696 // This is really just a no-op. It generates what is sent
697 // to the client if the poll times out without any events.
698 protected Hashtable NoEvents(UUID RequestID, UUID id)
499 { 699 {
500 Hashtable result = new Hashtable(); 700 Hashtable result = new Hashtable();
501 701
diff --git a/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs
index 9056548..4ff8cba 100644
--- a/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs
+++ b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs
@@ -55,6 +55,11 @@ namespace OpenSim.Framework
55 Dictionary2 = new Dictionary<TKey2, TValue>(capacity); 55 Dictionary2 = new Dictionary<TKey2, TValue>(capacity);
56 } 56 }
57 57
58 ~DoubleDictionaryThreadAbortSafe()
59 {
60 rwLock.Dispose();
61 }
62
58 public void Add(TKey1 key1, TKey2 key2, TValue value) 63 public void Add(TKey1 key1, TKey2 key2, TValue value)
59 { 64 {
60 bool gotLock = false; 65 bool gotLock = false;
diff --git a/OpenSim/Framework/LocklessQueue.cs b/OpenSim/Framework/LocklessQueue.cs
index 9bd9baf..7ccbba7 100644
--- a/OpenSim/Framework/LocklessQueue.cs
+++ b/OpenSim/Framework/LocklessQueue.cs
@@ -93,7 +93,10 @@ namespace OpenSim.Framework
93 if (oldHead == oldTail) 93 if (oldHead == oldTail)
94 { 94 {
95 if (oldHeadNext == null) 95 if (oldHeadNext == null)
96 {
97 count = 0;
96 return false; 98 return false;
99 }
97 100
98 CAS(ref tail, oldTail, oldHeadNext); 101 CAS(ref tail, oldTail, oldHeadNext);
99 } 102 }
@@ -118,8 +121,7 @@ namespace OpenSim.Framework
118 { 121 {
119 // ugly 122 // ugly
120 T item; 123 T item;
121 while(count > 0) 124 while(Dequeue(out item));
122 Dequeue(out item);
123 Init(); 125 Init();
124 } 126 }
125 127
diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs
index 2c20ef7..c270d98 100644
--- a/OpenSim/Framework/TaskInventoryDictionary.cs
+++ b/OpenSim/Framework/TaskInventoryDictionary.cs
@@ -64,6 +64,13 @@ namespace OpenSim.Framework
64 /// </value> 64 /// </value>
65 private volatile System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim(); 65 private volatile System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
66 66
67
68 ~TaskInventoryDictionary()
69 {
70 m_itemLock.Dispose();
71 m_itemLock = null;
72 }
73
67 /// <summary> 74 /// <summary>
68 /// Are we readlocked by the calling thread? 75 /// Are we readlocked by the calling thread?
69 /// </summary> 76 /// </summary>
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index 51d87bd..2bbf785 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -1062,11 +1062,10 @@ namespace OpenSim.Framework
1062 if (WebUtil.DebugLevel >= 5) 1062 if (WebUtil.DebugLevel >= 5)
1063 WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); 1063 WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
1064 1064
1065 Stream requestStream = null;
1066 try 1065 try
1067 { 1066 {
1068 requestStream = request.GetRequestStream(); 1067 using(Stream requestStream = request.GetRequestStream())
1069 requestStream.Write(data, 0, length); 1068 requestStream.Write(data,0,length);
1070 } 1069 }
1071 catch (Exception e) 1070 catch (Exception e)
1072 { 1071 {
@@ -1076,9 +1075,6 @@ namespace OpenSim.Framework
1076 } 1075 }
1077 finally 1076 finally
1078 { 1077 {
1079 if (requestStream != null)
1080 requestStream.Dispose();
1081
1082 // capture how much time was spent writing 1078 // capture how much time was spent writing
1083 tickdata = Util.EnvironmentTickCountSubtract(tickstart); 1079 tickdata = Util.EnvironmentTickCountSubtract(tickstart);
1084 } 1080 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 46c6a19..8ba26e8 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -347,12 +347,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
347 private const uint MaxTransferBytesPerPacket = 600; 347 private const uint MaxTransferBytesPerPacket = 600;
348 348
349 /// <value> 349 /// <value>
350 /// List used in construction of data blocks for an object update packet. This is to stop us having to
351 /// continually recreate it.
352 /// </value>
353 protected List<ObjectUpdatePacket.ObjectDataBlock> m_fullUpdateDataBlocksBuilder;
354
355 /// <value>
356 /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the 350 /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the
357 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 351 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
358 /// ownerless phantom. 352 /// ownerless phantom.
@@ -511,7 +505,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
511 m_scene = scene; 505 m_scene = scene;
512 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 506 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
513 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 507 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
514 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
515 m_killRecord = new List<uint>(); 508 m_killRecord = new List<uint>();
516// m_attachmentsSent = new HashSet<uint>(); 509// m_attachmentsSent = new HashSet<uint>();
517 510
@@ -594,13 +587,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
594 OutPacket(disable, ThrottleOutPacketType.Unknown); 587 OutPacket(disable, ThrottleOutPacketType.Unknown);
595 } 588 }
596 589
597 // Shutdown the image manager
598 ImageManager.Close();
599 590
600 // Fire the callback for this connection closing 591 // Fire the callback for this connection closing
601 if (OnConnectionClosed != null) 592 if (OnConnectionClosed != null)
602 OnConnectionClosed(this); 593 OnConnectionClosed(this);
603 594
595
604 // Flush all of the packets out of the UDP server for this client 596 // Flush all of the packets out of the UDP server for this client
605 if (m_udpServer != null) 597 if (m_udpServer != null)
606 m_udpServer.Flush(m_udpClient); 598 m_udpServer.Flush(m_udpClient);
@@ -615,8 +607,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
615 607
616 // Disable UDP handling for this client 608 // Disable UDP handling for this client
617 m_udpClient.Shutdown(); 609 m_udpClient.Shutdown();
618 610
619 611 m_udpClient.OnQueueEmpty -= HandleQueueEmpty;
612 m_udpClient.HasUpdates -= HandleHasUpdates;
613 m_udpClient.OnPacketStats -= PopulateStats;
614
615 // Shutdown the image manager
616 ImageManager.Close();
617 ImageManager = null;
618
619 m_entityUpdates = null;
620 m_entityProps = null;
621 m_killRecord.Clear();
622 GroupsInView.Clear();
623 m_scene = null;
620 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 624 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
621 //GC.Collect(); 625 //GC.Collect();
622 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 626 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -814,7 +818,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
814 public void ProcessSpecificPacketAsync(object state) 818 public void ProcessSpecificPacketAsync(object state)
815 { 819 {
816 AsyncPacketProcess packetObject = (AsyncPacketProcess)state; 820 AsyncPacketProcess packetObject = (AsyncPacketProcess)state;
817 821
818 try 822 try
819 { 823 {
820 packetObject.result = packetObject.Method(packetObject.ClientView, packetObject.Pack); 824 packetObject.result = packetObject.Method(packetObject.ClientView, packetObject.Pack);
@@ -4095,19 +4099,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4095 ResendPrimUpdate(update); 4099 ResendPrimUpdate(update);
4096 } 4100 }
4097 4101
4102 private List<ObjectUpdatePacket.ObjectDataBlock> objectUpdateBlocks = new List<ObjectUpdatePacket.ObjectDataBlock>();
4103 private List<ObjectUpdateCompressedPacket.ObjectDataBlock> compressedUpdateBlocks = new List<ObjectUpdateCompressedPacket.ObjectDataBlock>();
4104 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
4105 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseAgentUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
4106
4098 private void ProcessEntityUpdates(int maxUpdatesBytes) 4107 private void ProcessEntityUpdates(int maxUpdatesBytes)
4099 { 4108 {
4100 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
4101 OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
4102 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
4103 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
4104
4105 OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 4109 OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
4106 OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 4110 OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
4107 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 4111 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
4108 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 4112 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
4109 4113
4110
4111 // Check to see if this is a flush 4114 // Check to see if this is a flush
4112 if (maxUpdatesBytes <= 0) 4115 if (maxUpdatesBytes <= 0)
4113 { 4116 {
@@ -4328,7 +4331,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4328 ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); 4331 ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
4329 else 4332 else
4330 ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId); 4333 ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId);
4331 objectUpdateBlocks.Value.Add(ablock); 4334 objectUpdateBlocks.Add(ablock);
4332 objectUpdates.Value.Add(update); 4335 objectUpdates.Value.Add(update);
4333 maxUpdatesBytes -= ablock.Length; 4336 maxUpdatesBytes -= ablock.Length;
4334 4337
@@ -4337,7 +4340,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4337 { 4340 {
4338 ObjectUpdateCompressedPacket.ObjectDataBlock ablock = 4341 ObjectUpdateCompressedPacket.ObjectDataBlock ablock =
4339 CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags); 4342 CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags);
4340 compressedUpdateBlocks.Value.Add(ablock); 4343 compressedUpdateBlocks.Add(ablock);
4341 compressedUpdates.Value.Add(update); 4344 compressedUpdates.Value.Add(update);
4342 maxUpdatesBytes -= ablock.Length; 4345 maxUpdatesBytes -= ablock.Length;
4343 } 4346 }
@@ -4348,14 +4351,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4348 { 4351 {
4349 // ALL presence updates go into a special list 4352 // ALL presence updates go into a special list
4350 ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); 4353 ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
4351 terseAgentUpdateBlocks.Value.Add(ablock); 4354 terseAgentUpdateBlocks.Add(ablock);
4352 terseAgentUpdates.Value.Add(update); 4355 terseAgentUpdates.Value.Add(update);
4353 } 4356 }
4354 else 4357 else
4355 { 4358 {
4356 // Everything else goes here 4359 // Everything else goes here
4357 ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); 4360 ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
4358 terseUpdateBlocks.Value.Add(ablock); 4361 terseUpdateBlocks.Add(ablock);
4359 terseUpdates.Value.Add(update); 4362 terseUpdates.Value.Add(update);
4360 } 4363 }
4361 maxUpdatesBytes -= ablock.Length; 4364 maxUpdatesBytes -= ablock.Length;
@@ -4366,74 +4369,72 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4366 4369
4367 #region Packet Sending 4370 #region Packet Sending
4368 4371
4369// const float TIME_DILATION = 1.0f;
4370 ushort timeDilation; 4372 ushort timeDilation;
4371// if(updatesThisCall > 0) 4373
4372// timeDilation = Utils.FloatToUInt16(avgTimeDilation/updatesThisCall, 0.0f, 1.0f); 4374 if(m_scene == null)
4373// else 4375 return;
4374// timeDilation = ushort.MaxValue; // 1.0;
4375 4376
4376 timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); 4377 timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
4377 4378
4378 if (terseAgentUpdateBlocks.IsValueCreated) 4379 if (terseAgentUpdateBlocks.Count > 0)
4379 { 4380 {
4380 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
4381
4382 ImprovedTerseObjectUpdatePacket packet 4381 ImprovedTerseObjectUpdatePacket packet
4383 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4382 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4384 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4383 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4385 packet.RegionData.TimeDilation = timeDilation; 4384 packet.RegionData.TimeDilation = timeDilation;
4386 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4385 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseAgentUpdateBlocks.Count];
4386
4387 for (int i = 0; i < terseAgentUpdateBlocks.Count; i++)
4388 packet.ObjectData[i] = terseAgentUpdateBlocks[i];
4387 4389
4388 for (int i = 0; i < blocks.Count; i++) 4390 terseAgentUpdateBlocks.Clear();
4389 packet.ObjectData[i] = blocks[i];
4390 4391
4391 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4392 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
4392 } 4393 }
4393 4394
4394 if (objectUpdateBlocks.IsValueCreated) 4395 if (objectUpdateBlocks.Count > 0)
4395 { 4396 {
4396 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4397
4398 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 4397 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4399 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4398 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4400 packet.RegionData.TimeDilation = timeDilation; 4399 packet.RegionData.TimeDilation = timeDilation;
4401 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4400 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[objectUpdateBlocks.Count];
4402 4401
4403 for (int i = 0; i < blocks.Count; i++) 4402 for (int i = 0; i < objectUpdateBlocks.Count; i++)
4404 packet.ObjectData[i] = blocks[i]; 4403 packet.ObjectData[i] = objectUpdateBlocks[i];
4404
4405 objectUpdateBlocks.Clear();
4405 4406
4406 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); 4407 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4407 } 4408 }
4408 4409
4409 if (compressedUpdateBlocks.IsValueCreated) 4410 if (compressedUpdateBlocks.Count > 0)
4410 { 4411 {
4411 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4412
4413 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 4412 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4414 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4413 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4415 packet.RegionData.TimeDilation = timeDilation; 4414 packet.RegionData.TimeDilation = timeDilation;
4416 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 4415 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[compressedUpdateBlocks.Count];
4416
4417 for (int i = 0; i < compressedUpdateBlocks.Count; i++)
4418 packet.ObjectData[i] = compressedUpdateBlocks[i];
4417 4419
4418 for (int i = 0; i < blocks.Count; i++) 4420 compressedUpdateBlocks.Clear();
4419 packet.ObjectData[i] = blocks[i];
4420 4421
4421 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); }); 4422 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4422 } 4423 }
4423 4424
4424 if (terseUpdateBlocks.IsValueCreated) 4425 if (terseUpdateBlocks.Count > 0)
4425 { 4426 {
4426 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4427
4428 ImprovedTerseObjectUpdatePacket packet 4427 ImprovedTerseObjectUpdatePacket packet
4429 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( 4428 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4430 PacketType.ImprovedTerseObjectUpdate); 4429 PacketType.ImprovedTerseObjectUpdate);
4431 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4430 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4432 packet.RegionData.TimeDilation = timeDilation; 4431 packet.RegionData.TimeDilation = timeDilation;
4433 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4432 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseUpdateBlocks.Count];
4434 4433
4435 for (int i = 0; i < blocks.Count; i++) 4434 for (int i = 0; i < terseUpdateBlocks.Count; i++)
4436 packet.ObjectData[i] = blocks[i]; 4435 packet.ObjectData[i] = terseUpdateBlocks[i];
4436
4437 terseUpdateBlocks.Clear();
4437 4438
4438 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4439 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4439 } 4440 }
@@ -4634,6 +4635,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4634 4635
4635 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) 4636 void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
4636 { 4637 {
4638 if(m_scene == null)
4639 return;
4640
4637 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 4641 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
4638 { 4642 {
4639 int maxUpdateBytes = m_udpClient.GetCatBytesCanSend(ThrottleOutPacketType.Task, 30); 4643 int maxUpdateBytes = m_udpClient.GetCatBytesCanSend(ThrottleOutPacketType.Task, 30);
@@ -4828,21 +4832,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4828 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true)); 4832 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
4829 } 4833 }
4830 4834
4835 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> objectFamilyBlocks = new
4836 List<ObjectPropertiesFamilyPacket.ObjectDataBlock>();
4837 List<ObjectPropertiesPacket.ObjectDataBlock> objectPropertiesBlocks =
4838 new List<ObjectPropertiesPacket.ObjectDataBlock>();
4839 List<SceneObjectPart> needPhysics = new List<SceneObjectPart>();
4840
4831 private void ProcessEntityPropertyRequests(int maxUpdateBytes) 4841 private void ProcessEntityPropertyRequests(int maxUpdateBytes)
4832 { 4842 {
4833 OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks = 4843// OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates =
4834 new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>(); 4844// new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4835
4836 OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
4837 new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
4838 4845
4839 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates = 4846// OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
4840 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); 4847// new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4841
4842 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
4843 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4844 4848
4845 List<SceneObjectPart> needPhysics = new List<SceneObjectPart>();
4846 4849
4847 EntityUpdate iupdate; 4850 EntityUpdate iupdate;
4848 Int32 timeinqueue; // this is just debugging code & can be dropped later 4851 Int32 timeinqueue; // this is just debugging code & can be dropped later
@@ -4860,8 +4863,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4860 { 4863 {
4861 SceneObjectPart sop = (SceneObjectPart)update.Entity; 4864 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4862 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); 4865 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
4863 objectFamilyBlocks.Value.Add(objPropDB); 4866 objectFamilyBlocks.Add(objPropDB);
4864 familyUpdates.Value.Add(update); 4867// familyUpdates.Value.Add(update);
4865 maxUpdateBytes -= objPropDB.Length; 4868 maxUpdateBytes -= objPropDB.Length;
4866 } 4869 }
4867 } 4870 }
@@ -4873,23 +4876,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4873 SceneObjectPart sop = (SceneObjectPart)update.Entity; 4876 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4874 needPhysics.Add(sop); 4877 needPhysics.Add(sop);
4875 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); 4878 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
4876 objectPropertiesBlocks.Value.Add(objPropDB); 4879 objectPropertiesBlocks.Add(objPropDB);
4877 propertyUpdates.Value.Add(update); 4880// propertyUpdates.Value.Add(update);
4878 maxUpdateBytes -= objPropDB.Length; 4881 maxUpdateBytes -= objPropDB.Length;
4879 } 4882 }
4880 } 4883 }
4881 } 4884 }
4882 4885
4883 if (objectPropertiesBlocks.IsValueCreated) 4886 if (objectPropertiesBlocks.Count > 0)
4884 { 4887 {
4885 List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
4886 List<ObjectPropertyUpdate> updates = propertyUpdates.Value;
4887
4888 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 4888 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4889 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; 4889 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[objectPropertiesBlocks.Count];
4890 for (int i = 0; i < blocks.Count; i++) 4890 for (int i = 0; i < objectPropertiesBlocks.Count; i++)
4891 packet.ObjectData[i] = blocks[i]; 4891 packet.ObjectData[i] = objectPropertiesBlocks[i];
4892 4892
4893
4894 objectPropertiesBlocks.Clear();
4893 packet.Header.Zerocoded = true; 4895 packet.Header.Zerocoded = true;
4894 4896
4895 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4897 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
@@ -4898,7 +4900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4898 //OutPacket(packet, ThrottleOutPacketType.Task, true, 4900 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4899 // delegate(OutgoingPacket oPacket) 4901 // delegate(OutgoingPacket oPacket)
4900 // { 4902 // {
4901 // ResendPropertyUpdates(updates, oPacket); 4903 // ResendPropertyUpdates(propertyUpdates.Value, oPacket);
4902 // }); 4904 // });
4903 OutPacket(packet, ThrottleOutPacketType.Task, true); 4905 OutPacket(packet, ThrottleOutPacketType.Task, true);
4904 4906
@@ -4909,23 +4911,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4909 // Int32 fpcnt = 0; 4911 // Int32 fpcnt = 0;
4910 // Int32 fbcnt = 0; 4912 // Int32 fbcnt = 0;
4911 4913
4912 if (objectFamilyBlocks.IsValueCreated) 4914 if (objectFamilyBlocks.Count > 0)
4913 { 4915 {
4914 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
4915
4916 // one packet per object block... uggh... 4916 // one packet per object block... uggh...
4917 for (int i = 0; i < blocks.Count; i++) 4917 for (int i = 0; i < objectFamilyBlocks.Count; i++)
4918 { 4918 {
4919 ObjectPropertiesFamilyPacket packet = 4919 ObjectPropertiesFamilyPacket packet =
4920 (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); 4920 (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
4921 4921
4922 packet.ObjectData = blocks[i]; 4922 packet.ObjectData = objectFamilyBlocks[i];
4923 packet.Header.Zerocoded = true; 4923 packet.Header.Zerocoded = true;
4924 4924
4925 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4925 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4926 // of the object rather than the properties when the packet was created 4926 // of the object rather than the properties when the packet was created
4927 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4927// List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4928 updates.Add(familyUpdates.Value[i]); 4928// updates.Add(familyUpdates.Value[i]);
4929 // HACK : Remove intelligent resending until it's fixed in core 4929 // HACK : Remove intelligent resending until it's fixed in core
4930 //OutPacket(packet, ThrottleOutPacketType.Task, true, 4930 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4931 // delegate(OutgoingPacket oPacket) 4931 // delegate(OutgoingPacket oPacket)
@@ -4937,6 +4937,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4937 // fpcnt++; 4937 // fpcnt++;
4938 // fbcnt++; 4938 // fbcnt++;
4939 } 4939 }
4940 objectFamilyBlocks.Clear();
4940 } 4941 }
4941 4942
4942 if(needPhysics.Count > 0) 4943 if(needPhysics.Count > 0)
@@ -4962,6 +4963,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4962 4963
4963 eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId); 4964 eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId);
4964 } 4965 }
4966 needPhysics.Clear();
4965 } 4967 }
4966 4968
4967 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt); 4969 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt);
@@ -6251,9 +6253,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6251 return false; 6253 return false;
6252 } 6254 }
6253 6255
6256 uint seq = packet.Header.Sequence;
6257
6254 TotalAgentUpdates++; 6258 TotalAgentUpdates++;
6255 // dont let ignored updates pollute this throttles 6259 // dont let ignored updates pollute this throttles
6256 if(SceneAgent == null || SceneAgent.IsChildAgent || SceneAgent.IsInTransit) 6260 if(SceneAgent == null || SceneAgent.IsChildAgent ||
6261 SceneAgent.IsInTransit || seq <= m_thisAgentUpdateArgs.lastpacketSequence )
6257 { 6262 {
6258 // throttle reset is done at MoveAgentIntoRegion() 6263 // throttle reset is done at MoveAgentIntoRegion()
6259 // called by scenepresence on completemovement 6264 // called by scenepresence on completemovement
@@ -6261,6 +6266,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6261 return true; 6266 return true;
6262 } 6267 }
6263 6268
6269 m_thisAgentUpdateArgs.lastpacketSequence = seq;
6270
6264 bool movement = CheckAgentMovementUpdateSignificance(x); 6271 bool movement = CheckAgentMovementUpdateSignificance(x);
6265 bool camera = CheckAgentCameraUpdateSignificance(x); 6272 bool camera = CheckAgentCameraUpdateSignificance(x);
6266 6273
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index d59b761..e85cee2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -120,13 +120,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
120 /// <summary>Circuit code that this client is connected on</summary> 120 /// <summary>Circuit code that this client is connected on</summary>
121 public readonly uint CircuitCode; 121 public readonly uint CircuitCode;
122 /// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary> 122 /// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary>
123 public readonly IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200); 123 public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200);
124 124
125 /// <summary>Packets we have sent that need to be ACKed by the client</summary> 125 /// <summary>Packets we have sent that need to be ACKed by the client</summary>
126 public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); 126 public UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
127 127
128 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary> 128 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary>
129 public readonly DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>(); 129 public DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>();
130 130
131 /// <summary>Current packet sequence number</summary> 131 /// <summary>Current packet sequence number</summary>
132 public int CurrentSequence; 132 public int CurrentSequence;
@@ -170,7 +170,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
170 private double m_nextOnQueueEmpty = 0; 170 private double m_nextOnQueueEmpty = 0;
171 171
172 /// <summary>Throttle bucket for this agent's connection</summary> 172 /// <summary>Throttle bucket for this agent's connection</summary>
173 private readonly AdaptiveTokenBucket m_throttleClient; 173 private AdaptiveTokenBucket m_throttleClient;
174 public AdaptiveTokenBucket FlowThrottle 174 public AdaptiveTokenBucket FlowThrottle
175 { 175 {
176 get { return m_throttleClient; } 176 get { return m_throttleClient; }
@@ -179,10 +179,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
179 /// <summary>Throttle buckets for each packet category</summary> 179 /// <summary>Throttle buckets for each packet category</summary>
180 private readonly TokenBucket[] m_throttleCategories; 180 private readonly TokenBucket[] m_throttleCategories;
181 /// <summary>Outgoing queues for throttled packets</summary> 181 /// <summary>Outgoing queues for throttled packets</summary>
182 private readonly DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT]; 182 private DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT];
183 /// <summary>A container that can hold one packet for each outbox, used to store 183 /// <summary>A container that can hold one packet for each outbox, used to store
184 /// dequeued packets that are being held for throttling</summary> 184 /// dequeued packets that are being held for throttling</summary>
185 private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; 185 private OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
186 /// <summary>A reference to the LLUDPServer that is managing this client</summary> 186 /// <summary>A reference to the LLUDPServer that is managing this client</summary>
187 private readonly LLUDPServer m_udpServer; 187 private readonly LLUDPServer m_udpServer;
188 188
@@ -288,14 +288,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
288 for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) 288 for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
289 { 289 {
290 m_packetOutboxes[i].Clear(); 290 m_packetOutboxes[i].Clear();
291 m_throttleCategories[i] = null;
291 m_nextPackets[i] = null; 292 m_nextPackets[i] = null;
292 } 293 }
293 294
294 // pull the throttle out of the scene throttle 295 // pull the throttle out of the scene throttle
295 m_throttleClient.Parent.UnregisterRequest(m_throttleClient); 296 m_throttleClient.Parent.UnregisterRequest(m_throttleClient);
297 m_throttleClient = null;
296 OnPacketStats = null; 298 OnPacketStats = null;
297 OnQueueEmpty = null; 299 OnQueueEmpty = null;
298 } 300 PendingAcks.Clear();
301 NeedAcks.Clear();
302 NeedAcks = null;
303 PendingAcks = null;
304 m_nextPackets = null;
305 m_packetOutboxes = null;
306 }
299 307
300 /// <summary> 308 /// <summary>
301 /// Gets information about this client connection 309 /// Gets information about this client connection
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index ffdb639..af33d17 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -326,7 +326,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
326 protected double m_tickLastOutgoingPacketHandler; 326 protected double m_tickLastOutgoingPacketHandler;
327 327
328 /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary> 328 /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary>
329 protected int m_elapsedMSOutgoingPacketHandler; 329 protected double m_elapsedMSOutgoingPacketHandler;
330 330
331 /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary> 331 /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary>
332 protected int m_elapsed100MSOutgoingPacketHandler; 332 protected int m_elapsed100MSOutgoingPacketHandler;
@@ -2074,18 +2074,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2074 2074
2075 // Update elapsed time 2075 // Update elapsed time
2076 double thisTick = Util.GetTimeStampMS(); 2076 double thisTick = Util.GetTimeStampMS();
2077 int deltaMS = (int)(thisTick - m_tickLastOutgoingPacketHandler);
2078 m_tickLastOutgoingPacketHandler = thisTick;
2079 2077
2080 // update some 1ms resolution chained timers 2078 // update some 1ms resolution chained timers
2081 2079 m_elapsedMSOutgoingPacketHandler += thisTick - m_tickLastOutgoingPacketHandler;
2082 m_elapsedMSOutgoingPacketHandler += deltaMS; 2080 m_tickLastOutgoingPacketHandler = thisTick;
2083 2081
2084 // Check for pending outgoing resends every 100ms 2082 // Check for pending outgoing resends every 100ms
2085 if (m_elapsedMSOutgoingPacketHandler >= 100) 2083 if (m_elapsedMSOutgoingPacketHandler >= 100.0)
2086 { 2084 {
2087 m_resendUnacked = true; 2085 m_resendUnacked = true;
2088 m_elapsedMSOutgoingPacketHandler = 0; 2086 m_elapsedMSOutgoingPacketHandler = 0.0;
2089 m_elapsed100MSOutgoingPacketHandler += 1; 2087 m_elapsed100MSOutgoingPacketHandler += 1;
2090 } 2088 }
2091 2089
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
index 7b9661b..d4603f8 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/TokenBucket.cs
@@ -193,7 +193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
193 Parent = parent; 193 Parent = parent;
194 RequestedDripRate = dripRate; 194 RequestedDripRate = dripRate;
195 RequestedBurst = MaxBurst; 195 RequestedBurst = MaxBurst;
196 m_lastDrip = Util.GetTimeStampMS() + 50.0; 196 m_lastDrip = Util.GetTimeStampMS() + 100000.0; // skip first drip
197 } 197 }
198 198
199#endregion Constructor 199#endregion Constructor
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
index b546a99..c9d5697 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
@@ -74,6 +74,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
74 /// <summary>Holds information about pending removals</summary> 74 /// <summary>Holds information about pending removals</summary>
75 private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>(); 75 private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>();
76 76
77
78 public void Clear()
79 {
80 m_packets.Clear();
81 m_pendingAdds = null;
82 m_pendingAcknowledgements = null;
83 m_pendingRemoves = null;
84 }
85
77 /// <summary> 86 /// <summary>
78 /// Add an unacked packet to the collection 87 /// Add an unacked packet to the collection
79 /// </summary> 88 /// </summary>
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs
index 6c1cc52..2afd74e 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs
@@ -36,6 +36,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
36{ 36{
37 public class UserAccountCache : IUserAccountCacheModule 37 public class UserAccountCache : IUserAccountCacheModule
38 { 38 {
39 private const double CACHE_ALIEN_EXPIRATION_SECONDS = 172800; // 48 hours
39 private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour! 40 private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour!
40 private const double CACHE_NULL_EXPIRATION_SECONDS = 600; // 10minutes 41 private const double CACHE_NULL_EXPIRATION_SECONDS = 600; // 10minutes
41 42
@@ -60,21 +61,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
60 { 61 {
61 if (account == null) 62 if (account == null)
62 m_UUIDCache.AddOrUpdate(userID, null, CACHE_NULL_EXPIRATION_SECONDS); 63 m_UUIDCache.AddOrUpdate(userID, null, CACHE_NULL_EXPIRATION_SECONDS);
63 else 64 else if(account.LocalToGrid)
64 { 65 {
65 m_UUIDCache.AddOrUpdate(userID, account, CACHE_EXPIRATION_SECONDS); 66 m_UUIDCache.AddOrUpdate(userID, account, CACHE_EXPIRATION_SECONDS);
66 m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, CACHE_EXPIRATION_SECONDS); 67 m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, CACHE_EXPIRATION_SECONDS);
67 } 68 }
68 69 else
70 {
71 m_UUIDCache.AddOrUpdate(userID, account, CACHE_ALIEN_EXPIRATION_SECONDS);
72 m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, CACHE_ALIEN_EXPIRATION_SECONDS);
73 }
69 //m_log.DebugFormat("[USER CACHE]: cached user {0}", userID); 74 //m_log.DebugFormat("[USER CACHE]: cached user {0}", userID);
70 } 75 }
71 } 76 }
72 77
73 public void Invalidate(UUID userID)
74 {
75 lock(accessLock)
76 m_UUIDCache.Remove(userID);
77 }
78 78
79 public UserAccount Get(UUID userID, out bool inCache) 79 public UserAccount Get(UUID userID, out bool inCache)
80 { 80 {
@@ -114,6 +114,25 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
114 return null; 114 return null;
115 } 115 }
116 116
117 public void Invalidate(UUID userID)
118 {
119 m_UUIDCache.Remove(userID);
120 }
121
122 public void Remove(UUID id)
123 {
124 lock(accessLock)
125 {
126 if (!m_UUIDCache.Contains(id))
127 return;
128
129 UserAccount account = null;
130 if (m_UUIDCache.TryGetValue(id, out account) && account != null)
131 m_NameCache.Remove(account.Name);
132 m_UUIDCache.Remove(id);
133 }
134 }
135
117 public void Remove(string name) 136 public void Remove(string name)
118 { 137 {
119 lock(accessLock) 138 lock(accessLock)
diff --git a/OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs b/OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs
index ed26989..027a7e2 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserAccountCacheModule.cs
@@ -26,8 +26,10 @@
26 */ 26 */
27 27
28using OpenSim.Region.Framework.Scenes; 28using OpenSim.Region.Framework.Scenes;
29using OpenMetaverse;
29 30
30public interface IUserAccountCacheModule 31public interface IUserAccountCacheModule
31{ 32{
32 void Remove(string name); 33 void Remove(string name);
34 void Remove(UUID id);
33} 35}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ca32940..c349369 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4141,7 +4141,8 @@ namespace OpenSim.Region.Framework.Scenes
4141 { 4141 {
4142 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 4142 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
4143 if (cache != null) 4143 if (cache != null)
4144 cache.Remove(acd.firstname + " " + acd.lastname); 4144// cache.Remove(acd.firstname + " " + acd.lastname);
4145 cache.Remove(acd.AgentID);
4145 4146
4146 // Remove any preexisting circuit - we don't want duplicates 4147 // Remove any preexisting circuit - we don't want duplicates
4147 // This is a stab at preventing avatar "ghosting" 4148 // This is a stab at preventing avatar "ghosting"
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 3378ead..2cfdd94 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1104,7 +1104,7 @@ namespace OpenSim.Region.Framework.Scenes
1104 1104
1105 AdjustKnownSeeds(); 1105 AdjustKnownSeeds();
1106 1106
1107 RegisterToEvents(); 1107 RegisterToClientEvents();
1108 SetDirectionVectors(); 1108 SetDirectionVectors();
1109 1109
1110 Appearance = appearance; 1110 Appearance = appearance;
@@ -1171,7 +1171,7 @@ namespace OpenSim.Region.Framework.Scenes
1171 } 1171 }
1172 } 1172 }
1173 1173
1174 public void RegisterToEvents() 1174 public void RegisterToClientEvents()
1175 { 1175 {
1176 ControllingClient.OnCompleteMovementToRegion += CompleteMovement; 1176 ControllingClient.OnCompleteMovementToRegion += CompleteMovement;
1177 ControllingClient.OnAgentUpdate += HandleAgentUpdate; 1177 ControllingClient.OnAgentUpdate += HandleAgentUpdate;
@@ -1189,6 +1189,22 @@ namespace OpenSim.Region.Framework.Scenes
1189 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); 1189 // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange);
1190 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); 1190 // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement);
1191 } 1191 }
1192
1193 public void RemoveClientEvents()
1194 {
1195 ControllingClient.OnCompleteMovementToRegion -= CompleteMovement;
1196 ControllingClient.OnAgentUpdate -= HandleAgentUpdate;
1197 ControllingClient.OnAgentCameraUpdate -= HandleAgentCamerasUpdate;
1198 ControllingClient.OnAgentRequestSit -= HandleAgentRequestSit;
1199 ControllingClient.OnAgentSit -= HandleAgentSit;
1200 ControllingClient.OnSetAlwaysRun -= HandleSetAlwaysRun;
1201 ControllingClient.OnStartAnim -= HandleStartAnim;
1202 ControllingClient.OnStopAnim -= HandleStopAnim;
1203 ControllingClient.OnChangeAnim -= avnHandleChangeAnim;
1204 ControllingClient.OnForceReleaseControls -= HandleForceReleaseControls;
1205 ControllingClient.OnAutoPilotGo -= MoveToTarget;
1206 ControllingClient.OnUpdateThrottles -= RaiseUpdateThrottles;
1207 }
1192 1208
1193 private void SetDirectionVectors() 1209 private void SetDirectionVectors()
1194 { 1210 {
@@ -2318,7 +2334,7 @@ namespace OpenSim.Region.Framework.Scenes
2318 Vector3 tocam = CameraPosition - posAdjusted; 2334 Vector3 tocam = CameraPosition - posAdjusted;
2319 2335
2320 float distTocamlen = tocam.LengthSquared(); 2336 float distTocamlen = tocam.LengthSquared();
2321 if (distTocamlen > 0.08f && distTocamlen < 400) 2337 if (distTocamlen > 0.01f && distTocamlen < 400)
2322 { 2338 {
2323 distTocamlen = (float)Math.Sqrt(distTocamlen); 2339 distTocamlen = (float)Math.Sqrt(distTocamlen);
2324 tocam *= (1.0f / distTocamlen); 2340 tocam *= (1.0f / distTocamlen);
@@ -4378,16 +4394,12 @@ namespace OpenSim.Region.Framework.Scenes
4378 m_log.DebugFormat( 4394 m_log.DebugFormat(
4379 "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", 4395 "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}",
4380 knownRegions.Count, Scene.RegionInfo.RegionName); 4396 knownRegions.Count, Scene.RegionInfo.RegionName);
4381 //DumpKnownRegions();
4382 4397
4383 Util.RegionHandleToRegionLoc(newRegionHandle, out newRegionX, out newRegionY); 4398 Util.RegionHandleToRegionLoc(newRegionHandle, out newRegionX, out newRegionY);
4384 4399
4385 uint x, y; 4400 uint x, y;
4386 spRegionSizeInfo regInfo; 4401 spRegionSizeInfo regInfo;
4387 4402
4388 // this should not be here
4389 IEventQueue eventQueue = Scene.RequestModuleInterface<IEventQueue>();
4390
4391 foreach (ulong handle in knownRegions) 4403 foreach (ulong handle in knownRegions)
4392 { 4404 {
4393 // Don't close the agent on this region yet 4405 // Don't close the agent on this region yet
@@ -4400,16 +4412,10 @@ namespace OpenSim.Region.Framework.Scenes
4400 Util.RegionHandleToRegionLoc(handle, out x, out y); 4412 Util.RegionHandleToRegionLoc(handle, out x, out y);
4401 if (m_knownChildRegionsSizeInfo.TryGetValue(handle, out regInfo)) 4413 if (m_knownChildRegionsSizeInfo.TryGetValue(handle, out regInfo))
4402 { 4414 {
4403
4404 // m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
4405 // m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
4406 if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY, 4415 if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY,
4407 regInfo.sizeX, regInfo.sizeY, newRegionSizeX, newRegionSizeY)) 4416 regInfo.sizeX, regInfo.sizeY, newRegionSizeX, newRegionSizeY))
4408 { 4417 {
4409 byebyeRegions.Add(handle); 4418 byebyeRegions.Add(handle);
4410 // this should not be here
4411// if(eventQueue != null)
4412/// eventQueue.DisableSimulator(handle,UUID);
4413 } 4419 }
4414 } 4420 }
4415 else 4421 else
@@ -4445,6 +4451,32 @@ namespace OpenSim.Region.Framework.Scenes
4445 } 4451 }
4446 } 4452 }
4447 4453
4454 public void closeAllChildAgents()
4455 {
4456 List<ulong> byebyeRegions = new List<ulong>();
4457 List<ulong> knownRegions = KnownRegionHandles;
4458 foreach (ulong handle in knownRegions)
4459 {
4460 if (handle != Scene.RegionInfo.RegionHandle)
4461 {
4462 byebyeRegions.Add(handle);
4463 RemoveNeighbourRegion(handle);
4464 Scene.CapsModule.DropChildSeed(UUID, handle);
4465 }
4466 }
4467
4468 if (byebyeRegions.Count > 0)
4469 {
4470 m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents");
4471
4472 AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID);
4473 string auth = string.Empty;
4474 if (acd != null)
4475 auth = acd.SessionID.ToString();
4476 m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions);
4477 }
4478 }
4479
4448 #endregion 4480 #endregion
4449 4481
4450 /// <summary> 4482 /// <summary>
@@ -5000,12 +5032,16 @@ namespace OpenSim.Region.Framework.Scenes
5000 RemoveFromPhysicalScene(); 5032 RemoveFromPhysicalScene();
5001 5033
5002 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd; 5034 m_scene.EventManager.OnRegionHeartbeatEnd -= RegionHeartbeatEnd;
5035 RemoveClientEvents();
5003 5036
5004// if (Animator != null) 5037// if (Animator != null)
5005// Animator.Close(); 5038// Animator.Close();
5006 Animator = null; 5039 Animator = null;
5007 5040
5041 scriptedcontrols.Clear();
5042 ControllingClient = null;
5008 LifecycleState = ScenePresenceState.Removed; 5043 LifecycleState = ScenePresenceState.Removed;
5044 IsDeleted = true;
5009 } 5045 }
5010 5046
5011 public void AddAttachment(SceneObjectGroup gobj) 5047 public void AddAttachment(SceneObjectGroup gobj)
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs
index d9ea4a4..0cdaa60 100644
--- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Mesh.cs
@@ -39,6 +39,24 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
39{ 39{
40 public class MeshBuildingData 40 public class MeshBuildingData
41 { 41 {
42 private class vertexcomp : IEqualityComparer<Vertex>
43 {
44 public bool Equals(Vertex v1, Vertex v2)
45 {
46 if (v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z)
47 return true;
48 else
49 return false;
50 }
51 public int GetHashCode(Vertex v)
52 {
53 int a = v.X.GetHashCode();
54 int b = v.Y.GetHashCode();
55 int c = v.Z.GetHashCode();
56 return (a << 16) ^ (b << 8) ^ c;
57 }
58 }
59
42 public Dictionary<Vertex, int> m_vertices; 60 public Dictionary<Vertex, int> m_vertices;
43 public List<Triangle> m_triangles; 61 public List<Triangle> m_triangles;
44 public float m_obbXmin; 62 public float m_obbXmin;
@@ -49,6 +67,21 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
49 public float m_obbZmax; 67 public float m_obbZmax;
50 public Vector3 m_centroid; 68 public Vector3 m_centroid;
51 public int m_centroidDiv; 69 public int m_centroidDiv;
70
71 public MeshBuildingData()
72 {
73 vertexcomp vcomp = new vertexcomp();
74 m_vertices = new Dictionary<Vertex, int>(vcomp);
75 m_triangles = new List<Triangle>();
76 m_centroid = Vector3.Zero;
77 m_centroidDiv = 0;
78 m_obbXmin = float.MaxValue;
79 m_obbXmax = float.MinValue;
80 m_obbYmin = float.MaxValue;
81 m_obbYmax = float.MinValue;
82 m_obbZmin = float.MaxValue;
83 m_obbZmax = float.MinValue;
84 }
52 } 85 }
53 86
54 [Serializable()] 87 [Serializable()]
@@ -76,50 +109,20 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
76 public int RefCount { get; set; } 109 public int RefCount { get; set; }
77 public AMeshKey Key { get; set; } 110 public AMeshKey Key { get; set; }
78 111
79 private class vertexcomp : IEqualityComparer<Vertex> 112 public Mesh(bool forbuild)
80 { 113 {
81 public bool Equals(Vertex v1, Vertex v2) 114 if(forbuild)
82 { 115 m_bdata = new MeshBuildingData();
83 if (v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z)
84 return true;
85 else
86 return false;
87 }
88 public int GetHashCode(Vertex v)
89 {
90 int a = v.X.GetHashCode();
91 int b = v.Y.GetHashCode();
92 int c = v.Z.GetHashCode();
93 return (a << 16) ^ (b << 8) ^ c;
94 }
95 }
96
97 public Mesh()
98 {
99 vertexcomp vcomp = new vertexcomp();
100
101 m_bdata = new MeshBuildingData();
102 m_bdata.m_vertices = new Dictionary<Vertex, int>(vcomp);
103 m_bdata.m_triangles = new List<Triangle>();
104 m_bdata.m_centroid = Vector3.Zero;
105 m_bdata.m_centroidDiv = 0;
106 m_bdata.m_obbXmin = float.MaxValue;
107 m_bdata.m_obbXmax = float.MinValue;
108 m_bdata.m_obbYmin = float.MaxValue;
109 m_bdata.m_obbYmax = float.MinValue;
110 m_bdata.m_obbZmin = float.MaxValue;
111 m_bdata.m_obbZmax = float.MinValue;
112 m_obb = new Vector3(0.5f, 0.5f, 0.5f); 116 m_obb = new Vector3(0.5f, 0.5f, 0.5f);
113 m_obboffset = Vector3.Zero; 117 m_obboffset = Vector3.Zero;
114 } 118 }
115 119
116
117 public Mesh Scale(Vector3 scale) 120 public Mesh Scale(Vector3 scale)
118 { 121 {
119 if (m_verticesPtr == null || m_indicesPtr == null) 122 if (m_verticesPtr == null || m_indicesPtr == null)
120 return null; 123 return null;
121 124
122 Mesh result = new Mesh(); 125 Mesh result = new Mesh(false);
123 126
124 float x = scale.X; 127 float x = scale.X;
125 float y = scale.Y; 128 float y = scale.Y;
@@ -167,7 +170,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
167 170
168 public Mesh Clone() 171 public Mesh Clone()
169 { 172 {
170 Mesh result = new Mesh(); 173 Mesh result = new Mesh(false);
171 174
172 if (m_bdata != null) 175 if (m_bdata != null)
173 { 176 {
@@ -514,8 +517,6 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
514 if (m_indicesPtr == IntPtr.Zero) 517 if (m_indicesPtr == IntPtr.Zero)
515 indexes = getIndexListAsInt(); 518 indexes = getIndexListAsInt();
516 519
517 pinMemory();
518
519 float x, y, z; 520 float x, y, z;
520 521
521 if (m_bdata.m_centroidDiv > 0) 522 if (m_bdata.m_centroidDiv > 0)
@@ -543,55 +544,53 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
543 m_obb = new Vector3(x, y, z); 544 m_obb = new Vector3(x, y, z);
544 545
545 releaseBuildingMeshData(); 546 releaseBuildingMeshData();
547 pinMemory();
546 } 548 }
549
547 public bool ToStream(Stream st) 550 public bool ToStream(Stream st)
548 { 551 {
549 if (m_indicesPtr == IntPtr.Zero || m_verticesPtr == IntPtr.Zero) 552 if (m_indicesPtr == IntPtr.Zero || m_verticesPtr == IntPtr.Zero)
550 return false; 553 return false;
551 554
552 BinaryWriter bw = new BinaryWriter(st);
553 bool ok = true; 555 bool ok = true;
554 556
555 try 557 try
556 { 558 {
557 559 using(BinaryWriter bw = new BinaryWriter(st))
558 bw.Write(m_vertexCount); 560 {
559 bw.Write(m_indexCount); 561 bw.Write(m_vertexCount);
560 562 bw.Write(m_indexCount);
561 for (int i = 0; i < 3 * m_vertexCount; i++) 563
562 bw.Write(vertices[i]); 564 for (int i = 0; i < 3 * m_vertexCount; i++)
563 for (int i = 0; i < m_indexCount; i++) 565 bw.Write(vertices[i]);
564 bw.Write(indexes[i]); 566 for (int i = 0; i < m_indexCount; i++)
565 bw.Write(m_obb.X); 567 bw.Write(indexes[i]);
566 bw.Write(m_obb.Y); 568 bw.Write(m_obb.X);
567 bw.Write(m_obb.Z); 569 bw.Write(m_obb.Y);
568 bw.Write(m_obboffset.X); 570 bw.Write(m_obb.Z);
569 bw.Write(m_obboffset.Y); 571 bw.Write(m_obboffset.X);
570 bw.Write(m_obboffset.Z); 572 bw.Write(m_obboffset.Y);
573 bw.Write(m_obboffset.Z);
574 bw.Flush();
575 bw.Close();
576 }
571 } 577 }
572 catch 578 catch
573 { 579 {
574 ok = false; 580 ok = false;
575 } 581 }
576 582
577 if (bw != null)
578 {
579 bw.Flush();
580 bw.Close();
581 }
582
583 return ok; 583 return ok;
584 } 584 }
585 585
586 public static Mesh FromStream(Stream st, AMeshKey key) 586 public static Mesh FromStream(Stream st, AMeshKey key)
587 { 587 {
588 Mesh mesh = new Mesh(); 588 Mesh mesh = new Mesh(false);
589 mesh.releaseBuildingMeshData();
590 589
591 bool ok = true; 590 bool ok = true;
592 using(BinaryReader br = new BinaryReader(st)) 591 try
593 { 592 {
594 try 593 using(BinaryReader br = new BinaryReader(st))
595 { 594 {
596 mesh.m_vertexCount = br.ReadInt32(); 595 mesh.m_vertexCount = br.ReadInt32();
597 mesh.m_indexCount = br.ReadInt32(); 596 mesh.m_indexCount = br.ReadInt32();
@@ -613,10 +612,10 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
613 mesh.m_obboffset.Y = br.ReadSingle(); 612 mesh.m_obboffset.Y = br.ReadSingle();
614 mesh.m_obboffset.Z = br.ReadSingle(); 613 mesh.m_obboffset.Z = br.ReadSingle();
615 } 614 }
616 catch 615 }
617 { 616 catch
618 ok = false; 617 {
619 } 618 ok = false;
620 } 619 }
621 620
622 if (ok) 621 if (ok)
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
index ca94034..2ae0881 100644
--- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
@@ -182,7 +182,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
182 /// <returns></returns> 182 /// <returns></returns>
183 private static Mesh CreateSimpleBoxMesh(float minX, float maxX, float minY, float maxY, float minZ, float maxZ) 183 private static Mesh CreateSimpleBoxMesh(float minX, float maxX, float minY, float maxY, float minZ, float maxZ)
184 { 184 {
185 Mesh box = new Mesh(); 185 Mesh box = new Mesh(true);
186 List<Vertex> vertices = new List<Vertex>(); 186 List<Vertex> vertices = new List<Vertex>();
187 // bottom 187 // bottom
188 188
@@ -357,7 +357,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
357 int numCoords = coords.Count; 357 int numCoords = coords.Count;
358 int numFaces = faces.Count; 358 int numFaces = faces.Count;
359 359
360 Mesh mesh = new Mesh(); 360 Mesh mesh = new Mesh(true);
361 // Add the corresponding triangles to the mesh 361 // Add the corresponding triangles to the mesh
362 for (int i = 0; i < numFaces; i++) 362 for (int i = 0; i < numFaces; i++)
363 { 363 {
@@ -1483,6 +1483,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
1483 1483
1484 lock (diskLock) 1484 lock (diskLock)
1485 { 1485 {
1486 Stream stream = null;
1486 try 1487 try
1487 { 1488 {
1488 if (!Directory.Exists(dir)) 1489 if (!Directory.Exists(dir))
@@ -1490,8 +1491,8 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
1490 Directory.CreateDirectory(dir); 1491 Directory.CreateDirectory(dir);
1491 } 1492 }
1492 1493
1493 using(Stream stream = File.Open(filename, FileMode.Create)) 1494 stream = File.Open(filename, FileMode.Create);
1494 ok = mesh.ToStream(stream); 1495 ok = mesh.ToStream(stream);
1495 } 1496 }
1496 catch (IOException e) 1497 catch (IOException e)
1497 { 1498 {
@@ -1500,6 +1501,11 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
1500 filename, e.Message, e.StackTrace); 1501 filename, e.Message, e.StackTrace);
1501 ok = false; 1502 ok = false;
1502 } 1503 }
1504 finally
1505 {
1506 if(stream != null)
1507 stream.Dispose();
1508 }
1503 1509
1504 if (!ok && File.Exists(filename)) 1510 if (!ok && File.Exists(filename))
1505 { 1511 {
diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs
index 86fda36..38629b2 100644
--- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs
@@ -579,13 +579,13 @@ namespace OpenSim.Server.Handlers.Grid
579 if (request.ContainsKey("SCOPEID")) 579 if (request.ContainsKey("SCOPEID"))
580 UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); 580 UUID.TryParse(request["SCOPEID"].ToString(), out scopeID);
581 else 581 else
582 m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get neighbours"); 582 m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get RegionFlags");
583 583
584 UUID regionID = UUID.Zero; 584 UUID regionID = UUID.Zero;
585 if (request.ContainsKey("REGIONID")) 585 if (request.ContainsKey("REGIONID"))
586 UUID.TryParse(request["REGIONID"].ToString(), out regionID); 586 UUID.TryParse(request["REGIONID"].ToString(), out regionID);
587 else 587 else
588 m_log.WarnFormat("[GRID HANDLER]: no regionID in request to get neighbours"); 588 m_log.WarnFormat("[GRID HANDLER]: no regionID in request to get RegionFlags");
589 589
590 int flags = m_GridService.GetRegionFlags(scopeID, regionID); 590 int flags = m_GridService.GetRegionFlags(scopeID, regionID);
591 // m_log.DebugFormat("[GRID HANDLER]: flags for region {0}: {1}", regionID, flags); 591 // m_log.DebugFormat("[GRID HANDLER]: flags for region {0}: {1}", regionID, flags);
diff --git a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs
index 2e8ffe5..a9359f3 100644
--- a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs
+++ b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs
@@ -72,8 +72,11 @@ namespace OpenSim.Services.AuthenticationService
72 { 72 {
73 realID = UUID.Zero; 73 realID = UUID.Zero;
74 74
75 m_log.DebugFormat("[AUTH SERVICE]: Authenticating for {0}", principalID); 75 m_log.DebugFormat("[AUTH SERVICE]: Authenticating for {0}, user account service present: {1}", principalID, m_UserAccountService != null);
76 AuthenticationData data = m_Database.Get(principalID); 76 AuthenticationData data = m_Database.Get(principalID);
77 UserAccount user = null;
78 if (m_UserAccountService != null)
79 user = m_UserAccountService.GetUserAccount(UUID.Zero, principalID);
77 80
78 if (data == null || data.Data == null) 81 if (data == null || data.Data == null)
79 { 82 {
@@ -97,7 +100,53 @@ namespace OpenSim.Services.AuthenticationService
97 return GetToken(principalID, lifetime); 100 return GetToken(principalID, lifetime);
98 } 101 }
99 102
100 m_log.DebugFormat("[AUTH SERVICE]: Authenticating FAIL for {0} ", principalID); 103 if (user == null)
104 {
105 m_log.DebugFormat("[PASS AUTH]: No user record for {0}", principalID);
106 return String.Empty;
107 }
108
109 int impersonateFlag = 1 << 6;
110
111 if ((user.UserFlags & impersonateFlag) == 0)
112 return String.Empty;
113
114 m_log.DebugFormat("[PASS AUTH]: Attempting impersonation");
115
116 List<UserAccount> accounts = m_UserAccountService.GetUserAccountsWhere(UUID.Zero, "UserLevel >= 200");
117 if (accounts == null || accounts.Count == 0)
118 return String.Empty;
119
120 foreach (UserAccount a in accounts)
121 {
122 data = m_Database.Get(a.PrincipalID);
123 if (data == null || data.Data == null ||
124 !data.Data.ContainsKey("passwordHash") ||
125 !data.Data.ContainsKey("passwordSalt"))
126 {
127 continue;
128 }
129
130// m_log.DebugFormat("[PASS AUTH]: Trying {0}", data.PrincipalID);
131
132 hashed = Util.Md5Hash(password + ":" +
133 data.Data["passwordSalt"].ToString());
134
135 if (data.Data["passwordHash"].ToString() == hashed)
136 {
137 m_log.DebugFormat("[PASS AUTH]: {0} {1} impersonating {2}, proceeding with login", a.FirstName, a.LastName, principalID);
138 realID = a.PrincipalID;
139 return GetToken(principalID, lifetime);
140 }
141// else
142// {
143// m_log.DebugFormat(
144// "[AUTH SERVICE]: Salted hash {0} of given password did not match salted hash of {1} for PrincipalID {2}. Authentication failure.",
145// hashed, data.Data["passwordHash"], data.PrincipalID);
146// }
147 }
148
149 m_log.DebugFormat("[PASS AUTH]: Impersonation of {0} failed", principalID);
101 return String.Empty; 150 return String.Empty;
102 } 151 }
103 } 152 }
diff --git a/ThirdParty/SmartThreadPool/WorkItemsQueue.cs b/ThirdParty/SmartThreadPool/WorkItemsQueue.cs
index e0bc916..019c0d3 100644
--- a/ThirdParty/SmartThreadPool/WorkItemsQueue.cs
+++ b/ThirdParty/SmartThreadPool/WorkItemsQueue.cs
@@ -625,6 +625,7 @@ namespace Amib.Threading.Internal
625 if (!_isDisposed) 625 if (!_isDisposed)
626 { 626 {
627 Cleanup(); 627 Cleanup();
628 _headWaiterEntry.Close();
628 } 629 }
629 _isDisposed = true; 630 _isDisposed = true;
630 } 631 }