aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Agent
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Agent')
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs109
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs1691
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs90
-rw-r--r--OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs155
-rw-r--r--OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs679
5 files changed, 2724 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs
new file mode 100644
index 0000000..406b715
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs
@@ -0,0 +1,109 @@
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 System.Net;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server;
36
37using Mono.Addins;
38
39namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView
40{
41 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "IRCStackModule")]
42 public class IRCStackModule : INonSharedRegionModule
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 private IRCServer m_server;
47 private int m_Port;
48// private Scene m_scene;
49 private bool m_Enabled;
50
51 #region Implementation of INonSharedRegionModule
52
53 public void Initialise(IConfigSource source)
54 {
55 if (null != source.Configs["IRCd"] &&
56 source.Configs["IRCd"].GetBoolean("Enabled", false))
57 {
58 m_Enabled = true;
59 m_Port = source.Configs["IRCd"].GetInt("Port", 6666);
60 }
61 }
62
63 public void AddRegion(Scene scene)
64 {
65 if (!m_Enabled)
66 return;
67
68 m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), m_Port, scene);
69 m_server.OnNewIRCClient += m_server_OnNewIRCClient;
70 }
71
72 public void RegionLoaded(Scene scene)
73 {
74 }
75
76 public void RemoveRegion(Scene scene)
77 {
78 }
79
80 public void Close()
81 {
82 }
83
84 public string Name
85 {
86 get { return "IRCClientStackModule"; }
87 }
88
89 public Type ReplaceableInterface
90 {
91 get { return null; }
92 }
93
94 #endregion
95
96 void m_server_OnNewIRCClient(IRCClientView user)
97 {
98 user.OnIRCReady += user_OnIRCReady;
99 }
100
101 void user_OnIRCReady(IRCClientView cv)
102 {
103 m_log.Info("[IRCd] Adding user...");
104 cv.Start();
105 m_log.Info("[IRCd] Added user to Scene");
106 }
107
108 }
109}
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
new file mode 100644
index 0000000..6fe86b2
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -0,0 +1,1691 @@
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 System.Collections.Generic;
30using System.IO;
31using System.Net;
32using System.Net.Sockets;
33using System.Reflection;
34using System.Text;
35using System.Threading;
36using log4net;
37using OpenMetaverse;
38using OpenMetaverse.Packets;
39using OpenSim.Framework;
40using OpenSim.Framework.Client;
41using OpenSim.Framework.Monitoring;
42using OpenSim.Region.Framework.Scenes;
43
44namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
45{
46 public delegate void OnIRCClientReadyDelegate(IRCClientView cv);
47
48 public class IRCClientView : IClientAPI, IClientCore
49 {
50 public event OnIRCClientReadyDelegate OnIRCReady;
51
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 private readonly TcpClient m_client;
55 private readonly Scene m_scene;
56
57 private UUID m_agentID = UUID.Random();
58
59 public ISceneAgent SceneAgent { get; set; }
60
61 private string m_username;
62 private string m_nick;
63
64 private bool m_hasNick = false;
65 private bool m_hasUser = false;
66
67 private bool m_connected = true;
68
69 public IRCClientView(TcpClient client, Scene scene)
70 {
71 m_client = client;
72 m_scene = scene;
73
74 WorkManager.StartThread(InternalLoop, "IRCClientView", ThreadPriority.Normal, false, true);
75 }
76
77 private void SendServerCommand(string command)
78 {
79 SendCommand(":opensimircd " + command);
80 }
81
82 private void SendCommand(string command)
83 {
84 m_log.Info("[IRCd] Sending >>> " + command);
85
86 byte[] buf = Util.UTF8.GetBytes(command + "\r\n");
87
88 m_client.GetStream().BeginWrite(buf, 0, buf.Length, SendComplete, null);
89 }
90
91 private void SendComplete(IAsyncResult result)
92 {
93 m_log.Info("[IRCd] Send Complete.");
94 }
95
96 private string IrcRegionName
97 {
98 // I know &Channel is more technically correct, but people are used to seeing #Channel
99 // Dont shoot me!
100 get { return "#" + m_scene.RegionInfo.RegionName.Replace(" ", "-"); }
101 }
102
103 private void InternalLoop()
104 {
105 try
106 {
107 string strbuf = String.Empty;
108
109 while (m_connected && m_client.Connected)
110 {
111 byte[] buf = new byte[8]; // RFC1459 defines max message size as 512.
112
113 int count = m_client.GetStream().Read(buf, 0, buf.Length);
114 string line = Util.UTF8.GetString(buf, 0, count);
115
116 strbuf += line;
117
118 string message = ExtractMessage(strbuf);
119 if (message != null)
120 {
121 // Remove from buffer
122 strbuf = strbuf.Remove(0, message.Length);
123
124 m_log.Info("[IRCd] Recieving <<< " + message);
125 message = message.Trim();
126
127 // Extract command sequence
128 string command = ExtractCommand(message);
129 ProcessInMessage(message, command);
130 }
131 else
132 {
133 //m_log.Info("[IRCd] Recieved data, but not enough to make a message. BufLen is " + strbuf.Length +
134 // "[" + strbuf + "]");
135 if (strbuf.Length == 0)
136 {
137 m_connected = false;
138 m_log.Info("[IRCd] Buffer zero, closing...");
139 if (OnDisconnectUser != null)
140 OnDisconnectUser();
141 }
142 }
143
144 Thread.Sleep(0);
145 Watchdog.UpdateThread();
146 }
147 }
148 catch (IOException)
149 {
150 if (OnDisconnectUser != null)
151 OnDisconnectUser();
152
153 m_log.Warn("[IRCd] Disconnected client.");
154 }
155 catch (SocketException)
156 {
157 if (OnDisconnectUser != null)
158 OnDisconnectUser();
159
160 m_log.Warn("[IRCd] Disconnected client.");
161 }
162
163 Watchdog.RemoveThread();
164 }
165
166 private void ProcessInMessage(string message, string command)
167 {
168 m_log.Info("[IRCd] Processing [MSG:" + message + "] [COM:" + command + "]");
169 if (command != null)
170 {
171 switch (command)
172 {
173 case "ADMIN":
174 case "AWAY":
175 case "CONNECT":
176 case "DIE":
177 case "ERROR":
178 case "INFO":
179 case "INVITE":
180 case "ISON":
181 case "KICK":
182 case "KILL":
183 case "LINKS":
184 case "LUSERS":
185 case "OPER":
186 case "PART":
187 case "REHASH":
188 case "SERVICE":
189 case "SERVLIST":
190 case "SERVER":
191 case "SQUERY":
192 case "SQUIT":
193 case "STATS":
194 case "SUMMON":
195 case "TIME":
196 case "TRACE":
197 case "VERSION":
198 case "WALLOPS":
199 case "WHOIS":
200 case "WHOWAS":
201 SendServerCommand("421 " + command + " :Command unimplemented");
202 break;
203
204 // Connection Commands
205 case "PASS":
206 break; // Ignore for now. I want to implement authentication later however.
207
208 case "JOIN":
209 IRC_SendReplyJoin();
210 break;
211
212 case "MODE":
213 IRC_SendReplyModeChannel();
214 break;
215
216 case "USER":
217 IRC_ProcessUser(message);
218 IRC_Ready();
219 break;
220
221 case "USERHOST":
222 string[] userhostArgs = ExtractParameters(message);
223 if (userhostArgs[0] == ":" + m_nick)
224 {
225 SendServerCommand("302 :" + m_nick + "=+" + m_nick + "@" +
226 ((IPEndPoint) m_client.Client.RemoteEndPoint).Address);
227 }
228 break;
229 case "NICK":
230 IRC_ProcessNick(message);
231 IRC_Ready();
232
233 break;
234 case "TOPIC":
235 IRC_SendReplyTopic();
236 break;
237 case "USERS":
238 IRC_SendReplyUsers();
239 break;
240
241 case "LIST":
242 break; // TODO
243
244 case "MOTD":
245 IRC_SendMOTD();
246 break;
247
248 case "NOTICE": // TODO
249 break;
250
251 case "WHO": // TODO
252 IRC_SendNamesReply();
253 IRC_SendWhoReply();
254 break;
255
256 case "PING":
257 IRC_ProcessPing(message);
258 break;
259
260 // Special case, ignore this completely.
261 case "PONG":
262 break;
263
264 case "QUIT":
265 if (OnDisconnectUser != null)
266 OnDisconnectUser();
267 break;
268
269 case "NAMES":
270 IRC_SendNamesReply();
271 break;
272 case "PRIVMSG":
273 IRC_ProcessPrivmsg(message);
274 break;
275
276 default:
277 SendServerCommand("421 " + command + " :Unknown command");
278 break;
279 }
280 }
281 }
282
283 private void IRC_Ready()
284 {
285 if (m_hasUser && m_hasNick)
286 {
287 SendServerCommand("001 " + m_nick + " :Welcome to OpenSimulator IRCd");
288 SendServerCommand("002 " + m_nick + " :Running OpenSimVersion");
289 SendServerCommand("003 " + m_nick + " :This server was created over 9000 years ago");
290 SendServerCommand("004 " + m_nick + " :opensimirc r1 aoOirw abeiIklmnoOpqrstv");
291 SendServerCommand("251 " + m_nick + " :There are 0 users and 0 services on 1 servers");
292 SendServerCommand("252 " + m_nick + " 0 :operators online");
293 SendServerCommand("253 " + m_nick + " 0 :unknown connections");
294 SendServerCommand("254 " + m_nick + " 1 :channels formed");
295 SendServerCommand("255 " + m_nick + " :I have 1 users, 0 services and 1 servers");
296 SendCommand(":" + m_nick + " MODE " + m_nick + " :+i");
297 SendCommand(":" + m_nick + " JOIN :" + IrcRegionName);
298
299 // Rename to 'Real Name'
300 SendCommand(":" + m_nick + " NICK :" + m_username.Replace(" ", ""));
301 m_nick = m_username.Replace(" ", "");
302
303 IRC_SendReplyJoin();
304 IRC_SendChannelPrivmsg("System", "Welcome to OpenSimulator.");
305 IRC_SendChannelPrivmsg("System", "You are in a maze of twisty little passages, all alike.");
306 IRC_SendChannelPrivmsg("System", "It is pitch black. You are likely to be eaten by a grue.");
307
308 if (OnIRCReady != null)
309 OnIRCReady(this);
310 }
311 }
312
313 private void IRC_SendReplyJoin()
314 {
315 IRC_SendReplyTopic();
316 IRC_SendNamesReply();
317 }
318
319 private void IRC_SendReplyModeChannel()
320 {
321 SendServerCommand("324 " + m_nick + " " + IrcRegionName + " +n");
322 //SendCommand(":" + IrcRegionName + " MODE +n");
323 }
324
325 private void IRC_ProcessUser(string message)
326 {
327 string[] userArgs = ExtractParameters(message);
328 // TODO: unused: string username = userArgs[0];
329 // TODO: unused: string hostname = userArgs[1];
330 // TODO: unused: string servername = userArgs[2];
331 string realname = userArgs[3].Replace(":", "");
332
333 m_username = realname;
334 m_hasUser = true;
335 }
336
337 private void IRC_ProcessNick(string message)
338 {
339 string[] nickArgs = ExtractParameters(message);
340 string nickname = nickArgs[0].Replace(":","");
341 m_nick = nickname;
342 m_hasNick = true;
343 }
344
345 private void IRC_ProcessPing(string message)
346 {
347 string[] pingArgs = ExtractParameters(message);
348 string pingHost = pingArgs[0];
349 SendCommand("PONG " + pingHost);
350 }
351
352 private void IRC_ProcessPrivmsg(string message)
353 {
354 string[] privmsgArgs = ExtractParameters(message);
355 if (privmsgArgs[0] == IrcRegionName)
356 {
357 if (OnChatFromClient != null)
358 {
359 OSChatMessage msg = new OSChatMessage();
360 msg.Sender = this;
361 msg.Channel = 0;
362 msg.From = this.Name;
363 msg.Message = privmsgArgs[1].Replace(":", "");
364 msg.Position = Vector3.Zero;
365 msg.Scene = m_scene;
366 msg.SenderObject = null;
367 msg.SenderUUID = this.AgentId;
368 msg.Type = ChatTypeEnum.Say;
369
370 OnChatFromClient(this, msg);
371 }
372 }
373 else
374 {
375 // Handle as an IM, later.
376 }
377 }
378
379 private void IRC_SendNamesReply()
380 {
381 EntityBase[] users = m_scene.Entities.GetAllByType<ScenePresence>();
382 foreach (EntityBase user in users)
383 {
384 SendServerCommand("353 " + m_nick + " = " + IrcRegionName + " :" + user.Name.Replace(" ", ""));
385 }
386 SendServerCommand("366 " + IrcRegionName + " :End of /NAMES list");
387 }
388
389 private void IRC_SendWhoReply()
390 {
391 EntityBase[] users = m_scene.Entities.GetAllByType<ScenePresence>();
392 foreach (EntityBase user in users)
393 {
394 /*SendServerCommand(String.Format("352 {0} {1} {2} {3} {4} {5} :0 {6}", IrcRegionName,
395 user.Name.Replace(" ", ""), "nohost.com", "opensimircd",
396 user.Name.Replace(" ", ""), 'H', user.Name));*/
397
398 SendServerCommand("352 " + m_nick + " " + IrcRegionName + " n=" + user.Name.Replace(" ", "") + " fakehost.com " + user.Name.Replace(" ", "") + " H " + ":0 " + user.Name);
399
400 //SendServerCommand("352 " + IrcRegionName + " " + user.Name.Replace(" ", "") + " nohost.com irc.opensimulator " + user.Name.Replace(" ", "") + " H " + ":0 " + user.Name);
401 }
402 SendServerCommand("315 " + m_nick + " " + IrcRegionName + " :End of /WHO list");
403 }
404
405 private void IRC_SendMOTD()
406 {
407 SendServerCommand("375 :- OpenSimulator Message of the day -");
408 SendServerCommand("372 :- Hiya!");
409 SendServerCommand("376 :End of /MOTD command");
410 }
411
412 private void IRC_SendReplyTopic()
413 {
414 SendServerCommand("332 " + IrcRegionName + " :OpenSimulator IRC Server");
415 }
416
417 private void IRC_SendReplyUsers()
418 {
419 EntityBase[] users = m_scene.Entities.GetAllByType<ScenePresence>();
420
421 SendServerCommand("392 :UserID Terminal Host");
422
423 if (users.Length == 0)
424 {
425 SendServerCommand("395 :Nobody logged in");
426 return;
427 }
428
429 foreach (EntityBase user in users)
430 {
431 char[] nom = new char[8];
432 char[] term = "terminal_".ToCharArray();
433 char[] host = "hostname".ToCharArray();
434
435 string userName = user.Name.Replace(" ","");
436 for (int i = 0; i < nom.Length; i++)
437 {
438 if (userName.Length < i)
439 nom[i] = userName[i];
440 else
441 nom[i] = ' ';
442 }
443
444 SendServerCommand("393 :" + nom + " " + term + " " + host + "");
445 }
446
447 SendServerCommand("394 :End of users");
448 }
449
450 private static string ExtractMessage(string buffer)
451 {
452 int pos = buffer.IndexOf("\r\n");
453
454 if (pos == -1)
455 return null;
456
457 string command = buffer.Substring(0, pos + 2);
458
459 return command;
460 }
461
462 private static string ExtractCommand(string msg)
463 {
464 string[] msgs = msg.Split(' ');
465
466 if (msgs.Length < 2)
467 {
468 m_log.Warn("[IRCd] Dropped msg: " + msg);
469 return null;
470 }
471
472 if (msgs[0].StartsWith(":"))
473 return msgs[1];
474
475 return msgs[0];
476 }
477
478 private static string[] ExtractParameters(string msg)
479 {
480 string[] msgs = msg.Split(' ');
481 List<string> parms = new List<string>(msgs.Length);
482
483 bool foundCommand = false;
484 string command = ExtractCommand(msg);
485
486
487 for (int i=0;i<msgs.Length;i++)
488 {
489 if (msgs[i] == command)
490 {
491 foundCommand = true;
492 continue;
493 }
494
495 if (foundCommand != true)
496 continue;
497
498 if (i != 0 && msgs[i].StartsWith(":"))
499 {
500 List<string> tmp = new List<string>();
501 for (int j=i;j<msgs.Length;j++)
502 {
503 tmp.Add(msgs[j]);
504 }
505 parms.Add(string.Join(" ", tmp.ToArray()));
506 break;
507 }
508
509 parms.Add(msgs[i]);
510 }
511
512 return parms.ToArray();
513 }
514
515 #region Implementation of IClientAPI
516
517 public Vector3 StartPos
518 {
519 get { return new Vector3(m_scene.RegionInfo.RegionSizeX * 0.5f, m_scene.RegionInfo.RegionSizeY * 0.5f, 50f); }
520 set { }
521 }
522
523 public bool TryGet<T>(out T iface)
524 {
525 iface = default(T);
526 return false;
527 }
528
529 public T Get<T>()
530 {
531 return default(T);
532 }
533
534 public UUID AgentId
535 {
536 get { return m_agentID; }
537 }
538
539 public void Disconnect(string reason)
540 {
541 IRC_SendChannelPrivmsg("System", "You have been eaten by a grue. (" + reason + ")");
542
543 m_connected = false;
544 m_client.Close();
545 }
546
547 public void Disconnect()
548 {
549 IRC_SendChannelPrivmsg("System", "You have been eaten by a grue.");
550
551 m_connected = false;
552 m_client.Close();
553 SceneAgent = null;
554 }
555
556 public UUID SessionId
557 {
558 get { return m_agentID; }
559 }
560
561 public UUID SecureSessionId
562 {
563 get { return m_agentID; }
564 }
565
566 public UUID ActiveGroupId
567 {
568 get { return UUID.Zero; }
569 }
570
571 public string ActiveGroupName
572 {
573 get { return "IRCd User"; }
574 }
575
576 public ulong ActiveGroupPowers
577 {
578 get { return 0; }
579 }
580
581 public ulong GetGroupPowers(UUID groupID)
582 {
583 return 0;
584 }
585
586 public bool IsGroupMember(UUID GroupID)
587 {
588 return false;
589 }
590
591 public string FirstName
592 {
593 get
594 {
595 string[] names = m_username.Split(' ');
596 return names[0];
597 }
598 }
599
600 public string LastName
601 {
602 get
603 {
604 string[] names = m_username.Split(' ');
605 if (names.Length > 1)
606 return names[1];
607 return names[0];
608 }
609 }
610
611 public IScene Scene
612 {
613 get { return m_scene; }
614 }
615
616 public int NextAnimationSequenceNumber
617 {
618 get { return 0; }
619 }
620
621 public string Name
622 {
623 get { return m_username; }
624 }
625
626 public bool IsActive
627 {
628 get { return true; }
629 set { if (!value) Disconnect("IsActive Disconnected?"); }
630 }
631
632 public bool IsLoggingOut
633 {
634 get { return false; }
635 set { }
636 }
637
638 public bool SendLogoutPacketWhenClosing
639 {
640 set { }
641 }
642
643 public uint CircuitCode
644 {
645 get { return (uint)Util.RandomClass.Next(0,int.MaxValue); }
646 }
647
648 public IPEndPoint RemoteEndPoint
649 {
650 get { return (IPEndPoint)m_client.Client.RemoteEndPoint; }
651 }
652
653#pragma warning disable 67
654 public event GenericMessage OnGenericMessage;
655 public event ImprovedInstantMessage OnInstantMessage;
656 public event ChatMessage OnChatFromClient;
657 public event TextureRequest OnRequestTexture;
658 public event RezObject OnRezObject;
659 public event ModifyTerrain OnModifyTerrain;
660 public event BakeTerrain OnBakeTerrain;
661 public event EstateChangeInfo OnEstateChangeInfo;
662 public event EstateManageTelehub OnEstateManageTelehub;
663 public event CachedTextureRequest OnCachedTextureRequest;
664 public event SetAppearance OnSetAppearance;
665 public event AvatarNowWearing OnAvatarNowWearing;
666 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
667 public event RezMultipleAttachmentsFromInv OnRezMultipleAttachmentsFromInv;
668 public event UUIDNameRequest OnDetachAttachmentIntoInv;
669 public event ObjectAttach OnObjectAttach;
670 public event ObjectDeselect OnObjectDetach;
671 public event ObjectDrop OnObjectDrop;
672 public event StartAnim OnStartAnim;
673 public event StopAnim OnStopAnim;
674 public event LinkObjects OnLinkObjects;
675 public event DelinkObjects OnDelinkObjects;
676 public event RequestMapBlocks OnRequestMapBlocks;
677 public event RequestMapName OnMapNameRequest;
678 public event TeleportLocationRequest OnTeleportLocationRequest;
679 public event DisconnectUser OnDisconnectUser;
680 public event RequestAvatarProperties OnRequestAvatarProperties;
681 public event SetAlwaysRun OnSetAlwaysRun;
682 public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
683 public event TeleportCancel OnTeleportCancel;
684 public event DeRezObject OnDeRezObject;
685 public event Action<IClientAPI> OnRegionHandShakeReply;
686 public event GenericCall1 OnRequestWearables;
687 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
688 public event UpdateAgent OnPreAgentUpdate;
689 public event UpdateAgent OnAgentUpdate;
690 public event UpdateAgent OnAgentCameraUpdate;
691 public event AgentRequestSit OnAgentRequestSit;
692 public event AgentSit OnAgentSit;
693 public event AvatarPickerRequest OnAvatarPickerRequest;
694 public event Action<IClientAPI> OnRequestAvatarsData;
695 public event AddNewPrim OnAddPrim;
696 public event FetchInventory OnAgentDataUpdateRequest;
697 public event TeleportLocationRequest OnSetStartLocationRequest;
698 public event RequestGodlikePowers OnRequestGodlikePowers;
699 public event GodKickUser OnGodKickUser;
700 public event ObjectDuplicate OnObjectDuplicate;
701 public event ObjectDuplicateOnRay OnObjectDuplicateOnRay;
702 public event GrabObject OnGrabObject;
703 public event DeGrabObject OnDeGrabObject;
704 public event MoveObject OnGrabUpdate;
705 public event SpinStart OnSpinStart;
706 public event SpinObject OnSpinUpdate;
707 public event SpinStop OnSpinStop;
708 public event UpdateShape OnUpdatePrimShape;
709 public event ObjectExtraParams OnUpdateExtraParams;
710 public event ObjectRequest OnObjectRequest;
711 public event ObjectSelect OnObjectSelect;
712 public event ObjectDeselect OnObjectDeselect;
713 public event GenericCall7 OnObjectDescription;
714 public event GenericCall7 OnObjectName;
715 public event GenericCall7 OnObjectClickAction;
716 public event GenericCall7 OnObjectMaterial;
717 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
718 public event UpdatePrimFlags OnUpdatePrimFlags;
719 public event UpdatePrimTexture OnUpdatePrimTexture;
720 public event UpdateVector OnUpdatePrimGroupPosition;
721 public event UpdateVector OnUpdatePrimSinglePosition;
722 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
723 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
724 public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition;
725 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
726 public event UpdateVector OnUpdatePrimScale;
727 public event UpdateVector OnUpdatePrimGroupScale;
728 public event StatusChange OnChildAgentStatus;
729 public event GenericCall2 OnStopMovement;
730 public event Action<UUID> OnRemoveAvatar;
731 public event ObjectPermissions OnObjectPermissions;
732 public event CreateNewInventoryItem OnCreateNewInventoryItem;
733 public event LinkInventoryItem OnLinkInventoryItem;
734 public event CreateInventoryFolder OnCreateNewInventoryFolder;
735 public event UpdateInventoryFolder OnUpdateInventoryFolder;
736 public event MoveInventoryFolder OnMoveInventoryFolder;
737 public event FetchInventoryDescendents OnFetchInventoryDescendents;
738 public event PurgeInventoryDescendents OnPurgeInventoryDescendents;
739 public event FetchInventory OnFetchInventory;
740 public event RequestTaskInventory OnRequestTaskInventory;
741 public event UpdateInventoryItem OnUpdateInventoryItem;
742 public event CopyInventoryItem OnCopyInventoryItem;
743 public event MoveInventoryItem OnMoveInventoryItem;
744 public event RemoveInventoryFolder OnRemoveInventoryFolder;
745 public event RemoveInventoryItem OnRemoveInventoryItem;
746 public event UDPAssetUploadRequest OnAssetUploadRequest;
747 public event XferReceive OnXferReceive;
748 public event RequestXfer OnRequestXfer;
749 public event ConfirmXfer OnConfirmXfer;
750 public event AbortXfer OnAbortXfer;
751 public event RezScript OnRezScript;
752 public event UpdateTaskInventory OnUpdateTaskInventory;
753 public event MoveTaskInventory OnMoveTaskItem;
754 public event RemoveTaskInventory OnRemoveTaskItem;
755 public event RequestAsset OnRequestAsset;
756 public event UUIDNameRequest OnNameFromUUIDRequest;
757 public event ParcelAccessListRequest OnParcelAccessListRequest;
758 public event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest;
759 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
760 public event ParcelDivideRequest OnParcelDivideRequest;
761 public event ParcelJoinRequest OnParcelJoinRequest;
762 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
763 public event ParcelSelectObjects OnParcelSelectObjects;
764 public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest;
765 public event ParcelAbandonRequest OnParcelAbandonRequest;
766 public event ParcelGodForceOwner OnParcelGodForceOwner;
767 public event ParcelReclaim OnParcelReclaim;
768 public event ParcelReturnObjectsRequest OnParcelReturnObjectsRequest;
769 public event ParcelDeedToGroup OnParcelDeedToGroup;
770 public event RegionInfoRequest OnRegionInfoRequest;
771 public event EstateCovenantRequest OnEstateCovenantRequest;
772 public event FriendActionDelegate OnApproveFriendRequest;
773 public event FriendActionDelegate OnDenyFriendRequest;
774 public event FriendshipTermination OnTerminateFriendship;
775 public event GrantUserFriendRights OnGrantUserRights;
776 public event MoneyTransferRequest OnMoneyTransferRequest;
777 public event EconomyDataRequest OnEconomyDataRequest;
778 public event MoneyBalanceRequest OnMoneyBalanceRequest;
779 public event UpdateAvatarProperties OnUpdateAvatarProperties;
780 public event ParcelBuy OnParcelBuy;
781 public event RequestPayPrice OnRequestPayPrice;
782 public event ObjectSaleInfo OnObjectSaleInfo;
783 public event ObjectBuy OnObjectBuy;
784 public event BuyObjectInventory OnBuyObjectInventory;
785 public event RequestTerrain OnRequestTerrain;
786 public event RequestTerrain OnUploadTerrain;
787 public event ObjectIncludeInSearch OnObjectIncludeInSearch;
788 public event UUIDNameRequest OnTeleportHomeRequest;
789 public event ScriptAnswer OnScriptAnswer;
790 public event AgentSit OnUndo;
791 public event AgentSit OnRedo;
792 public event LandUndo OnLandUndo;
793 public event ForceReleaseControls OnForceReleaseControls;
794 public event GodLandStatRequest OnLandStatRequest;
795 public event DetailedEstateDataRequest OnDetailedEstateDataRequest;
796 public event SetEstateFlagsRequest OnSetEstateFlagsRequest;
797 public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture;
798 public event SetEstateTerrainDetailTexture OnSetEstateTerrainDetailTexture;
799 public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights;
800 public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest;
801 public event SetRegionTerrainSettings OnSetRegionTerrainSettings;
802 public event EstateRestartSimRequest OnEstateRestartSimRequest;
803 public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest;
804 public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest;
805 public event SimulatorBlueBoxMessageRequest OnSimulatorBlueBoxMessageRequest;
806 public event EstateBlueBoxMessageRequest OnEstateBlueBoxMessageRequest;
807 public event EstateDebugRegionRequest OnEstateDebugRegionRequest;
808 public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
809 public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest;
810 public event UUIDNameRequest OnUUIDGroupNameRequest;
811 public event RegionHandleRequest OnRegionHandleRequest;
812 public event ParcelInfoRequest OnParcelInfoRequest;
813 public event RequestObjectPropertiesFamily OnObjectGroupRequest;
814 public event ScriptReset OnScriptReset;
815 public event GetScriptRunning OnGetScriptRunning;
816 public event SetScriptRunning OnSetScriptRunning;
817 public event Action<Vector3, bool, bool> OnAutoPilotGo;
818 public event TerrainUnacked OnUnackedTerrain;
819 public event ActivateGesture OnActivateGesture;
820 public event DeactivateGesture OnDeactivateGesture;
821 public event ObjectOwner OnObjectOwner;
822 public event DirPlacesQuery OnDirPlacesQuery;
823 public event DirFindQuery OnDirFindQuery;
824 public event DirLandQuery OnDirLandQuery;
825 public event DirPopularQuery OnDirPopularQuery;
826 public event DirClassifiedQuery OnDirClassifiedQuery;
827 public event EventInfoRequest OnEventInfoRequest;
828 public event ParcelSetOtherCleanTime OnParcelSetOtherCleanTime;
829 public event MapItemRequest OnMapItemRequest;
830 public event OfferCallingCard OnOfferCallingCard;
831 public event AcceptCallingCard OnAcceptCallingCard;
832 public event DeclineCallingCard OnDeclineCallingCard;
833 public event SoundTrigger OnSoundTrigger;
834 public event StartLure OnStartLure;
835 public event TeleportLureRequest OnTeleportLureRequest;
836 public event NetworkStats OnNetworkStatsUpdate;
837 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
838 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
839 public event ClassifiedDelete OnClassifiedDelete;
840 public event ClassifiedDelete OnClassifiedGodDelete;
841 public event EventNotificationAddRequest OnEventNotificationAddRequest;
842 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
843 public event EventGodDelete OnEventGodDelete;
844 public event ParcelDwellRequest OnParcelDwellRequest;
845 public event UserInfoRequest OnUserInfoRequest;
846 public event UpdateUserInfo OnUpdateUserInfo;
847 public event RetrieveInstantMessages OnRetrieveInstantMessages;
848 public event PickDelete OnPickDelete;
849 public event PickGodDelete OnPickGodDelete;
850 public event PickInfoUpdate OnPickInfoUpdate;
851 public event AvatarNotesUpdate OnAvatarNotesUpdate;
852 public event MuteListRequest OnMuteListRequest;
853 public event AvatarInterestUpdate OnAvatarInterestUpdate;
854 public event PlacesQuery OnPlacesQuery;
855 public event FindAgentUpdate OnFindAgent;
856 public event TrackAgentUpdate OnTrackAgent;
857 public event NewUserReport OnUserReport;
858 public event SaveStateHandler OnSaveState;
859 public event GroupAccountSummaryRequest OnGroupAccountSummaryRequest;
860 public event GroupAccountDetailsRequest OnGroupAccountDetailsRequest;
861 public event GroupAccountTransactionsRequest OnGroupAccountTransactionsRequest;
862 public event FreezeUserUpdate OnParcelFreezeUser;
863 public event EjectUserUpdate OnParcelEjectUser;
864 public event ParcelBuyPass OnParcelBuyPass;
865 public event ParcelGodMark OnParcelGodMark;
866 public event GroupActiveProposalsRequest OnGroupActiveProposalsRequest;
867 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
868 public event SimWideDeletesDelegate OnSimWideDeletes;
869 public event SendPostcard OnSendPostcard;
870 public event MuteListEntryUpdate OnUpdateMuteListEntry;
871 public event MuteListEntryRemove OnRemoveMuteListEntry;
872 public event GodlikeMessage onGodlikeMessage;
873 public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate;
874
875#pragma warning restore 67
876
877 public int DebugPacketLevel { get; set; }
878
879 public void InPacket(object NewPack)
880 {
881
882 }
883
884 public void ProcessInPacket(Packet NewPack)
885 {
886
887 }
888
889 public void Close()
890 {
891 Close(false);
892 }
893
894 public void Close(bool force)
895 {
896 Disconnect();
897 }
898
899 public void Kick(string message)
900 {
901 Disconnect(message);
902 }
903
904 public void Start()
905 {
906 m_scene.AddNewAgent(this, PresenceType.User);
907
908 // Mimicking LLClientView which gets always set appearance from client.
909 AvatarAppearance appearance;
910 m_scene.GetAvatarAppearance(this, out appearance);
911 OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize, new WearableCacheItem[0]);
912 }
913
914 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
915 {
916 m_log.Info("[IRCd ClientStack] Completing Handshake to Region");
917
918 if (OnRegionHandShakeReply != null)
919 {
920 OnRegionHandShakeReply(this);
921 }
922
923 if (OnCompleteMovementToRegion != null)
924 {
925 OnCompleteMovementToRegion(this, true);
926 }
927 }
928
929 public void Stop()
930 {
931 Disconnect();
932 }
933
934 public void SendWearables(AvatarWearable[] wearables, int serial)
935 {
936
937 }
938
939 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
940 {
941
942 }
943
944 public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures)
945 {
946
947 }
948
949 public void SendStartPingCheck(byte seq)
950 {
951
952 }
953
954 public void SendKillObject(List<uint> localID)
955 {
956
957 }
958
959 public void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
960 {
961
962 }
963
964 public void SendChatMessage(
965 string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source, byte audible)
966 {
967 if (audible > 0 && message.Length > 0)
968 IRC_SendChannelPrivmsg(fromName, message);
969 }
970
971 private void IRC_SendChannelPrivmsg(string fromName, string message)
972 {
973 SendCommand(":" + fromName.Replace(" ", "") + " PRIVMSG " + IrcRegionName + " :" + message);
974 }
975
976 public void SendInstantMessage(GridInstantMessage im)
977 {
978 // TODO
979 }
980
981 public void SendGenericMessage(string method, UUID invoice, List<string> message)
982 {
983
984 }
985
986 public void SendGenericMessage(string method, UUID invoice, List<byte[]> message)
987 {
988
989 }
990
991 public void SendLayerData(float[] map)
992 {
993
994 }
995
996 public void SendLayerData(int px, int py, float[] map)
997 {
998
999 }
1000
1001 public void SendWindData(Vector2[] windSpeeds)
1002 {
1003
1004 }
1005
1006 public void SendCloudData(float[] cloudCover)
1007 {
1008
1009 }
1010
1011 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
1012 {
1013
1014 }
1015
1016 public void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint)
1017 {
1018
1019 }
1020
1021 public AgentCircuitData RequestClientInfo()
1022 {
1023 return new AgentCircuitData();
1024 }
1025
1026 public void CrossRegion(ulong newRegionHandle, Vector3 pos, Vector3 lookAt, IPEndPoint newRegionExternalEndPoint, string capsURL)
1027 {
1028
1029 }
1030
1031 public void SendMapBlock(List<MapBlockData> mapBlocks, uint flag)
1032 {
1033
1034 }
1035
1036 public void SendLocalTeleport(Vector3 position, Vector3 lookAt, uint flags)
1037 {
1038
1039 }
1040
1041 public void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, uint flags, string capsURL)
1042 {
1043
1044 }
1045
1046 public void SendTeleportFailed(string reason)
1047 {
1048
1049 }
1050
1051 public void SendTeleportStart(uint flags)
1052 {
1053
1054 }
1055
1056 public void SendTeleportProgress(uint flags, string message)
1057 {
1058 }
1059
1060 public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance, int transactionType, UUID sourceID, bool sourceIsGroup, UUID destID, bool destIsGroup, int amount, string item)
1061 {
1062
1063 }
1064
1065 public void SendPayPrice(UUID objectID, int[] payPrice)
1066 {
1067
1068 }
1069
1070 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
1071 {
1072
1073 }
1074
1075 public void SendAvatarDataImmediate(ISceneEntity avatar)
1076 {
1077
1078 }
1079
1080 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
1081 {
1082
1083 }
1084
1085 public void ReprioritizeUpdates()
1086 {
1087
1088 }
1089
1090 public void FlushPrimUpdates()
1091 {
1092
1093 }
1094
1095 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems)
1096 {
1097
1098 }
1099
1100 public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
1101 {
1102
1103 }
1104
1105 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
1106 {
1107
1108 }
1109
1110 public void SendRemoveInventoryItem(UUID itemID)
1111 {
1112
1113 }
1114
1115 public void SendTakeControls(int controls, bool passToAgent, bool TakeControls)
1116 {
1117
1118 }
1119
1120 public void SendTaskInventory(UUID taskID, short serial, byte[] fileName)
1121 {
1122
1123 }
1124
1125 public void SendBulkUpdateInventory(InventoryNodeBase node)
1126 {
1127
1128 }
1129
1130 public void SendXferPacket(ulong xferID, uint packet, byte[] data)
1131 {
1132
1133 }
1134
1135 public void SendAbortXferPacket(ulong xferID)
1136 {
1137
1138 }
1139
1140 public void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor, int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent)
1141 {
1142
1143 }
1144
1145 public void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data)
1146 {
1147
1148 }
1149
1150 public void SendAgentDataUpdate(UUID agentid, UUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle)
1151 {
1152
1153 }
1154
1155 public void SendPreLoadSound(UUID objectID, UUID ownerID, UUID soundID)
1156 {
1157
1158 }
1159
1160 public void SendPlayAttachedSound(UUID soundID, UUID objectID, UUID ownerID, float gain, byte flags)
1161 {
1162
1163 }
1164
1165 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
1166 {
1167
1168 }
1169
1170 public void SendAttachedSoundGainChange(UUID objectID, float gain)
1171 {
1172
1173 }
1174
1175 public void SendNameReply(UUID profileId, string firstname, string lastname)
1176 {
1177
1178 }
1179
1180 public void SendAlertMessage(string message)
1181 {
1182 IRC_SendChannelPrivmsg("Alert",message);
1183 }
1184
1185 public void SendAgentAlertMessage(string message, bool modal)
1186 {
1187
1188 }
1189
1190 public void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url)
1191 {
1192 IRC_SendChannelPrivmsg(objectname,url);
1193 }
1194
1195 public void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
1196 {
1197
1198 }
1199
1200 public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition)
1201 {
1202
1203 }
1204
1205 public void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks)
1206 {
1207
1208 }
1209
1210 public void SendViewerTime(int phase)
1211 {
1212
1213 }
1214
1215 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, byte[] charterMember, string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID)
1216 {
1217
1218 }
1219
1220 public void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question)
1221 {
1222
1223 }
1224
1225 public void SendHealth(float health)
1226 {
1227
1228 }
1229
1230 public void SendEstateList(UUID invoice, int code, UUID[] Data, uint estateID)
1231 {
1232
1233 }
1234
1235 public void SendBannedUserList(UUID invoice, EstateBan[] banlist, uint estateID)
1236 {
1237
1238 }
1239
1240 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
1241 {
1242
1243 }
1244
1245 public void SendEstateCovenantInformation(UUID covenant)
1246 {
1247
1248 }
1249
1250 public void SendDetailedEstateData(UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition, UUID covenant, uint covenantChanged, string abuseEmail, UUID estateOwner)
1251 {
1252
1253 }
1254
1255 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, ILandObject lo, float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags)
1256 {
1257
1258 }
1259
1260 public void SendLandAccessListData(List<LandAccessEntry> accessList, uint accessFlag, int localLandID)
1261 {
1262
1263 }
1264
1265 public void SendForceClientSelectObjects(List<uint> objectIDs)
1266 {
1267
1268 }
1269
1270 public void SendCameraConstraint(Vector4 ConstraintPlane)
1271 {
1272
1273 }
1274
1275 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
1276 {
1277
1278 }
1279
1280 public void SendLandParcelOverlay(byte[] data, int sequence_id)
1281 {
1282
1283 }
1284
1285 public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
1286 {
1287
1288 }
1289
1290 public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID, byte autoScale, string mediaType, string mediaDesc, int mediaWidth, int mediaHeight, byte mediaLoop)
1291 {
1292
1293 }
1294
1295 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
1296 {
1297
1298 }
1299
1300 public void SendConfirmXfer(ulong xferID, uint PacketID)
1301 {
1302
1303 }
1304
1305 public void SendXferRequest(ulong XferID, short AssetType, UUID vFileID, byte FilePath, byte[] FileName)
1306 {
1307
1308 }
1309
1310 public void SendInitiateDownload(string simFileName, string clientFileName)
1311 {
1312
1313 }
1314
1315 public void SendImageFirstPart(ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec)
1316 {
1317
1318 }
1319
1320 public void SendImageNextPart(ushort partNumber, UUID imageUuid, byte[] imageData)
1321 {
1322
1323 }
1324
1325 public void SendImageNotFound(UUID imageid)
1326 {
1327
1328 }
1329
1330 public void SendShutdownConnectionNotice()
1331 {
1332 // TODO
1333 }
1334
1335 public void SendSimStats(SimStats stats)
1336 {
1337
1338 }
1339
1340 public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags)
1341 {
1342
1343 }
1344
1345 public void SendObjectPropertiesReply(ISceneEntity entity)
1346 {
1347 }
1348
1349 public void SendAgentOffline(UUID[] agentIDs)
1350 {
1351
1352 }
1353
1354 public void SendAgentOnline(UUID[] agentIDs)
1355 {
1356
1357 }
1358
1359 public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook)
1360 {
1361
1362 }
1363
1364 public void SendAdminResponse(UUID Token, uint AdminLevel)
1365 {
1366
1367 }
1368
1369 public void SendGroupMembership(GroupMembershipData[] GroupMembership)
1370 {
1371
1372 }
1373
1374 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
1375 {
1376
1377 }
1378
1379 public void SendJoinGroupReply(UUID groupID, bool success)
1380 {
1381
1382 }
1383
1384 public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success)
1385 {
1386
1387 }
1388
1389 public void SendLeaveGroupReply(UUID groupID, bool success)
1390 {
1391
1392 }
1393
1394 public void SendCreateGroupReply(UUID groupID, bool success, string message)
1395 {
1396
1397 }
1398
1399 public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia)
1400 {
1401
1402 }
1403
1404 public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running)
1405 {
1406
1407 }
1408
1409 public void SendAsset(AssetRequestToClient req)
1410 {
1411
1412 }
1413
1414 public void SendTexture(AssetBase TextureAsset)
1415 {
1416
1417 }
1418
1419 public virtual void SetChildAgentThrottle(byte[] throttle)
1420 {
1421
1422 }
1423
1424 public byte[] GetThrottlesPacked(float multiplier)
1425 {
1426 return new byte[0];
1427 }
1428
1429#pragma warning disable 0067
1430 public event ViewerEffectEventHandler OnViewerEffect;
1431 public event Action<IClientAPI> OnLogout;
1432 public event Action<IClientAPI> OnConnectionClosed;
1433#pragma warning restore 0067
1434
1435 public void SendBlueBoxMessage(UUID FromAvatarID, string FromAvatarName, string Message)
1436 {
1437 IRC_SendChannelPrivmsg(FromAvatarName, Message);
1438 }
1439
1440 public void SendLogoutPacket()
1441 {
1442 Disconnect();
1443 }
1444
1445 public ClientInfo GetClientInfo()
1446 {
1447 return new ClientInfo();
1448 }
1449
1450 public void SetClientInfo(ClientInfo info)
1451 {
1452
1453 }
1454
1455 public void SetClientOption(string option, string value)
1456 {
1457
1458 }
1459
1460 public string GetClientOption(string option)
1461 {
1462 return String.Empty;
1463 }
1464
1465 public void Terminate()
1466 {
1467 Disconnect();
1468 }
1469
1470 public void SendSetFollowCamProperties(UUID objectID, SortedDictionary<int, float> parameters)
1471 {
1472
1473 }
1474
1475 public void SendClearFollowCamProperties(UUID objectID)
1476 {
1477
1478 }
1479
1480 public void SendRegionHandle(UUID regoinID, ulong handle)
1481 {
1482
1483 }
1484
1485 public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y)
1486 {
1487
1488 }
1489
1490 public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt)
1491 {
1492
1493 }
1494
1495 public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data)
1496 {
1497
1498 }
1499
1500 public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data)
1501 {
1502
1503 }
1504
1505 public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data)
1506 {
1507
1508 }
1509
1510 public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data)
1511 {
1512
1513 }
1514
1515 public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data)
1516 {
1517
1518 }
1519
1520 public void SendDirLandReply(UUID queryID, DirLandReplyData[] data)
1521 {
1522
1523 }
1524
1525 public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data)
1526 {
1527
1528 }
1529
1530 public void SendEventInfoReply(EventData info)
1531 {
1532
1533 }
1534
1535 public void SendTelehubInfo(UUID ObjectID, string ObjectName, Vector3 ObjectPos, Quaternion ObjectRot, List<Vector3> SpawnPoint)
1536 {
1537
1538 }
1539
1540 public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags)
1541 {
1542
1543 }
1544
1545 public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data)
1546 {
1547
1548 }
1549
1550 public void SendOfferCallingCard(UUID srcID, UUID transactionID)
1551 {
1552
1553 }
1554
1555 public void SendAcceptCallingCard(UUID transactionID)
1556 {
1557
1558 }
1559
1560 public void SendDeclineCallingCard(UUID transactionID)
1561 {
1562
1563 }
1564
1565 public void SendTerminateFriend(UUID exFriendID)
1566 {
1567
1568 }
1569
1570 public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name)
1571 {
1572
1573 }
1574
1575 public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price)
1576 {
1577
1578 }
1579
1580 public void SendAgentDropGroup(UUID groupID)
1581 {
1582
1583 }
1584
1585 public void RefreshGroupMembership()
1586 {
1587
1588 }
1589
1590 public void SendAvatarNotesReply(UUID targetID, string text)
1591 {
1592
1593 }
1594
1595 public void SendAvatarPicksReply(UUID targetID, Dictionary<UUID, string> picks)
1596 {
1597
1598 }
1599
1600 public void SendPickInfoReply(UUID pickID, UUID creatorID, bool topPick, UUID parcelID, string name, string desc, UUID snapshotID, string user, string originalName, string simName, Vector3 posGlobal, int sortOrder, bool enabled)
1601 {
1602
1603 }
1604
1605 public void SendAvatarClassifiedReply(UUID targetID, Dictionary<UUID, string> classifieds)
1606 {
1607
1608 }
1609
1610 public void SendAvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages)
1611 {
1612
1613 }
1614
1615 public void SendParcelDwellReply(int localID, UUID parcelID, float dwell)
1616 {
1617
1618 }
1619
1620 public void SendUserInfoReply(bool imViaEmail, bool visible, string email)
1621 {
1622
1623 }
1624
1625 public void SendUseCachedMuteList()
1626 {
1627
1628 }
1629
1630 public void SendMuteListUpdate(string filename)
1631 {
1632
1633 }
1634
1635 public bool AddGenericPacketHandler(string MethodName, GenericMessage handler)
1636 {
1637 return true;
1638 }
1639
1640 #endregion
1641
1642 public void SendRebakeAvatarTextures(UUID textureID)
1643 {
1644 }
1645
1646 public void SendAvatarInterestsReply(UUID avatarID, uint wantMask, string wantText, uint skillsMask, string skillsText, string languages)
1647 {
1648 }
1649
1650 public void SendGroupAccountingDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID, int amt)
1651 {
1652 }
1653
1654 public void SendGroupAccountingSummary(IClientAPI sender,UUID groupID, uint moneyAmt, int totalTier, int usedTier)
1655 {
1656 }
1657
1658 public void SendGroupTransactionsSummaryDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID,int amt)
1659 {
1660 }
1661
1662 public void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes)
1663 {
1664 }
1665
1666 public void SendGroupActiveProposals(UUID groupID, UUID transactionID, GroupActiveProposals[] Proposals)
1667 {
1668 }
1669
1670 public void SendChangeUserRights(UUID agentID, UUID friendID, int rights)
1671 {
1672 }
1673
1674 public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
1675 {
1676 }
1677
1678 public void SendAgentTerseUpdate(ISceneEntity presence)
1679 {
1680 }
1681
1682 public void SendPlacesReply(UUID queryID, UUID transactionID, PlacesReplyData[] data)
1683 {
1684 }
1685
1686 public void SendPartPhysicsProprieties(ISceneEntity entity)
1687 {
1688 }
1689
1690 }
1691}
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
new file mode 100644
index 0000000..a1682d2
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCServer.cs
@@ -0,0 +1,90 @@
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 System.Collections.Generic;
30using System.Net;
31using System.Net.Sockets;
32using System.Reflection;
33using System.Text;
34using System.Threading;
35using log4net;
36using OpenSim.Framework;
37using OpenSim.Framework.Monitoring;
38using OpenSim.Region.Framework.Scenes;
39
40namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
41{
42 public delegate void OnNewIRCUserDelegate(IRCClientView user);
43
44 /// <summary>
45 /// Adam's completely hacked up not-probably-compliant RFC1459 server class.
46 /// </summary>
47 class IRCServer
48 {
49 public event OnNewIRCUserDelegate OnNewIRCClient;
50
51 private readonly TcpListener m_listener;
52 private readonly Scene m_baseScene;
53 private bool m_running = true;
54
55 public IRCServer(IPAddress listener, int port, Scene baseScene)
56 {
57 m_listener = new TcpListener(listener, port);
58
59 m_listener.Start(50);
60
61 WorkManager.StartThread(ListenLoop, "IRCServer", ThreadPriority.Normal, false, true);
62 m_baseScene = baseScene;
63 }
64
65 public void Stop()
66 {
67 m_running = false;
68 m_listener.Stop();
69 }
70
71 private void ListenLoop()
72 {
73 while (m_running)
74 {
75 AcceptClient(m_listener.AcceptTcpClient());
76 Watchdog.UpdateThread();
77 }
78
79 Watchdog.RemoveThread();
80 }
81
82 private void AcceptClient(TcpClient client)
83 {
84 IRCClientView cv = new IRCClientView(client, m_baseScene);
85
86 if (OnNewIRCClient != null)
87 OnNewIRCClient(cv);
88 }
89 }
90}
diff --git a/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs b/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs
new file mode 100644
index 0000000..c897aa5
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs
@@ -0,0 +1,155 @@
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 System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Text;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenMetaverse;
37using OpenMetaverse.Imaging;
38using OpenSim.Framework;
39using OpenSim.Framework.Console;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42
43namespace OpenSim.Region.OptionalModules.Agent.TextureSender
44{
45 /// <summary>
46 /// Commands for the J2KDecoder module. For debugging purposes.
47 /// </summary>
48 /// <remarks>
49 /// Placed here so that they can be removed if not required and to keep the J2KDecoder module itself simple.
50 /// </remarks>
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "J2KDecoderCommandModule")]
52 public class J2KDecoderCommandModule : ISharedRegionModule
53 {
54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Scene m_scene;
57
58 public string Name { get { return "Asset Information Module"; } }
59
60 public Type ReplaceableInterface { get { return null; } }
61
62 public void Initialise(IConfigSource source)
63 {
64// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: INITIALIZED MODULE");
65 }
66
67 public void PostInitialise()
68 {
69// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: POST INITIALIZED MODULE");
70 }
71
72 public void Close()
73 {
74// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: CLOSED MODULE");
75 }
76
77 public void AddRegion(Scene scene)
78 {
79// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
80 }
81
82 public void RemoveRegion(Scene scene)
83 {
84// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
85 }
86
87 public void RegionLoaded(Scene scene)
88 {
89// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
90
91 if (m_scene == null)
92 m_scene = scene;
93
94 MainConsole.Instance.Commands.AddCommand(
95 "Assets",
96 false,
97 "j2k decode",
98 "j2k decode <ID>",
99 "Do JPEG2000 decoding of an asset.",
100 "This is for debugging purposes. The asset id given must contain JPEG2000 data.",
101 HandleDecode);
102 }
103
104 void HandleDecode(string module, string[] args)
105 {
106 if (args.Length < 3)
107 {
108 MainConsole.Instance.Output("Usage is j2k decode <ID>");
109 return;
110 }
111
112 UUID assetId;
113 string rawAssetId = args[2];
114
115 if (!UUID.TryParse(rawAssetId, out assetId))
116 {
117 MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid ID format", rawAssetId);
118 return;
119 }
120
121 AssetBase asset = m_scene.AssetService.Get(assetId.ToString());
122 if (asset == null)
123 {
124 MainConsole.Instance.OutputFormat("ERROR: No asset found with ID {0}", assetId);
125 return;
126 }
127
128 if (asset.Type != (sbyte)AssetType.Texture)
129 {
130 MainConsole.Instance.OutputFormat("ERROR: Asset {0} is not a texture type", assetId);
131 return;
132 }
133
134 IJ2KDecoder decoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
135 if (decoder == null)
136 {
137 MainConsole.Instance.OutputFormat("ERROR: No IJ2KDecoder module available");
138 return;
139 }
140
141 OpenJPEG.J2KLayerInfo[] layers;
142 int components;
143 if (decoder.Decode(assetId, asset.Data, out layers, out components))
144 {
145 MainConsole.Instance.OutputFormat(
146 "Successfully decoded asset {0} with {1} layers and {2} components",
147 assetId, layers.Length, components);
148 }
149 else
150 {
151 MainConsole.Instance.OutputFormat("Decode of asset {0} failed", assetId);
152 }
153 }
154 }
155} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
new file mode 100644
index 0000000..08d0fbf
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
@@ -0,0 +1,679 @@
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 System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Text;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Console;
39using OpenSim.Framework.Monitoring;
40using OpenSim.Region.ClientStack.LindenUDP;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43
44namespace OpenSim.Region.OptionalModules.UDP.Linden
45{
46 /// <summary>
47 /// A module that just holds commands for inspecting the current state of the Linden UDP stack.
48 /// </summary>
49 /// <remarks>
50 /// All actual client stack functionality remains in OpenSim.Region.ClientStack.LindenUDP
51 /// </remarks>
52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LindenUDPInfoModule")]
53 public class LindenUDPInfoModule : ISharedRegionModule
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
58
59 public string Name { get { return "Linden UDP Module"; } }
60
61 public Type ReplaceableInterface { get { return null; } }
62
63 public void Initialise(IConfigSource source)
64 {
65// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: INITIALIZED MODULE");
66 }
67
68 public void PostInitialise()
69 {
70// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: POST INITIALIZED MODULE");
71 }
72
73 public void Close()
74 {
75// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: CLOSED MODULE");
76 }
77
78 public void AddRegion(Scene scene)
79 {
80// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
81
82 lock (m_scenes)
83 m_scenes[scene.RegionInfo.RegionID] = scene;
84
85 scene.AddCommand(
86 "Comms", this, "show pqueues",
87 "show pqueues [full]",
88 "Show priority queue data for each client",
89 "Without the 'full' option, only root agents are shown."
90 + " With the 'full' option child agents are also shown.",
91 (mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd)));
92
93 scene.AddCommand(
94 "Comms", this, "show queues",
95 "show queues [full]",
96 "Show queue data for each client",
97 "Without the 'full' option, only root agents are shown.\n"
98 + "With the 'full' option child agents are also shown.\n\n"
99 + "Type - Rt is a root (avatar) client whilst cd is a child (neighbour interacting) client.\n"
100 + "Since Last In - Time in milliseconds since last packet received.\n"
101 + "Pkts In - Number of packets processed from the client.\n"
102 + "Pkts Out - Number of packets sent to the client.\n"
103 + "Pkts Resent - Number of packets resent to the client.\n"
104 + "Bytes Unacked - Number of bytes transferred to the client that are awaiting acknowledgement.\n"
105 + "Q Pkts * - Number of packets of various types (land, wind, etc.) to be sent to the client that are waiting for available bandwidth.\n",
106 (mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd)));
107
108 scene.AddCommand(
109 "Comms", this, "show image queues",
110 "show image queues <first-name> <last-name>",
111 "Show the image queues (textures downloaded via UDP) for a particular client.",
112 (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
113
114 scene.AddCommand(
115 "Comms", this, "clear image queues",
116 "clear image queues <first-name> <last-name>",
117 "Clear the image queues (textures downloaded via UDP) for a particular client.",
118 (mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
119
120 scene.AddCommand(
121 "Comms", this, "show throttles",
122 "show throttles [full]",
123 "Show throttle settings for each client and for the server overall",
124 "Without the 'full' option, only root agents are shown."
125 + " With the 'full' option child agents are also shown.",
126 (mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd)));
127
128 scene.AddCommand(
129 "Comms", this, "emergency-monitoring",
130 "emergency-monitoring",
131 "Go on/off emergency monitoring mode",
132 "Go on/off emergency monitoring mode",
133 HandleEmergencyMonitoring);
134
135 scene.AddCommand(
136 "Comms", this, "show client stats",
137 "show client stats [first_name last_name]",
138 "Show client request stats",
139 "Without the 'first_name last_name' option, all clients are shown."
140 + " With the 'first_name last_name' option only a specific client is shown.",
141 (mod, cmd) => MainConsole.Instance.Output(HandleClientStatsReport(cmd)));
142
143 }
144
145 public void RemoveRegion(Scene scene)
146 {
147// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
148
149 lock (m_scenes)
150 m_scenes.Remove(scene.RegionInfo.RegionID);
151 }
152
153 public void RegionLoaded(Scene scene)
154 {
155// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
156 }
157
158 protected string HandleImageQueuesClear(string[] cmd)
159 {
160 if (cmd.Length != 5)
161 return "Usage: image queues clear <first-name> <last-name>";
162
163 string firstName = cmd[3];
164 string lastName = cmd[4];
165
166 List<ScenePresence> foundAgents = new List<ScenePresence>();
167
168 lock (m_scenes)
169 {
170 foreach (Scene scene in m_scenes.Values)
171 {
172 ScenePresence sp = scene.GetScenePresence(firstName, lastName);
173 if (sp != null)
174 foundAgents.Add(sp);
175 }
176 }
177
178 if (foundAgents.Count == 0)
179 return string.Format("No agents found for {0} {1}", firstName, lastName);
180
181 StringBuilder report = new StringBuilder();
182
183 foreach (ScenePresence agent in foundAgents)
184 {
185 LLClientView client = agent.ControllingClient as LLClientView;
186
187 if (client == null)
188 return "This command is only supported for LLClientView";
189
190 int requestsDeleted = client.ImageManager.ClearImageQueue();
191
192 report.AppendFormat(
193 "In region {0} ({1} agent) cleared {2} requests\n",
194 agent.Scene.RegionInfo.RegionName, agent.IsChildAgent ? "child" : "root", requestsDeleted);
195 }
196
197 return report.ToString();
198 }
199
200 protected void HandleEmergencyMonitoring(string module, string[] cmd)
201 {
202 bool mode = true;
203 if (cmd.Length == 1 || (cmd.Length > 1 && cmd[1] == "on"))
204 {
205 mode = true;
206 MainConsole.Instance.Output("Emergency Monitoring ON");
207 }
208 else
209 {
210 mode = false;
211 MainConsole.Instance.Output("Emergency Monitoring OFF");
212 }
213
214 foreach (Scene s in m_scenes.Values)
215 s.EmergencyMonitoring = mode;
216 }
217
218 protected string GetColumnEntry(string entry, int maxLength, int columnPadding)
219 {
220 return string.Format(
221 "{0,-" + maxLength + "}{1,-" + columnPadding + "}",
222 entry.Length > maxLength ? entry.Substring(0, maxLength) : entry,
223 "");
224 }
225
226 /// <summary>
227 /// Generate UDP Queue data report for each client
228 /// </summary>
229 /// <param name="showParams"></param>
230 /// <returns></returns>
231 protected string GetPQueuesReport(string[] showParams)
232 {
233 bool showChildren = false;
234 string pname = "";
235
236 if (showParams.Length > 2 && showParams[2] == "full")
237 showChildren = true;
238 else if (showParams.Length > 3)
239 pname = showParams[2] + " " + showParams[3];
240
241 StringBuilder report = new StringBuilder();
242
243 int columnPadding = 2;
244 int maxNameLength = 18;
245 int maxRegionNameLength = 14;
246 int maxTypeLength = 4;
247// int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
248
249 report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
250 report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
251 report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
252
253 report.AppendFormat(
254 "{0,7} {1,7} {2,7} {3,7} {4,7} {5,7} {6,7} {7,7} {8,7} {9,7} {10,7} {11,7}\n",
255 "Pri 0",
256 "Pri 1",
257 "Pri 2",
258 "Pri 3",
259 "Pri 4",
260 "Pri 5",
261 "Pri 6",
262 "Pri 7",
263 "Pri 8",
264 "Pri 9",
265 "Pri 10",
266 "Pri 11");
267
268 lock (m_scenes)
269 {
270 foreach (Scene scene in m_scenes.Values)
271 {
272 scene.ForEachClient(
273 delegate(IClientAPI client)
274 {
275 if (client is LLClientView)
276 {
277 bool isChild = client.SceneAgent.IsChildAgent;
278 if (isChild && !showChildren)
279 return;
280
281 string name = client.Name;
282 if (pname != "" && name != pname)
283 return;
284
285 string regionName = scene.RegionInfo.RegionName;
286
287 report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
288 report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
289 report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
290 report.AppendLine(((LLClientView)client).EntityUpdateQueue.ToString());
291 }
292 });
293 }
294 }
295
296 return report.ToString();
297 }
298
299 /// <summary>
300 /// Generate an image queue report
301 /// </summary>
302 /// <param name="showParams"></param>
303 /// <returns></returns>
304 private string GetImageQueuesReport(string[] showParams)
305 {
306 if (showParams.Length < 5 || showParams.Length > 6)
307 return "Usage: show image queues <first-name> <last-name> [full]";
308
309 string firstName = showParams[3];
310 string lastName = showParams[4];
311
312 bool showChildAgents = showParams.Length == 6;
313
314 List<ScenePresence> foundAgents = new List<ScenePresence>();
315
316 lock (m_scenes)
317 {
318 foreach (Scene scene in m_scenes.Values)
319 {
320 ScenePresence sp = scene.GetScenePresence(firstName, lastName);
321 if (sp != null && (showChildAgents || !sp.IsChildAgent))
322 foundAgents.Add(sp);
323 }
324 }
325
326 if (foundAgents.Count == 0)
327 return string.Format("No agents found for {0} {1}", firstName, lastName);
328
329 StringBuilder report = new StringBuilder();
330
331 foreach (ScenePresence agent in foundAgents)
332 {
333 LLClientView client = agent.ControllingClient as LLClientView;
334
335 if (client == null)
336 return "This command is only supported for LLClientView";
337
338 J2KImage[] images = client.ImageManager.GetImages();
339
340 report.AppendFormat(
341 "In region {0} ({1} agent)\n",
342 agent.Scene.RegionInfo.RegionName, agent.IsChildAgent ? "child" : "root");
343 report.AppendFormat("Images in queue: {0}\n", images.Length);
344
345 if (images.Length > 0)
346 {
347 report.AppendFormat(
348 "{0,-36} {1,-8} {2,-10} {3,-9} {4,-9} {5,-7}\n",
349 "Texture ID",
350 "Last Seq",
351 "Priority",
352 "Start Pkt",
353 "Has Asset",
354 "Decoded");
355
356 foreach (J2KImage image in images)
357 report.AppendFormat(
358 "{0,36} {1,8} {2,10} {3,10} {4,9} {5,7}\n",
359 image.TextureID, image.LastSequence, image.Priority, image.StartPacket, image.HasAsset, image.IsDecoded);
360 }
361 }
362
363 return report.ToString();
364 }
365
366 /// <summary>
367 /// Generate UDP Queue data report for each client
368 /// </summary>
369 /// <param name="showParams"></param>
370 /// <returns></returns>
371 protected string GetQueuesReport(string[] showParams)
372 {
373 bool showChildren = false;
374 string pname = "";
375
376 if (showParams.Length > 2 && showParams[2] == "full")
377 showChildren = true;
378 else if (showParams.Length > 3)
379 pname = showParams[2] + " " + showParams[3];
380
381 StringBuilder report = new StringBuilder();
382
383 int columnPadding = 2;
384 int maxNameLength = 18;
385 int maxRegionNameLength = 14;
386 int maxTypeLength = 4;
387
388 int totalInfoFieldsLength
389 = maxNameLength + columnPadding
390 + maxRegionNameLength + columnPadding
391 + maxTypeLength + columnPadding;
392
393 report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
394 report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
395 report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
396
397 report.AppendFormat(
398 "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7}\n",
399 "Since",
400 "Pkts",
401 "Pkts",
402 "Pkts",
403 "Bytes",
404 "Q Pkts",
405 "Q Pkts",
406 "Q Pkts",
407 "Q Pkts",
408 "Q Pkts",
409 "Q Pkts",
410 "Q Pkts");
411
412 report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
413 report.AppendFormat(
414 "{0,7} {1,7} {2,7} {3,7} {4,9} {5,7} {6,7} {7,7} {8,7} {9,7} {10,8} {11,7}\n",
415 "Last In",
416 "In",
417 "Out",
418 "Resent",
419 "Unacked",
420 "Resend",
421 "Land",
422 "Wind",
423 "Cloud",
424 "Task",
425 "Texture",
426 "Asset");
427
428 lock (m_scenes)
429 {
430 foreach (Scene scene in m_scenes.Values)
431 {
432 scene.ForEachClient(
433 delegate(IClientAPI client)
434 {
435 if (client is IStatsCollector)
436 {
437
438 bool isChild = client.SceneAgent.IsChildAgent;
439 if (isChild && !showChildren)
440 return;
441
442 string name = client.Name;
443 if (pname != "" && name != pname)
444 return;
445
446 string regionName = scene.RegionInfo.RegionName;
447
448 report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
449 report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
450 report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
451
452 IStatsCollector stats = (IStatsCollector)client;
453 report.AppendLine(stats.Report());
454 }
455 });
456 }
457 }
458
459 return report.ToString();
460 }
461
462 /// <summary>
463 /// Show throttle data
464 /// </summary>
465 /// <param name="showParams"></param>
466 /// <returns></returns>
467 protected string GetThrottlesReport(string[] showParams)
468 {
469 bool showChildren = false;
470 string pname = "";
471
472 if (showParams.Length > 2 && showParams[2] == "full")
473 showChildren = true;
474 else if (showParams.Length > 3)
475 pname = showParams[2] + " " + showParams[3];
476
477 StringBuilder report = new StringBuilder();
478
479 int columnPadding = 2;
480 int maxNameLength = 18;
481 int maxRegionNameLength = 14;
482 int maxTypeLength = 4;
483 int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
484
485 report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
486 report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
487 report.Append(GetColumnEntry("Type", maxTypeLength, columnPadding));
488
489 report.AppendFormat(
490 "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
491 "Max",
492 "Target",
493 "Actual",
494 "Resend",
495 "Land",
496 "Wind",
497 "Cloud",
498 "Task",
499 "Texture",
500 "Asset");
501
502 report.AppendFormat("{0,-" + totalInfoFieldsLength + "}", "");
503 report.AppendFormat(
504 "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
505 "kb/s",
506 "kb/s",
507 "kb/s",
508 "kb/s",
509 "kb/s",
510 "kb/s",
511 "kb/s",
512 "kb/s",
513 "kb/s",
514 "kb/s");
515
516 report.AppendLine();
517
518 lock (m_scenes)
519 {
520 foreach (Scene scene in m_scenes.Values)
521 {
522 scene.ForEachClient(
523 delegate(IClientAPI client)
524 {
525 if (client is LLClientView)
526 {
527 LLClientView llClient = client as LLClientView;
528
529 bool isChild = client.SceneAgent.IsChildAgent;
530 if (isChild && !showChildren)
531 return;
532
533 string name = client.Name;
534 if (pname != "" && name != pname)
535 return;
536
537 string regionName = scene.RegionInfo.RegionName;
538
539 LLUDPClient llUdpClient = llClient.UDPClient;
540 ClientInfo ci = llUdpClient.GetClientInfo();
541
542 report.Append(GetColumnEntry(name, maxNameLength, columnPadding));
543 report.Append(GetColumnEntry(regionName, maxRegionNameLength, columnPadding));
544 report.Append(GetColumnEntry(isChild ? "Cd" : "Rt", maxTypeLength, columnPadding));
545
546 report.AppendFormat(
547 "{0,8} {1,8} {2,7} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7}\n",
548 ci.maxThrottle > 0 ? ((ci.maxThrottle * 8) / 1000).ToString() : "-",
549 llUdpClient.FlowThrottle.AdaptiveEnabled
550 ? ((ci.targetThrottle * 8) / 1000).ToString()
551 : (llUdpClient.FlowThrottle.TotalDripRequest * 8 / 1000).ToString(),
552 (ci.totalThrottle * 8) / 1000,
553 (ci.resendThrottle * 8) / 1000,
554 (ci.landThrottle * 8) / 1000,
555 (ci.windThrottle * 8) / 1000,
556 (ci.cloudThrottle * 8) / 1000,
557 (ci.taskThrottle * 8) / 1000,
558 (ci.textureThrottle * 8) / 1000,
559 (ci.assetThrottle * 8) / 1000);
560 }
561 });
562 }
563 }
564
565 return report.ToString();
566 }
567
568 /// <summary>
569 /// Show client stats data
570 /// </summary>
571 /// <param name="showParams"></param>
572 /// <returns></returns>
573 protected string HandleClientStatsReport(string[] showParams)
574 {
575 // NOTE: This writes to m_log on purpose. We want to store this information
576 // in case we need to analyze it later.
577 //
578 if (showParams.Length <= 4)
579 {
580 m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates");
581 foreach (Scene scene in m_scenes.Values)
582 {
583 scene.ForEachClient(
584 delegate(IClientAPI client)
585 {
586 if (client is LLClientView)
587 {
588 LLClientView llClient = client as LLClientView;
589 ClientInfo cinfo = llClient.UDPClient.GetClientInfo();
590 int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
591 avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
592
593 string childAgentStatus;
594
595 if (llClient.SceneAgent != null)
596 childAgentStatus = llClient.SceneAgent.IsChildAgent ? "N" : "Y";
597 else
598 childAgentStatus = "Off!";
599
600 m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}",
601 scene.RegionInfo.RegionName, llClient.Name,
602 childAgentStatus,
603 (DateTime.Now - cinfo.StartedTime).Minutes,
604 avg_reqs,
605 string.Format(
606 "{0} ({1:0.00}%)",
607 llClient.TotalAgentUpdates,
608 cinfo.SyncRequests.ContainsKey("AgentUpdate")
609 ? (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100
610 : 0));
611 }
612 });
613 }
614 return string.Empty;
615 }
616
617 string fname = "", lname = "";
618
619 if (showParams.Length > 3)
620 fname = showParams[3];
621 if (showParams.Length > 4)
622 lname = showParams[4];
623
624 foreach (Scene scene in m_scenes.Values)
625 {
626 scene.ForEachClient(
627 delegate(IClientAPI client)
628 {
629 if (client is LLClientView)
630 {
631 LLClientView llClient = client as LLClientView;
632
633 if (llClient.Name == fname + " " + lname)
634 {
635
636 ClientInfo cinfo = llClient.GetClientInfo();
637 AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(llClient.CircuitCode);
638 if (aCircuit == null) // create a dummy one
639 aCircuit = new AgentCircuitData();
640
641 if (!llClient.SceneAgent.IsChildAgent)
642 m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, Util.GetViewerName(aCircuit), aCircuit.Id0);
643
644 int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
645 avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
646
647 m_log.InfoFormat("[INFO]:");
648 m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName,
649 (llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs);
650
651 Dictionary<string, int> sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry)
652 .ToDictionary(pair => pair.Key, pair => pair.Value);
653 PrintRequests("TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum());
654
655 sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry)
656 .ToDictionary(pair => pair.Key, pair => pair.Value);
657 PrintRequests("TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum());
658
659 sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry)
660 .ToDictionary(pair => pair.Key, pair => pair.Value);
661 PrintRequests("TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum());
662 }
663 }
664 });
665 }
666 return string.Empty;
667 }
668
669 private void PrintRequests(string type, Dictionary<string, int> sortedDict, int sum)
670 {
671 m_log.InfoFormat("[INFO]:");
672 m_log.InfoFormat("[INFO]: {0,25}", type);
673 foreach (KeyValuePair<string, int> kvp in sortedDict.Take(12))
674 m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value);
675 m_log.InfoFormat("[INFO]: {0,25}", "...");
676 m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum);
677 }
678 }
679}