aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs11
-rw-r--r--OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs123
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs6
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs220
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs18
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs59
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs23
-rw-r--r--OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs339
-rw-r--r--OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs657
-rwxr-xr-xOpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs113
-rw-r--r--OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs11
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs10
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs2
16 files changed, 1184 insertions, 414 deletions
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index dd72cfb..a96c8b4 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -660,6 +660,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
660 public event BakeTerrain OnBakeTerrain; 660 public event BakeTerrain OnBakeTerrain;
661 public event EstateChangeInfo OnEstateChangeInfo; 661 public event EstateChangeInfo OnEstateChangeInfo;
662 public event EstateManageTelehub OnEstateManageTelehub; 662 public event EstateManageTelehub OnEstateManageTelehub;
663 public event CachedTextureRequest OnCachedTextureRequest;
663 public event SetAppearance OnSetAppearance; 664 public event SetAppearance OnSetAppearance;
664 public event AvatarNowWearing OnAvatarNowWearing; 665 public event AvatarNowWearing OnAvatarNowWearing;
665 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; 666 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
@@ -687,6 +688,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
687 public event Action<IClientAPI, bool> OnCompleteMovementToRegion; 688 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
688 public event UpdateAgent OnPreAgentUpdate; 689 public event UpdateAgent OnPreAgentUpdate;
689 public event UpdateAgent OnAgentUpdate; 690 public event UpdateAgent OnAgentUpdate;
691 public event UpdateAgent OnAgentCameraUpdate;
690 public event AgentRequestSit OnAgentRequestSit; 692 public event AgentRequestSit OnAgentRequestSit;
691 public event AgentSit OnAgentSit; 693 public event AgentSit OnAgentSit;
692 public event AvatarPickerRequest OnAvatarPickerRequest; 694 public event AvatarPickerRequest OnAvatarPickerRequest;
@@ -943,13 +945,18 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
943 { 945 {
944 946
945 } 947 }
948
949 public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures)
950 {
946 951
952 }
953
947 public void SendStartPingCheck(byte seq) 954 public void SendStartPingCheck(byte seq)
948 { 955 {
949 956
950 } 957 }
951 958
952 public void SendKillObject(ulong regionHandle, List<uint> localID) 959 public void SendKillObject(List<uint> localID)
953 { 960 {
954 961
955 } 962 }
@@ -1681,7 +1688,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1681 { 1688 {
1682 } 1689 }
1683 1690
1684 public void StopFlying(ISceneEntity presence) 1691 public void SendAgentTerseUpdate(ISceneEntity presence)
1685 { 1692 {
1686 } 1693 }
1687 1694
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
index 992f38e..1eb0a6b 100644
--- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq;
30using System.Reflection; 31using System.Reflection;
31using System.Text; 32using System.Text;
32using log4net; 33using log4net;
@@ -51,7 +52,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LindenUDPInfoModule")] 52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LindenUDPInfoModule")]
52 public class LindenUDPInfoModule : ISharedRegionModule 53 public class LindenUDPInfoModule : ISharedRegionModule
53 { 54 {
54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 56
56 protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); 57 protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
57 58
@@ -130,6 +131,15 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
130 "Go on/off emergency monitoring mode", 131 "Go on/off emergency monitoring mode",
131 "Go on/off emergency monitoring mode", 132 "Go on/off emergency monitoring mode",
132 HandleEmergencyMonitoring); 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
133 } 143 }
134 144
135 public void RemoveRegion(Scene scene) 145 public void RemoveRegion(Scene scene)
@@ -587,6 +597,115 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
587 (throttleRates.Asset * 8) / 1000); 597 (throttleRates.Asset * 8) / 1000);
588 598
589 return report.ToString(); 599 return report.ToString();
590 } 600 }
601
602 /// <summary>
603 /// Show client stats data
604 /// </summary>
605 /// <param name="showParams"></param>
606 /// <returns></returns>
607 protected string HandleClientStatsReport(string[] showParams)
608 {
609 // NOTE: This writes to m_log on purpose. We want to store this information
610 // in case we need to analyze it later.
611 //
612 if (showParams.Length <= 4)
613 {
614 m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates");
615 foreach (Scene scene in m_scenes.Values)
616 {
617 scene.ForEachClient(
618 delegate(IClientAPI client)
619 {
620 if (client is LLClientView)
621 {
622 LLClientView llClient = client as LLClientView;
623 ClientInfo cinfo = llClient.UDPClient.GetClientInfo();
624 int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
625 avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
626
627 string childAgentStatus;
628
629 if (llClient.SceneAgent != null)
630 childAgentStatus = llClient.SceneAgent.IsChildAgent ? "N" : "Y";
631 else
632 childAgentStatus = "Off!";
633
634 m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}",
635 scene.RegionInfo.RegionName, llClient.Name,
636 childAgentStatus,
637 (DateTime.Now - cinfo.StartedTime).Minutes,
638 avg_reqs,
639 string.Format(
640 "{0} ({1:0.00}%)",
641 llClient.TotalAgentUpdates,
642 (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100));
643 }
644 });
645 }
646 return string.Empty;
647 }
648
649 string fname = "", lname = "";
650
651 if (showParams.Length > 3)
652 fname = showParams[3];
653 if (showParams.Length > 4)
654 lname = showParams[4];
655
656 foreach (Scene scene in m_scenes.Values)
657 {
658 scene.ForEachClient(
659 delegate(IClientAPI client)
660 {
661 if (client is LLClientView)
662 {
663 LLClientView llClient = client as LLClientView;
664
665 if (llClient.Name == fname + " " + lname)
666 {
667
668 ClientInfo cinfo = llClient.GetClientInfo();
669 AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(llClient.CircuitCode);
670 if (aCircuit == null) // create a dummy one
671 aCircuit = new AgentCircuitData();
672
673 if (!llClient.SceneAgent.IsChildAgent)
674 m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, aCircuit.Viewer, aCircuit.Id0);
675
676 int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
677 avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
678
679 m_log.InfoFormat("[INFO]:");
680 m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName,
681 (llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs);
682
683 Dictionary<string, int> sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry)
684 .ToDictionary(pair => pair.Key, pair => pair.Value);
685 PrintRequests("TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum());
686
687 sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry)
688 .ToDictionary(pair => pair.Key, pair => pair.Value);
689 PrintRequests("TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum());
690
691 sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry)
692 .ToDictionary(pair => pair.Key, pair => pair.Value);
693 PrintRequests("TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum());
694 }
695 }
696 });
697 }
698 return string.Empty;
699 }
700
701 private void PrintRequests(string type, Dictionary<string, int> sortedDict, int sum)
702 {
703 m_log.InfoFormat("[INFO]:");
704 m_log.InfoFormat("[INFO]: {0,25}", type);
705 foreach (KeyValuePair<string, int> kvp in sortedDict.Take(12))
706 m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value);
707 m_log.InfoFormat("[INFO]: {0,25}", "...");
708 m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum);
709 }
591 } 710 }
592} \ No newline at end of file 711} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs
index 018357a..c48e585 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs
@@ -375,11 +375,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
375 scene.GetRootAgentCount(), scene.RegionInfo.RegionName, 375 scene.GetRootAgentCount(), scene.RegionInfo.RegionName,
376 scene.RegionInfo.RegionID, 376 scene.RegionInfo.RegionID,
377 DateTime.UtcNow.ToString("s"))); 377 DateTime.UtcNow.ToString("s")));
378
378 scene.ForEachRootScenePresence(delegate(ScenePresence sp) 379 scene.ForEachRootScenePresence(delegate(ScenePresence sp)
379 { 380 {
380 list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID)); 381 list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID));
381 list.Append("</avatars>");
382 }); 382 });
383
384 list.Append("</avatars>");
383 string payload = list.ToString(); 385 string payload = list.ToString();
384 386
385 // post via REST to broker 387 // post via REST to broker
diff --git a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs
new file mode 100644
index 0000000..5a6b284
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs
@@ -0,0 +1,220 @@
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 System.Text.RegularExpressions;
34using log4net;
35using Mono.Addins;
36using NDesk.Options;
37using Nini.Config;
38using OpenMetaverse;
39using OpenSim.Framework;
40using OpenSim.Framework.Console;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43
44namespace OpenSim.Region.OptionalModules.Avatar.SitStand
45{
46 /// <summary>
47 /// A module that just holds commands for changing avatar sitting and standing states.
48 /// </summary>
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AnimationsCommandModule")]
50 public class SitStandCommandModule : INonSharedRegionModule
51 {
52// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 private Scene m_scene;
55
56 public string Name { get { return "SitStand Command Module"; } }
57
58 public Type ReplaceableInterface { get { return null; } }
59
60 public void Initialise(IConfigSource source)
61 {
62// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE");
63 }
64
65 public void PostInitialise()
66 {
67// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE");
68 }
69
70 public void Close()
71 {
72// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE");
73 }
74
75 public void AddRegion(Scene scene)
76 {
77// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
78 }
79
80 public void RemoveRegion(Scene scene)
81 {
82// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
83 }
84
85 public void RegionLoaded(Scene scene)
86 {
87// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
88
89 m_scene = scene;
90
91 scene.AddCommand(
92 "Users", this, "sit user name",
93 "sit user name [--regex] <first-name> <last-name>",
94 "Sit the named user on an unoccupied object with a sit target.",
95 "If there are no such objects then nothing happens.\n"
96 + "If --regex is specified then the names are treated as regular expressions.",
97 HandleSitUserNameCommand);
98
99 scene.AddCommand(
100 "Users", this, "stand user name",
101 "stand user name [--regex] <first-name> <last-name>",
102 "Stand the named user.",
103 "If --regex is specified then the names are treated as regular expressions.",
104 HandleStandUserNameCommand);
105 }
106
107 private void HandleSitUserNameCommand(string module, string[] cmd)
108 {
109 if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null)
110 return;
111
112 if (cmd.Length < 5)
113 {
114 MainConsole.Instance.Output("Usage: sit user name [--regex] <first-name> <last-name>");
115 return;
116 }
117
118 List<ScenePresence> scenePresences = GetScenePresences(cmd);
119
120 foreach (ScenePresence sp in scenePresences)
121 {
122 if (sp.SitGround || sp.IsSatOnObject)
123 continue;
124
125 SceneObjectPart sitPart = null;
126 List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups();
127
128 foreach (SceneObjectGroup sceneObject in sceneObjects)
129 {
130 if (sceneObject.IsAttachment)
131 continue;
132
133 foreach (SceneObjectPart part in sceneObject.Parts)
134 {
135 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
136 {
137 sitPart = part;
138 break;
139 }
140 }
141 }
142
143 if (sitPart != null)
144 {
145 MainConsole.Instance.OutputFormat(
146 "Sitting {0} on {1} {2} in {3}",
147 sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name);
148
149 sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero);
150 sp.HandleAgentSit(sp.ControllingClient, sp.UUID);
151 }
152 else
153 {
154 MainConsole.Instance.OutputFormat(
155 "Could not find any unoccupied set seat on which to sit {0} in {1}. Aborting",
156 sp.Name, m_scene.Name);
157
158 break;
159 }
160 }
161 }
162
163 private void HandleStandUserNameCommand(string module, string[] cmd)
164 {
165 if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null)
166 return;
167
168 if (cmd.Length < 5)
169 {
170 MainConsole.Instance.Output("Usage: stand user name [--regex] <first-name> <last-name>");
171 return;
172 }
173
174 List<ScenePresence> scenePresences = GetScenePresences(cmd);
175
176 foreach (ScenePresence sp in scenePresences)
177 {
178 if (sp.SitGround || sp.IsSatOnObject)
179 {
180 MainConsole.Instance.OutputFormat("Standing {0} in {1}", sp.Name, m_scene.Name);
181 sp.StandUp();
182 }
183 }
184 }
185
186 private List<ScenePresence> GetScenePresences(string[] cmdParams)
187 {
188 bool useRegex = false;
189 OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
190
191 List<string> mainParams = options.Parse(cmdParams);
192
193 string firstName = mainParams[3];
194 string lastName = mainParams[4];
195
196 List<ScenePresence> scenePresencesMatched = new List<ScenePresence>();
197
198 if (useRegex)
199 {
200 Regex nameRegex = new Regex(string.Format("{0} {1}", firstName, lastName));
201 List<ScenePresence> scenePresences = m_scene.GetScenePresences();
202
203 foreach (ScenePresence sp in scenePresences)
204 {
205 if (!sp.IsChildAgent && nameRegex.IsMatch(sp.Name))
206 scenePresencesMatched.Add(sp);
207 }
208 }
209 else
210 {
211 ScenePresence sp = m_scene.GetScenePresence(firstName, lastName);
212
213 if (sp != null && !sp.IsChildAgent)
214 scenePresencesMatched.Add(sp);
215 }
216
217 return scenePresencesMatched;
218 }
219 }
220} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 0cec959..2b33084 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -326,15 +326,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
326 "ParcelVoiceInfoRequest", 326 "ParcelVoiceInfoRequest",
327 agentID.ToString())); 327 agentID.ToString()));
328 328
329 caps.RegisterHandler( 329 //caps.RegisterHandler(
330 "ChatSessionRequest", 330 // "ChatSessionRequest",
331 new RestStreamHandler( 331 // new RestStreamHandler(
332 "POST", 332 // "POST",
333 capsBase + m_chatSessionRequestPath, 333 // capsBase + m_chatSessionRequestPath,
334 (request, path, param, httpRequest, httpResponse) 334 // (request, path, param, httpRequest, httpResponse)
335 => ChatSessionRequest(scene, request, path, param, agentID, caps), 335 // => ChatSessionRequest(scene, request, path, param, agentID, caps),
336 "ChatSessionRequest", 336 // "ChatSessionRequest",
337 agentID.ToString())); 337 // agentID.ToString()));
338 } 338 }
339 339
340 /// <summary> 340 /// <summary>
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
index e756c70..349c0d0 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
@@ -117,6 +117,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
117 117
118 private IConfig m_config; 118 private IConfig m_config;
119 119
120 private object m_Lock;
121
120 public void Initialise(IConfigSource config) 122 public void Initialise(IConfigSource config)
121 { 123 {
122 124
@@ -128,6 +130,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
128 if (!m_config.GetBoolean("enabled", false)) 130 if (!m_config.GetBoolean("enabled", false))
129 return; 131 return;
130 132
133 m_Lock = new object();
134
131 try 135 try
132 { 136 {
133 // retrieve configuration variables 137 // retrieve configuration variables
@@ -429,15 +433,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
429 "ParcelVoiceInfoRequest", 433 "ParcelVoiceInfoRequest",
430 agentID.ToString())); 434 agentID.ToString()));
431 435
432 caps.RegisterHandler( 436 //caps.RegisterHandler(
433 "ChatSessionRequest", 437 // "ChatSessionRequest",
434 new RestStreamHandler( 438 // new RestStreamHandler(
435 "POST", 439 // "POST",
436 capsBase + m_chatSessionRequestPath, 440 // capsBase + m_chatSessionRequestPath,
437 (request, path, param, httpRequest, httpResponse) 441 // (request, path, param, httpRequest, httpResponse)
438 => ChatSessionRequest(scene, request, path, param, agentID, caps), 442 // => ChatSessionRequest(scene, request, path, param, agentID, caps),
439 "ChatSessionRequest", 443 // "ChatSessionRequest",
440 agentID.ToString())); 444 // agentID.ToString()));
441 } 445 }
442 446
443 /// <summary> 447 /// <summary>
@@ -837,7 +841,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
837 requrl = String.Format("{0}&chan_roll_off={1}", requrl, m_vivoxChannelRollOff); 841 requrl = String.Format("{0}&chan_roll_off={1}", requrl, m_vivoxChannelRollOff);
838 requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel); 842 requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel);
839 requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange); 843 requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange);
840 requrl = String.Format("{0}&chan_ckamping_distance={1}", requrl, m_vivoxChannelClampingDistance); 844 requrl = String.Format("{0}&chan_clamping_distance={1}", requrl, m_vivoxChannelClampingDistance);
841 845
842 XmlElement resp = VivoxCall(requrl, true); 846 XmlElement resp = VivoxCall(requrl, true);
843 if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri)) 847 if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri))
@@ -1118,25 +1122,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1118 1122
1119 doc = new XmlDocument(); 1123 doc = new XmlDocument();
1120 1124
1121 try 1125 // Let's serialize all calls to Vivox. Most of these are driven by
1126 // the clients (CAPs), when the user arrives at the region. We don't
1127 // want to issue many simultaneous http requests to Vivox, because mono
1128 // doesn't like that
1129 lock (m_Lock)
1122 { 1130 {
1123 // Otherwise prepare the request 1131 try
1124// m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); 1132 {
1133 // Otherwise prepare the request
1134 //m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl);
1125 1135
1126 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); 1136 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl);
1127 1137
1128 // We are sending just parameters, no content 1138 // We are sending just parameters, no content
1129 req.ContentLength = 0; 1139 req.ContentLength = 0;
1130 1140
1131 // Send request and retrieve the response 1141 // Send request and retrieve the response
1132 using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse()) 1142 using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse())
1133 using (Stream s = rsp.GetResponseStream()) 1143 using (Stream s = rsp.GetResponseStream())
1134 using (XmlTextReader rdr = new XmlTextReader(s)) 1144 using (XmlTextReader rdr = new XmlTextReader(s))
1135 doc.Load(rdr); 1145 doc.Load(rdr);
1136 } 1146 }
1137 catch (Exception e) 1147 catch (Exception e)
1138 { 1148 {
1139 m_log.ErrorFormat("[VivoxVoice] Error in admin call : {0}", e.Message); 1149 m_log.ErrorFormat("[VivoxVoice] Error in admin call : {0}", e.Message);
1150 }
1140 } 1151 }
1141 1152
1142 // If we're debugging server responses, dump the whole 1153 // If we're debugging server responses, dump the whole
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index d0a5989..8a734e1 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -250,7 +250,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
250 250
251 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; 251 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
252 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 252 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
253 client.OnDirFindQuery += OnDirFindQuery;
254 client.OnRequestAvatarProperties += OnRequestAvatarProperties; 253 client.OnRequestAvatarProperties += OnRequestAvatarProperties;
255 254
256 // Used for Notices and Group Invites/Accept/Reject 255 // Used for Notices and Group Invites/Accept/Reject
@@ -303,21 +302,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
303 } 302 }
304 */ 303 */
305 304
306 void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
307 {
308 if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
309 {
310 if (m_debugEnabled)
311 m_log.DebugFormat(
312 "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})",
313 System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
314
315 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
316 remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray());
317 }
318
319 }
320
321 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) 305 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
322 { 306 {
323 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 307 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -1178,6 +1162,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1178 } 1162 }
1179 } 1163 }
1180 1164
1165 public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
1166 {
1167 return m_groupData.FindGroups(GetRequestingAgentID(remoteClient), query);
1168 }
1169
1170
1181 #endregion 1171 #endregion
1182 1172
1183 #region Client/Update Tools 1173 #region Client/Update Tools
@@ -1222,7 +1212,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1222 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); 1212 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
1223 AgentData.Add(AgentDataMap); 1213 AgentData.Add(AgentDataMap);
1224 1214
1225
1226 OSDArray GroupData = new OSDArray(data.Length); 1215 OSDArray GroupData = new OSDArray(data.Length);
1227 OSDArray NewGroupData = new OSDArray(data.Length); 1216 OSDArray NewGroupData = new OSDArray(data.Length);
1228 1217
diff --git a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs b/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
deleted file mode 100644
index 6e74ce0..0000000
--- a/OpenSim/Region/OptionalModules/Framework/Monitoring/ServerStats.cs
+++ /dev/null
@@ -1,339 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31using System.Linq;
32using System.Net.NetworkInformation;
33using System.Text;
34using System.Threading;
35
36using log4net;
37using Mono.Addins;
38using Nini.Config;
39
40using OpenSim.Framework;
41using OpenSim.Framework.Console;
42using OpenSim.Framework.Monitoring;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45
46using OpenMetaverse.StructuredData;
47
48namespace OpenSim.Region.OptionalModules.Framework.Monitoring
49{
50[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ServerStatistics")]
51public class ServerStats : ISharedRegionModule
52{
53 private readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
54 private readonly string LogHeader = "[SERVER STATS]";
55
56 public bool Enabled = false;
57 private static Dictionary<string, Stat> RegisteredStats = new Dictionary<string, Stat>();
58
59 public readonly string CategoryServer = "server";
60
61 public readonly string ContainerProcessor = "processor";
62 public readonly string ContainerMemory = "memory";
63 public readonly string ContainerNetwork = "network";
64 public readonly string ContainerProcess = "process";
65
66 public string NetworkInterfaceTypes = "Ethernet";
67
68 readonly int performanceCounterSampleInterval = 500;
69 int lastperformanceCounterSampleTime = 0;
70
71 private class PerfCounterControl
72 {
73 public PerformanceCounter perfCounter;
74 public int lastFetch;
75 public string name;
76 public PerfCounterControl(PerformanceCounter pPc)
77 : this(pPc, String.Empty)
78 {
79 }
80 public PerfCounterControl(PerformanceCounter pPc, string pName)
81 {
82 perfCounter = pPc;
83 lastFetch = 0;
84 name = pName;
85 }
86 }
87
88 PerfCounterControl processorPercentPerfCounter = null;
89
90 #region ISharedRegionModule
91 // IRegionModuleBase.Name
92 public string Name { get { return "Server Stats"; } }
93 // IRegionModuleBase.ReplaceableInterface
94 public Type ReplaceableInterface { get { return null; } }
95 // IRegionModuleBase.Initialize
96 public void Initialise(IConfigSource source)
97 {
98 IConfig cfg = source.Configs["Monitoring"];
99
100 if (cfg != null)
101 Enabled = cfg.GetBoolean("ServerStatsEnabled", true);
102
103 if (Enabled)
104 {
105 NetworkInterfaceTypes = cfg.GetString("NetworkInterfaceTypes", "Ethernet");
106 }
107 }
108 // IRegionModuleBase.Close
109 public void Close()
110 {
111 if (RegisteredStats.Count > 0)
112 {
113 foreach (Stat stat in RegisteredStats.Values)
114 {
115 StatsManager.DeregisterStat(stat);
116 stat.Dispose();
117 }
118 RegisteredStats.Clear();
119 }
120 }
121 // IRegionModuleBase.AddRegion
122 public void AddRegion(Scene scene)
123 {
124 }
125 // IRegionModuleBase.RemoveRegion
126 public void RemoveRegion(Scene scene)
127 {
128 }
129 // IRegionModuleBase.RegionLoaded
130 public void RegionLoaded(Scene scene)
131 {
132 }
133 // ISharedRegionModule.PostInitialize
134 public void PostInitialise()
135 {
136 if (RegisteredStats.Count == 0)
137 {
138 RegisterServerStats();
139 }
140 }
141 #endregion ISharedRegionModule
142
143 private void MakeStat(string pName, string pDesc, string pUnit, string pContainer, Action<Stat> act)
144 {
145 string desc = pDesc;
146 if (desc == null)
147 desc = pName;
148 Stat stat = new Stat(pName, pName, desc, pUnit, CategoryServer, pContainer, StatType.Pull, act, StatVerbosity.Info);
149 StatsManager.RegisterStat(stat);
150 RegisteredStats.Add(pName, stat);
151 }
152
153 public void RegisterServerStats()
154 {
155 lastperformanceCounterSampleTime = Util.EnvironmentTickCount();
156 PerformanceCounter tempPC;
157 Stat tempStat;
158 string tempName;
159
160 try
161 {
162 tempName = "CPUPercent";
163 tempPC = new PerformanceCounter("Processor", "% Processor Time", "_Total");
164 processorPercentPerfCounter = new PerfCounterControl(tempPC);
165 // A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy.
166 tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor,
167 StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter, Util.IsWindows() ? 1 : -1); },
168 StatVerbosity.Info);
169 StatsManager.RegisterStat(tempStat);
170 RegisteredStats.Add(tempName, tempStat);
171
172 MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor,
173 (s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; });
174
175 MakeStat("UserProcessorTime", null, "sec", ContainerProcessor,
176 (s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; });
177
178 MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor,
179 (s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; });
180
181 MakeStat("Threads", null, "threads", ContainerProcessor,
182 (s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
183 }
184 catch (Exception e)
185 {
186 m_log.ErrorFormat("{0} Exception creating 'Process': {1}", LogHeader, e);
187 }
188
189 try
190 {
191 List<string> okInterfaceTypes = new List<string>(NetworkInterfaceTypes.Split(','));
192
193 IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces();
194 foreach (NetworkInterface nic in nics)
195 {
196 if (nic.OperationalStatus != OperationalStatus.Up)
197 continue;
198
199 string nicInterfaceType = nic.NetworkInterfaceType.ToString();
200 if (!okInterfaceTypes.Contains(nicInterfaceType))
201 {
202 m_log.DebugFormat("{0} Not including stats for network interface '{1}' of type '{2}'.",
203 LogHeader, nic.Name, nicInterfaceType);
204 m_log.DebugFormat("{0} To include, add to comma separated list in [Monitoring]NetworkInterfaceTypes={1}",
205 LogHeader, NetworkInterfaceTypes);
206 continue;
207 }
208
209 if (nic.Supports(NetworkInterfaceComponent.IPv4))
210 {
211 IPv4InterfaceStatistics nicStats = nic.GetIPv4Statistics();
212 if (nicStats != null)
213 {
214 MakeStat("BytesRcvd/" + nic.Name, nic.Name, "KB", ContainerNetwork,
215 (s) => { LookupNic(s, (ns) => { return ns.BytesReceived; }, 1024.0); });
216 MakeStat("BytesSent/" + nic.Name, nic.Name, "KB", ContainerNetwork,
217 (s) => { LookupNic(s, (ns) => { return ns.BytesSent; }, 1024.0); });
218 MakeStat("TotalBytes/" + nic.Name, nic.Name, "KB", ContainerNetwork,
219 (s) => { LookupNic(s, (ns) => { return ns.BytesSent + ns.BytesReceived; }, 1024.0); });
220 }
221 }
222 // TODO: add IPv6 (it may actually happen someday)
223 }
224 }
225 catch (Exception e)
226 {
227 m_log.ErrorFormat("{0} Exception creating 'Network Interface': {1}", LogHeader, e);
228 }
229
230 MakeStat("ProcessMemory", null, "MB", ContainerMemory,
231 (s) => { s.Value = Process.GetCurrentProcess().WorkingSet64 / 1024d / 1024d; });
232 MakeStat("ObjectMemory", null, "MB", ContainerMemory,
233 (s) => { s.Value = GC.GetTotalMemory(false) / 1024d / 1024d; });
234 MakeStat("LastMemoryChurn", null, "MB/sec", ContainerMemory,
235 (s) => { s.Value = Math.Round(MemoryWatchdog.LastMemoryChurn * 1000d / 1024d / 1024d, 3); });
236 MakeStat("AverageMemoryChurn", null, "MB/sec", ContainerMemory,
237 (s) => { s.Value = Math.Round(MemoryWatchdog.AverageMemoryChurn * 1000d / 1024d / 1024d, 3); });
238 }
239
240 // Notes on performance counters:
241 // "How To Read Performance Counters": http://blogs.msdn.com/b/bclteam/archive/2006/06/02/618156.aspx
242 // "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c
243 // "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters
244 private delegate double PerfCounterNextValue();
245 private void GetNextValue(Stat stat, PerfCounterControl perfControl)
246 {
247 GetNextValue(stat, perfControl, 1.0);
248 }
249 private void GetNextValue(Stat stat, PerfCounterControl perfControl, double factor)
250 {
251 if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval)
252 {
253 if (perfControl != null && perfControl.perfCounter != null)
254 {
255 try
256 {
257 // Kludge for factor to run double duty. If -1, subtract the value from one
258 if (factor == -1)
259 stat.Value = 1 - perfControl.perfCounter.NextValue();
260 else
261 stat.Value = perfControl.perfCounter.NextValue() / factor;
262 }
263 catch (Exception e)
264 {
265 m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e);
266 }
267 perfControl.lastFetch = Util.EnvironmentTickCount();
268 }
269 }
270 }
271
272 // Lookup the nic that goes with this stat and set the value by using a fetch action.
273 // Not sure about closure with delegates inside delegates.
274 private delegate double GetIPv4StatValue(IPv4InterfaceStatistics interfaceStat);
275 private void LookupNic(Stat stat, GetIPv4StatValue getter, double factor)
276 {
277 // Get the one nic that has the name of this stat
278 IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces().Where(
279 (network) => network.Name == stat.Description);
280 try
281 {
282 foreach (NetworkInterface nic in nics)
283 {
284 IPv4InterfaceStatistics intrStats = nic.GetIPv4Statistics();
285 if (intrStats != null)
286 {
287 double newVal = Math.Round(getter(intrStats) / factor, 3);
288 stat.Value = newVal;
289 }
290 break;
291 }
292 }
293 catch
294 {
295 // There are times interfaces go away so we just won't update the stat for this
296 m_log.ErrorFormat("{0} Exception fetching stat on interface '{1}'", LogHeader, stat.Description);
297 }
298 }
299}
300
301public class ServerStatsAggregator : Stat
302{
303 public ServerStatsAggregator(
304 string shortName,
305 string name,
306 string description,
307 string unitName,
308 string category,
309 string container
310 )
311 : base(
312 shortName,
313 name,
314 description,
315 unitName,
316 category,
317 container,
318 StatType.Push,
319 MeasuresOfInterest.None,
320 null,
321 StatVerbosity.Info)
322 {
323 }
324 public override string ToConsoleString()
325 {
326 StringBuilder sb = new StringBuilder();
327
328 return sb.ToString();
329 }
330
331 public override OSDMap ToOSDMap()
332 {
333 OSDMap ret = new OSDMap();
334
335 return ret;
336 }
337}
338
339}
diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs
new file mode 100644
index 0000000..d8f5563
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs
@@ -0,0 +1,657 @@
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.Security.Cryptography; // for computing md5 hash
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39
40using OpenSim.Framework;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45
46using Ionic.Zlib;
47
48// You will need to uncomment these lines if you are adding a region module to some other assembly which does not already
49// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans
50// the available DLLs
51//[assembly: Addin("MaterialsDemoModule", "1.0")]
52//[assembly: AddinDependency("OpenSim", "0.5")]
53
54namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
55{
56 /// <summary>
57 ///
58 // # # ## ##### # # # # # ####
59 // # # # # # # ## # # ## # # #
60 // # # # # # # # # # # # # # #
61 // # ## # ###### ##### # # # # # # # # ###
62 // ## ## # # # # # ## # # ## # #
63 // # # # # # # # # # # # ####
64 //
65 // THIS MODULE IS FOR EXPERIMENTAL USE ONLY AND MAY CAUSE REGION OR ASSET CORRUPTION!
66 //
67 ////////////// WARNING //////////////////////////////////////////////////////////////////
68 /// This is an *Experimental* module for developing support for materials-capable viewers
69 /// This module should NOT be used in a production environment! It may cause data corruption and
70 /// viewer crashes. It should be only used to evaluate implementations of materials.
71 ///
72 /// Materials are persisted via SceneObjectPart.dynattrs. This is a relatively new feature
73 /// of OpenSimulator and is not field proven at the time this module was written. Persistence
74 /// may fail or become corrupt and this could cause viewer crashes due to erroneous materials
75 /// data being sent to viewers. Materials descriptions might survive IAR, OAR, or other means
76 /// of archiving however the texture resources used by these materials probably will not as they
77 /// may not be adequately referenced to ensure proper archiving.
78 ///
79 ///
80 ///
81 /// To enable this module, add this string at the bottom of OpenSim.ini:
82 /// [MaterialsDemoModule]
83 ///
84 /// </summary>
85 ///
86
87 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MaterialsDemoModule")]
88 public class MaterialsDemoModule : INonSharedRegionModule
89 {
90 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
91
92 public string Name { get { return "MaterialsDemoModule"; } }
93
94 public Type ReplaceableInterface { get { return null; } }
95
96 private Scene m_scene = null;
97 private bool m_enabled = false;
98
99 public Dictionary<UUID, OSDMap> m_knownMaterials = new Dictionary<UUID, OSDMap>();
100
101 public void Initialise(IConfigSource source)
102 {
103 m_enabled = (source.Configs["MaterialsDemoModule"] != null);
104 if (!m_enabled)
105 return;
106
107 m_log.DebugFormat("[MaterialsDemoModule]: INITIALIZED MODULE");
108 }
109
110 public void Close()
111 {
112 if (!m_enabled)
113 return;
114
115 m_log.DebugFormat("[MaterialsDemoModule]: CLOSED MODULE");
116 }
117
118 public void AddRegion(Scene scene)
119 {
120 if (!m_enabled)
121 return;
122
123 m_log.DebugFormat("[MaterialsDemoModule]: REGION {0} ADDED", scene.RegionInfo.RegionName);
124
125 m_scene = scene;
126 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
127 m_scene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
128// m_scene.EventManager.OnGatherUuids += GatherMaterialsUuids;
129 }
130
131 void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
132 {
133 foreach (var part in obj.Parts)
134 if (part != null)
135 GetStoredMaterialsForPart(part);
136 }
137
138 void OnRegisterCaps(OpenMetaverse.UUID agentID, OpenSim.Framework.Capabilities.Caps caps)
139 {
140 string capsBase = "/CAPS/" + caps.CapsObjectPath;
141
142 IRequestHandler renderMaterialsPostHandler
143 = new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap, "RenderMaterials", null);
144 caps.RegisterHandler("RenderMaterials", renderMaterialsPostHandler);
145
146 // OpenSimulator CAPs infrastructure seems to be somewhat hostile towards any CAP that requires both GET
147 // and POST handlers, (at least at the time this was originally written), so we first set up a POST
148 // handler normally and then add a GET handler via MainServer
149
150 IRequestHandler renderMaterialsGetHandler
151 = new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap, "RenderMaterials", null);
152 MainServer.Instance.AddStreamHandler(renderMaterialsGetHandler);
153
154 // materials viewer seems to use either POST or PUT, so assign POST handler for PUT as well
155 IRequestHandler renderMaterialsPutHandler
156 = new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap, "RenderMaterials", null);
157 MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler);
158 }
159
160 public void RemoveRegion(Scene scene)
161 {
162 if (!m_enabled)
163 return;
164
165 m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
166 m_scene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene;
167// m_scene.EventManager.OnGatherUuids -= GatherMaterialsUuids;
168
169 m_log.DebugFormat("[MaterialsDemoModule]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
170 }
171
172 public void RegionLoaded(Scene scene)
173 {
174 }
175
176 OSDMap GetMaterial(UUID id)
177 {
178 OSDMap map = null;
179 lock (m_knownMaterials)
180 {
181 if (m_knownMaterials.ContainsKey(id))
182 {
183 map = new OSDMap();
184 map["ID"] = OSD.FromBinary(id.GetBytes());
185 map["Material"] = m_knownMaterials[id];
186 }
187 }
188 return map;
189 }
190
191 void GetStoredMaterialsForPart(SceneObjectPart part)
192 {
193 OSD OSMaterials = null;
194 OSDArray matsArr = null;
195
196 if (part.DynAttrs == null)
197 {
198 m_log.Warn("[MaterialsDemoModule]: NULL DYNATTRS :( ");
199 }
200
201 lock (part.DynAttrs)
202 {
203 if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
204 {
205 OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
206
207 if (materialsStore == null)
208 return;
209
210 materialsStore.TryGetValue("Materials", out OSMaterials);
211 }
212
213 if (OSMaterials != null && OSMaterials is OSDArray)
214 matsArr = OSMaterials as OSDArray;
215 else
216 return;
217 }
218
219 m_log.Info("[MaterialsDemoModule]: OSMaterials: " + OSDParser.SerializeJsonString(OSMaterials));
220
221 if (matsArr == null)
222 {
223 m_log.Info("[MaterialsDemoModule]: matsArr is null :( ");
224 return;
225 }
226
227 foreach (OSD elemOsd in matsArr)
228 {
229 if (elemOsd != null && elemOsd is OSDMap)
230 {
231 OSDMap matMap = elemOsd as OSDMap;
232 if (matMap.ContainsKey("ID") && matMap.ContainsKey("Material"))
233 {
234 try
235 {
236 lock (m_knownMaterials)
237 m_knownMaterials[matMap["ID"].AsUUID()] = (OSDMap)matMap["Material"];
238 }
239 catch (Exception e)
240 {
241 m_log.Warn("[MaterialsDemoModule]: exception decoding persisted material: " + e.ToString());
242 }
243 }
244 }
245 }
246 }
247
248 void StoreMaterialsForPart(SceneObjectPart part)
249 {
250 try
251 {
252 if (part == null || part.Shape == null)
253 return;
254
255 Dictionary<UUID, OSDMap> mats = new Dictionary<UUID, OSDMap>();
256
257 Primitive.TextureEntry te = part.Shape.Textures;
258
259 if (te.DefaultTexture != null)
260 {
261 lock (m_knownMaterials)
262 {
263 if (m_knownMaterials.ContainsKey(te.DefaultTexture.MaterialID))
264 mats[te.DefaultTexture.MaterialID] = m_knownMaterials[te.DefaultTexture.MaterialID];
265 }
266 }
267
268 if (te.FaceTextures != null)
269 {
270 foreach (var face in te.FaceTextures)
271 {
272 if (face != null)
273 {
274 lock (m_knownMaterials)
275 {
276 if (m_knownMaterials.ContainsKey(face.MaterialID))
277 mats[face.MaterialID] = m_knownMaterials[face.MaterialID];
278 }
279 }
280 }
281 }
282 if (mats.Count == 0)
283 return;
284
285 OSDArray matsArr = new OSDArray();
286 foreach (KeyValuePair<UUID, OSDMap> kvp in mats)
287 {
288 OSDMap matOsd = new OSDMap();
289 matOsd["ID"] = OSD.FromUUID(kvp.Key);
290 matOsd["Material"] = kvp.Value;
291 matsArr.Add(matOsd);
292 }
293
294 OSDMap OSMaterials = new OSDMap();
295 OSMaterials["Materials"] = matsArr;
296
297 lock (part.DynAttrs)
298 part.DynAttrs.SetStore("OpenSim", "Materials", OSMaterials);
299 }
300 catch (Exception e)
301 {
302 m_log.Warn("[MaterialsDemoModule]: exception in StoreMaterialsForPart(): " + e.ToString());
303 }
304 }
305
306 public string RenderMaterialsPostCap(string request, string path,
307 string param, IOSHttpRequest httpRequest,
308 IOSHttpResponse httpResponse)
309 {
310 m_log.Debug("[MaterialsDemoModule]: POST cap handler");
311
312 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
313 OSDMap resp = new OSDMap();
314
315 OSDMap materialsFromViewer = null;
316
317 OSDArray respArr = new OSDArray();
318
319 if (req.ContainsKey("Zipped"))
320 {
321 OSD osd = null;
322
323 byte[] inBytes = req["Zipped"].AsBinary();
324
325 try
326 {
327 osd = ZDecompressBytesToOsd(inBytes);
328
329 if (osd != null)
330 {
331 if (osd is OSDArray) // assume array of MaterialIDs designating requested material entries
332 {
333 foreach (OSD elem in (OSDArray)osd)
334 {
335
336 try
337 {
338 UUID id = new UUID(elem.AsBinary(), 0);
339
340 lock (m_knownMaterials)
341 {
342 if (m_knownMaterials.ContainsKey(id))
343 {
344 m_log.Info("[MaterialsDemoModule]: request for known material ID: " + id.ToString());
345 OSDMap matMap = new OSDMap();
346 matMap["ID"] = OSD.FromBinary(id.GetBytes());
347
348 matMap["Material"] = m_knownMaterials[id];
349 respArr.Add(matMap);
350 }
351 else
352 m_log.Info("[MaterialsDemoModule]: request for UNKNOWN material ID: " + id.ToString());
353 }
354 }
355 catch (Exception e)
356 {
357 // report something here?
358 continue;
359 }
360 }
361 }
362 else if (osd is OSDMap) // reqest to assign a material
363 {
364 materialsFromViewer = osd as OSDMap;
365
366 if (materialsFromViewer.ContainsKey("FullMaterialsPerFace"))
367 {
368 OSD matsOsd = materialsFromViewer["FullMaterialsPerFace"];
369 if (matsOsd is OSDArray)
370 {
371 OSDArray matsArr = matsOsd as OSDArray;
372
373 try
374 {
375 foreach (OSDMap matsMap in matsArr)
376 {
377 m_log.Debug("[MaterialsDemoModule]: processing matsMap: " + OSDParser.SerializeJsonString(matsMap));
378
379 uint matLocalID = 0;
380 try { matLocalID = matsMap["ID"].AsUInteger(); }
381 catch (Exception e) { m_log.Warn("[MaterialsDemoModule]: cannot decode \"ID\" from matsMap: " + e.Message); }
382 m_log.Debug("[MaterialsDemoModule]: matLocalId: " + matLocalID.ToString());
383
384
385 OSDMap mat = null;
386 try { mat = matsMap["Material"] as OSDMap; }
387 catch (Exception e) { m_log.Warn("[MaterialsDemoModule]: cannot decode \"Material\" from matsMap: " + e.Message); }
388 m_log.Debug("[MaterialsDemoModule]: mat: " + OSDParser.SerializeJsonString(mat));
389
390 UUID id = HashOsd(mat);
391 lock (m_knownMaterials)
392 m_knownMaterials[id] = mat;
393
394
395 var sop = m_scene.GetSceneObjectPart(matLocalID);
396 if (sop == null)
397 m_log.Debug("[MaterialsDemoModule]: null SOP for localId: " + matLocalID.ToString());
398 else
399 {
400 var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length);
401
402 if (te == null)
403 {
404 m_log.Debug("[MaterialsDemoModule]: null TextureEntry for localId: " + matLocalID.ToString());
405 }
406 else
407 {
408 int face = -1;
409
410 if (matsMap.ContainsKey("Face"))
411 {
412 face = matsMap["Face"].AsInteger();
413 if (te.FaceTextures == null) // && face == 0)
414 {
415 if (te.DefaultTexture == null)
416 m_log.Debug("[MaterialsDemoModule]: te.DefaultTexture is null");
417 else
418 te.DefaultTexture.MaterialID = id;
419 }
420 else
421 {
422 if (te.FaceTextures.Length >= face - 1)
423 {
424 if (te.FaceTextures[face] == null)
425 te.DefaultTexture.MaterialID = id;
426 else
427 te.FaceTextures[face].MaterialID = id;
428 }
429 }
430 }
431 else
432 {
433 if (te.DefaultTexture != null)
434 te.DefaultTexture.MaterialID = id;
435 }
436
437 m_log.Debug("[MaterialsDemoModule]: setting material ID for face " + face.ToString() + " to " + id.ToString());
438
439 //we cant use sop.UpdateTextureEntry(te); because it filters so do it manually
440
441 if (sop.ParentGroup != null)
442 {
443 sop.Shape.TextureEntry = te.GetBytes();
444 sop.TriggerScriptChangedEvent(Changed.TEXTURE);
445 sop.UpdateFlag = UpdateRequired.FULL;
446 sop.ParentGroup.HasGroupChanged = true;
447
448 sop.ScheduleFullUpdate();
449
450 StoreMaterialsForPart(sop);
451 }
452 }
453 }
454 }
455 }
456 catch (Exception e)
457 {
458 m_log.Warn("[MaterialsDemoModule]: exception processing received material: " + e.Message);
459 }
460 }
461 }
462 }
463 }
464
465 }
466 catch (Exception e)
467 {
468 m_log.Warn("[MaterialsDemoModule]: exception decoding zipped CAP payload: " + e.Message);
469 //return "";
470 }
471 m_log.Debug("[MaterialsDemoModule]: knownMaterials.Count: " + m_knownMaterials.Count.ToString());
472 }
473
474
475 resp["Zipped"] = ZCompressOSD(respArr, false);
476 string response = OSDParser.SerializeLLSDXmlString(resp);
477
478 //m_log.Debug("[MaterialsDemoModule]: cap request: " + request);
479 m_log.Debug("[MaterialsDemoModule]: cap request (zipped portion): " + ZippedOsdBytesToString(req["Zipped"].AsBinary()));
480 m_log.Debug("[MaterialsDemoModule]: cap response: " + response);
481 return response;
482 }
483
484
485 public string RenderMaterialsGetCap(string request, string path,
486 string param, IOSHttpRequest httpRequest,
487 IOSHttpResponse httpResponse)
488 {
489 m_log.Debug("[MaterialsDemoModule]: GET cap handler");
490
491 OSDMap resp = new OSDMap();
492 int matsCount = 0;
493 OSDArray allOsd = new OSDArray();
494
495 lock (m_knownMaterials)
496 {
497 foreach (KeyValuePair<UUID, OSDMap> kvp in m_knownMaterials)
498 {
499 OSDMap matMap = new OSDMap();
500
501 matMap["ID"] = OSD.FromBinary(kvp.Key.GetBytes());
502 matMap["Material"] = kvp.Value;
503 allOsd.Add(matMap);
504 matsCount++;
505 }
506 }
507
508 resp["Zipped"] = ZCompressOSD(allOsd, false);
509 m_log.Debug("[MaterialsDemoModule]: matsCount: " + matsCount.ToString());
510
511 return OSDParser.SerializeLLSDXmlString(resp);
512 }
513
514 static string ZippedOsdBytesToString(byte[] bytes)
515 {
516 try
517 {
518 return OSDParser.SerializeJsonString(ZDecompressBytesToOsd(bytes));
519 }
520 catch (Exception e)
521 {
522 return "ZippedOsdBytesToString caught an exception: " + e.ToString();
523 }
524 }
525
526 /// <summary>
527 /// computes a UUID by hashing a OSD object
528 /// </summary>
529 /// <param name="osd"></param>
530 /// <returns></returns>
531 private static UUID HashOsd(OSD osd)
532 {
533 using (var md5 = MD5.Create())
534 using (MemoryStream ms = new MemoryStream(OSDParser.SerializeLLSDBinary(osd, false)))
535 return new UUID(md5.ComputeHash(ms), 0);
536 }
537
538 public static OSD ZCompressOSD(OSD inOsd, bool useHeader)
539 {
540 OSD osd = null;
541
542 using (MemoryStream msSinkCompressed = new MemoryStream())
543 {
544 using (Ionic.Zlib.ZlibStream zOut = new Ionic.Zlib.ZlibStream(msSinkCompressed,
545 Ionic.Zlib.CompressionMode.Compress, CompressionLevel.BestCompression, true))
546 {
547 CopyStream(new MemoryStream(OSDParser.SerializeLLSDBinary(inOsd, useHeader)), zOut);
548 zOut.Close();
549 }
550
551 msSinkCompressed.Seek(0L, SeekOrigin.Begin);
552 osd = OSD.FromBinary( msSinkCompressed.ToArray());
553 }
554
555 return osd;
556 }
557
558
559 public static OSD ZDecompressBytesToOsd(byte[] input)
560 {
561 OSD osd = null;
562
563 using (MemoryStream msSinkUnCompressed = new MemoryStream())
564 {
565 using (Ionic.Zlib.ZlibStream zOut = new Ionic.Zlib.ZlibStream(msSinkUnCompressed, CompressionMode.Decompress, true))
566 {
567 CopyStream(new MemoryStream(input), zOut);
568 zOut.Close();
569 }
570 msSinkUnCompressed.Seek(0L, SeekOrigin.Begin);
571 osd = OSDParser.DeserializeLLSDBinary(msSinkUnCompressed.ToArray());
572 }
573
574 return osd;
575 }
576
577 static void CopyStream(System.IO.Stream input, System.IO.Stream output)
578 {
579 byte[] buffer = new byte[2048];
580 int len;
581 while ((len = input.Read(buffer, 0, 2048)) > 0)
582 {
583 output.Write(buffer, 0, len);
584 }
585
586 output.Flush();
587 }
588
589 // FIXME: This code is currently still in UuidGatherer since we cannot use Scene.EventManager as some
590 // calls to the gatherer are done for objects with no scene.
591// /// <summary>
592// /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps
593// /// </summary>
594// /// <param name="part"></param>
595// /// <param name="assetUuids"></param>
596// private void GatherMaterialsUuids(SceneObjectPart part, IDictionary<UUID, AssetType> assetUuids)
597// {
598// // scan thru the dynAttrs map of this part for any textures used as materials
599// OSD osdMaterials = null;
600//
601// lock (part.DynAttrs)
602// {
603// if (part.DynAttrs.ContainsStore("OpenSim", "Materials"))
604// {
605// OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials");
606// if (materialsStore == null)
607// return;
608//
609// materialsStore.TryGetValue("Materials", out osdMaterials);
610// }
611//
612// if (osdMaterials != null)
613// {
614// //m_log.Info("[UUID Gatherer]: found Materials: " + OSDParser.SerializeJsonString(osd));
615//
616// if (osdMaterials is OSDArray)
617// {
618// OSDArray matsArr = osdMaterials as OSDArray;
619// foreach (OSDMap matMap in matsArr)
620// {
621// try
622// {
623// if (matMap.ContainsKey("Material"))
624// {
625// OSDMap mat = matMap["Material"] as OSDMap;
626// if (mat.ContainsKey("NormMap"))
627// {
628// UUID normalMapId = mat["NormMap"].AsUUID();
629// if (normalMapId != UUID.Zero)
630// {
631// assetUuids[normalMapId] = AssetType.Texture;
632// //m_log.Info("[UUID Gatherer]: found normal map ID: " + normalMapId.ToString());
633// }
634// }
635// if (mat.ContainsKey("SpecMap"))
636// {
637// UUID specularMapId = mat["SpecMap"].AsUUID();
638// if (specularMapId != UUID.Zero)
639// {
640// assetUuids[specularMapId] = AssetType.Texture;
641// //m_log.Info("[UUID Gatherer]: found specular map ID: " + specularMapId.ToString());
642// }
643// }
644// }
645//
646// }
647// catch (Exception e)
648// {
649// m_log.Warn("[MaterialsDemoModule]: exception getting materials: " + e.Message);
650// }
651// }
652// }
653// }
654// }
655// }
656 }
657} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
index 6009dc5..d1d318c 100755
--- a/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ExtendedPhysics/ExtendedPhysics.cs
@@ -31,10 +31,10 @@ using System.Reflection;
31using System.Text; 31using System.Text;
32 32
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.CoreModules;
34using OpenSim.Region.Framework; 35using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.CoreModules;
38 38
39using Mono.Addins; 39using Mono.Addins;
40using Nini.Config; 40using Nini.Config;
@@ -49,6 +49,20 @@ public class ExtendedPhysics : INonSharedRegionModule
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 private static string LogHeader = "[EXTENDED PHYSICS]"; 50 private static string LogHeader = "[EXTENDED PHYSICS]";
51 51
52 // =============================================================
53 // Since BulletSim is a plugin, this these values aren't defined easily in one place.
54 // This table must correspond to an identical table in BSScene.
55
56 // Per scene functions. See BSScene.
57
58 // Per avatar functions. See BSCharacter.
59
60 // Per prim functions. See BSPrim.
61 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
62 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
63
64 // =============================================================
65
52 private IConfig Configuration { get; set; } 66 private IConfig Configuration { get; set; }
53 private bool Enabled { get; set; } 67 private bool Enabled { get; set; }
54 private Scene BaseScene { get; set; } 68 private Scene BaseScene { get; set; }
@@ -119,6 +133,7 @@ public class ExtendedPhysics : INonSharedRegionModule
119 133
120 // Register as LSL functions all the [ScriptInvocation] marked methods. 134 // Register as LSL functions all the [ScriptInvocation] marked methods.
121 Comms.RegisterScriptInvocations(this); 135 Comms.RegisterScriptInvocations(this);
136 Comms.RegisterConstants(this);
122 137
123 // When an object is modified, we might need to update its extended physics parameters 138 // When an object is modified, we might need to update its extended physics parameters
124 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; 139 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
@@ -132,7 +147,6 @@ public class ExtendedPhysics : INonSharedRegionModule
132 147
133 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj) 148 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
134 { 149 {
135 throw new NotImplementedException();
136 } 150 }
137 151
138 // Event generated when some property of a prim changes. 152 // Event generated when some property of a prim changes.
@@ -143,13 +157,6 @@ public class ExtendedPhysics : INonSharedRegionModule
143 [ScriptConstant] 157 [ScriptConstant]
144 public static int PHYS_CENTER_OF_MASS = 1 << 0; 158 public static int PHYS_CENTER_OF_MASS = 1 << 0;
145 159
146 [ScriptConstant]
147 public static int PHYS_LINKSET_TYPE_CONSTRAINT = 1;
148 [ScriptConstant]
149 public static int PHYS_LINKSET_TYPE_COMPOUND = 2;
150 [ScriptConstant]
151 public static int PHYS_LINKSET_TYPE_MANUAL = 3;
152
153 [ScriptInvocation] 160 [ScriptInvocation]
154 public string physGetEngineType(UUID hostID, UUID scriptID) 161 public string physGetEngineType(UUID hostID, UUID scriptID)
155 { 162 {
@@ -163,9 +170,95 @@ public class ExtendedPhysics : INonSharedRegionModule
163 return ret; 170 return ret;
164 } 171 }
165 172
173 [ScriptConstant]
174 public static int PHYS_LINKSET_TYPE_CONSTRAINT = 0;
175 [ScriptConstant]
176 public static int PHYS_LINKSET_TYPE_COMPOUND = 1;
177 [ScriptConstant]
178 public static int PHYS_LINKSET_TYPE_MANUAL = 2;
179
166 [ScriptInvocation] 180 [ScriptInvocation]
167 public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType) 181 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
168 { 182 {
183 int ret = -1;
184
185 if (!Enabled) return ret;
186
187 // The part that is requesting the change.
188 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
189
190 if (requestingPart != null)
191 {
192 // The change is always made to the root of a linkset.
193 SceneObjectGroup containingGroup = requestingPart.ParentGroup;
194 SceneObjectPart rootPart = containingGroup.RootPart;
195
196 if (rootPart != null)
197 {
198 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
199 if (rootPhysActor != null)
200 {
201 ret = (int)rootPhysActor.Extension(PhysFunctSetLinksetType, linksetType);
202 }
203 else
204 {
205 m_log.WarnFormat("{0} physSetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
206 LogHeader, rootPart.Name, hostID);
207 }
208 }
209 else
210 {
211 m_log.WarnFormat("{0} physSetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
212 LogHeader, requestingPart.Name, hostID);
213 }
214 }
215 else
216 {
217 m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
218 }
219 return ret;
220 }
221
222 [ScriptInvocation]
223 public int physGetLinksetType(UUID hostID, UUID scriptID)
224 {
225 int ret = -1;
226
227 if (!Enabled) return ret;
228
229 // The part that is requesting the change.
230 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
231
232 if (requestingPart != null)
233 {
234 // The type is is always on the root of a linkset.
235 SceneObjectGroup containingGroup = requestingPart.ParentGroup;
236 SceneObjectPart rootPart = containingGroup.RootPart;
237
238 if (rootPart != null)
239 {
240 Physics.Manager.PhysicsActor rootPhysActor = rootPart.PhysActor;
241 if (rootPhysActor != null)
242 {
243 ret = (int)rootPhysActor.Extension(PhysFunctGetLinksetType);
244 }
245 else
246 {
247 m_log.WarnFormat("{0} physGetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
248 LogHeader, rootPart.Name, hostID);
249 }
250 }
251 else
252 {
253 m_log.WarnFormat("{0} physGetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
254 LogHeader, requestingPart.Name, hostID);
255 }
256 }
257 else
258 {
259 m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
260 }
261 return ret;
169 } 262 }
170} 263}
171} 264}
diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
index c68fe99..3b3b300 100644
--- a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
+++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs
@@ -263,7 +263,7 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport
263 m_module = module; 263 m_module = module;
264 } 264 }
265 265
266 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 266 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
267 { 267 {
268 StreamReader reader = new StreamReader(request); 268 StreamReader reader = new StreamReader(request);
269 string requestBody = reader.ReadToEnd(); 269 string requestBody = reader.ReadToEnd();
diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
index 5d10e93..bcb21d0 100644
--- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
+++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
@@ -696,7 +696,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
696 /// <param name="agentId"></param> 696 /// <param name="agentId"></param>
697 public void EconomyDataRequestHandler(IClientAPI user) 697 public void EconomyDataRequestHandler(IClientAPI user)
698 { 698 {
699 Scene s = LocateSceneClientIn(user.AgentId); 699 Scene s = (Scene)user.Scene;
700 700
701 user.SendEconomyData(EnergyEfficiency, s.RegionInfo.ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, 701 user.SendEconomyData(EnergyEfficiency, s.RegionInfo.ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate,
702 PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, 702 PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor,
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 4674489..f2355e2 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -259,6 +259,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
259 public event Action<IClientAPI, bool> OnCompleteMovementToRegion; 259 public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
260 public event UpdateAgent OnPreAgentUpdate; 260 public event UpdateAgent OnPreAgentUpdate;
261 public event UpdateAgent OnAgentUpdate; 261 public event UpdateAgent OnAgentUpdate;
262 public event UpdateAgent OnAgentCameraUpdate;
262 public event AgentRequestSit OnAgentRequestSit; 263 public event AgentRequestSit OnAgentRequestSit;
263 public event AgentSit OnAgentSit; 264 public event AgentSit OnAgentSit;
264 public event AvatarPickerRequest OnAvatarPickerRequest; 265 public event AvatarPickerRequest OnAvatarPickerRequest;
@@ -393,6 +394,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
393 public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest; 394 public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest;
394 public event EstateChangeInfo OnEstateChangeInfo; 395 public event EstateChangeInfo OnEstateChangeInfo;
395 public event EstateManageTelehub OnEstateManageTelehub; 396 public event EstateManageTelehub OnEstateManageTelehub;
397 public event CachedTextureRequest OnCachedTextureRequest;
396 public event ScriptReset OnScriptReset; 398 public event ScriptReset OnScriptReset;
397 public event GetScriptRunning OnGetScriptRunning; 399 public event GetScriptRunning OnGetScriptRunning;
398 public event SetScriptRunning OnSetScriptRunning; 400 public event SetScriptRunning OnSetScriptRunning;
@@ -573,6 +575,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
573 { 575 {
574 } 576 }
575 577
578 public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List<CachedTextureResponseArg> cachedTextures)
579 {
580
581 }
582
576 public virtual void Kick(string message) 583 public virtual void Kick(string message)
577 { 584 {
578 } 585 }
@@ -590,7 +597,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
590 597
591 } 598 }
592 599
593 public virtual void SendKillObject(ulong regionHandle, List<uint> localID) 600 public virtual void SendKillObject(List<uint> localID)
594 { 601 {
595 } 602 }
596 603
@@ -1236,7 +1243,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
1236 { 1243 {
1237 } 1244 }
1238 1245
1239 public void StopFlying(ISceneEntity presence) 1246 public void SendAgentTerseUpdate(ISceneEntity presence)
1240 { 1247 {
1241 } 1248 }
1242 1249
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 8c9c006..78fe096 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -116,7 +116,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
116 return false; 116 return false;
117 117
118 // Delete existing npc attachments 118 // Delete existing npc attachments
119 scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false); 119 if(scene.AttachmentsModule != null)
120 scene.AttachmentsModule.DeleteAttachmentsFromScene(npc, false);
120 121
121 // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet 122 // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet
122 // since it doesn't transfer attachments 123 // since it doesn't transfer attachments
@@ -125,7 +126,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
125 npc.Appearance = npcAppearance; 126 npc.Appearance = npcAppearance;
126 127
127 // Rez needed npc attachments 128 // Rez needed npc attachments
128 scene.AttachmentsModule.RezAttachments(npc); 129 if (scene.AttachmentsModule != null)
130 scene.AttachmentsModule.RezAttachments(npc);
129 131
130 IAvatarFactoryModule module = 132 IAvatarFactoryModule module =
131 scene.RequestModuleInterface<IAvatarFactoryModule>(); 133 scene.RequestModuleInterface<IAvatarFactoryModule>();
@@ -375,7 +377,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
375 m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove", 377 m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove",
376 agentID, av.Name); 378 agentID, av.Name);
377 */ 379 */
378 scene.RemoveClient(agentID, false); 380
381 scene.IncomingCloseAgent(agentID, false);
382// scene.RemoveClient(agentID, false);
379 m_avatars.Remove(agentID); 383 m_avatars.Remove(agentID);
380 384
381// m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}", agentID, av.Name); 385// m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}", agentID, av.Name);
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 34362af..20c178c 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -155,7 +155,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
155 public void TestCreateWithAttachments() 155 public void TestCreateWithAttachments()
156 { 156 {
157 TestHelpers.InMethod(); 157 TestHelpers.InMethod();
158// log4net.Config.XmlConfigurator.Configure(); 158// TestHelpers.EnableLogging();
159 159
160 UUID userId = TestHelpers.ParseTail(0x1); 160 UUID userId = TestHelpers.ParseTail(0x1);
161 UserAccountHelpers.CreateUserWithInventory(m_scene, userId); 161 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
diff --git a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs
index 550b5d4..8720cc7 100644
--- a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs
+++ b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.World.WorldView
55 m_WorldViewModule = fmodule; 55 m_WorldViewModule = fmodule;
56 } 56 }
57 57
58 public override byte[] Handle(string path, Stream requestData, 58 protected override byte[] ProcessRequest(string path, Stream requestData,
59 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 59 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
60 { 60 {
61 httpResponse.ContentType = "image/jpeg"; 61 httpResponse.ContentType = "image/jpeg";