clockwerk-opensim-stable – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Net;
32 using System.Reflection;
33 using log4net;
34 using Nini.Config;
35 using Nwc.XmlRpc;
36 using Mono.Addins;
37 using OpenMetaverse;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Servers;
40 using OpenSim.Region.Framework.Interfaces;
41 using OpenSim.Region.Framework.Scenes;
42 using GridRegion = OpenSim.Services.Interfaces.GridRegion;
43 using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
44 using OpenSim.Services.Interfaces;
45 using OpenSim.Services.Connectors.InstantMessage;
46 using OpenSim.Services.Connectors.Hypergrid;
47 using OpenSim.Server.Handlers.Hypergrid;
48  
49 namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
50 {
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGMessageTransferModule")]
52 public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector
53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55  
56 protected bool m_Enabled = false;
57 protected List<Scene> m_Scenes = new List<Scene>();
58  
59 protected IInstantMessage m_IMService;
60 protected Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
61  
62 public event UndeliveredMessage OnUndeliveredMessage;
63  
64 IUserManagement m_uMan;
65 IUserManagement UserManagementModule
66 {
67 get
68 {
69 if (m_uMan == null)
70 m_uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
71 return m_uMan;
72 }
73 }
74  
75 public virtual void Initialise(IConfigSource config)
76 {
77 IConfig cnf = config.Configs["Messaging"];
78 if (cnf != null && cnf.GetString(
79 "MessageTransferModule", "MessageTransferModule") != Name)
80 {
81 m_log.Debug("[HG MESSAGE TRANSFER]: Disabled by configuration");
82 return;
83 }
84  
85 InstantMessageServerConnector imServer = new InstantMessageServerConnector(config, MainServer.Instance, this);
86 m_IMService = imServer.GetService();
87 m_Enabled = true;
88 }
89  
90 public virtual void AddRegion(Scene scene)
91 {
92 if (!m_Enabled)
93 return;
94  
95 lock (m_Scenes)
96 {
97 m_log.DebugFormat("[HG MESSAGE TRANSFER]: Message transfer module {0} active", Name);
98 scene.RegisterModuleInterface<IMessageTransferModule>(this);
99 m_Scenes.Add(scene);
100 }
101 }
102  
103 public virtual void PostInitialise()
104 {
105 if (!m_Enabled)
106 return;
107  
108 }
109  
110 public virtual void RegionLoaded(Scene scene)
111 {
112 }
113  
114 public virtual void RemoveRegion(Scene scene)
115 {
116 if (!m_Enabled)
117 return;
118  
119 lock (m_Scenes)
120 {
121 m_Scenes.Remove(scene);
122 }
123 }
124  
125 public virtual void Close()
126 {
127 }
128  
129 public virtual string Name
130 {
131 get { return "HGMessageTransferModule"; }
132 }
133  
134 public virtual Type ReplaceableInterface
135 {
136 get { return null; }
137 }
138  
139 public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
140 {
141 UUID toAgentID = new UUID(im.toAgentID);
142  
143 // Try root avatar only first
144 foreach (Scene scene in m_Scenes)
145 {
146 // m_log.DebugFormat(
147 // "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}",
148 // toAgentID.ToString(), scene.RegionInfo.RegionName);
149 ScenePresence sp = scene.GetScenePresence(toAgentID);
150 if (sp != null && !sp.IsChildAgent)
151 {
152 // Local message
153 // m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
154 sp.ControllingClient.SendInstantMessage(im);
155  
156 // Message sent
157 result(true);
158 return;
159 }
160 }
161  
162 // try child avatar second
163 foreach (Scene scene in m_Scenes)
164 {
165 // m_log.DebugFormat(
166 // "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}",
167 // toAgentID, scene.RegionInfo.RegionName);
168 ScenePresence sp = scene.GetScenePresence(toAgentID);
169 if (sp != null)
170 {
171 // Local message
172 // m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
173 sp.ControllingClient.SendInstantMessage(im);
174  
175 // Message sent
176 result(true);
177 return;
178 }
179 }
180  
181 // m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
182 // Is the user a local user?
183 string url = string.Empty;
184 bool foreigner = false;
185 if (UserManagementModule != null && !UserManagementModule.IsLocalGridUser(toAgentID)) // foreign user
186 {
187 url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI");
188 foreigner = true;
189 }
190  
191 Util.FireAndForget(delegate
192 {
193 bool success = false;
194 if (foreigner && url == string.Empty) // we don't know about this user
195 {
196 string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID);
197 m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
198 if (recipientUUI != string.Empty)
199 {
200 UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty;
201 if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret))
202 {
203 success = m_IMService.OutgoingInstantMessage(im, u, true);
204 if (success)
205 UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last);
206 }
207 }
208 }
209 else
210 success = m_IMService.OutgoingInstantMessage(im, url, foreigner);
211  
212 if (!success && !foreigner)
213 HandleUndeliveredMessage(im, result);
214 else
215 result(success);
216 });
217  
218 return;
219 }
220  
221 protected bool SendIMToScene(GridInstantMessage gim, UUID toAgentID)
222 {
223 bool successful = false;
224 foreach (Scene scene in m_Scenes)
225 {
226 ScenePresence sp = scene.GetScenePresence(toAgentID);
227 if(sp != null && !sp.IsChildAgent)
228 {
229 scene.EventManager.TriggerIncomingInstantMessage(gim);
230 successful = true;
231 }
232 }
233  
234 if (!successful)
235 {
236 // If the message can't be delivered to an agent, it
237 // is likely to be a group IM. On a group IM, the
238 // imSessionID = toAgentID = group id. Raise the
239 // unhandled IM event to give the groups module
240 // a chance to pick it up. We raise that in a random
241 // scene, since the groups module is shared.
242 //
243 m_Scenes[0].EventManager.TriggerUnhandledInstantMessage(gim);
244 }
245  
246 return successful;
247 }
248  
249 protected void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
250 {
251 UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
252  
253 // If this event has handlers, then an IM from an agent will be
254 // considered delivered. This will suppress the error message.
255 //
256 if (handlerUndeliveredMessage != null)
257 {
258 handlerUndeliveredMessage(im);
259 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
260 result(true);
261 else
262 result(false);
263 return;
264 }
265  
266 //m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
267 result(false);
268 }
269  
270 private string TryGetRecipientUUI(UUID fromAgent, UUID toAgent)
271 {
272 // Let's call back the fromAgent's user agent service
273 // Maybe that service knows about the toAgent
274 IClientAPI client = LocateClientObject(fromAgent);
275 if (client != null)
276 {
277 AgentCircuitData circuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.AgentId);
278 if (circuit != null)
279 {
280 if (circuit.ServiceURLs.ContainsKey("HomeURI"))
281 {
282 string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
283 m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
284 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
285 return uasConn.GetUUI(fromAgent, toAgent);
286 }
287 }
288 }
289  
290 return string.Empty;
291 }
292  
293 /// <summary>
294 /// Find the root client for a ID
295 /// </summary>
296 public IClientAPI LocateClientObject(UUID agentID)
297 {
298 lock (m_Scenes)
299 {
300 foreach (Scene scene in m_Scenes)
301 {
302 ScenePresence presence = scene.GetScenePresence(agentID);
303 if (presence != null && !presence.IsChildAgent)
304 return presence.ControllingClient;
305 }
306 }
307  
308 return null;
309 }
310  
311 #region IInstantMessageSimConnector
312 public bool SendInstantMessage(GridInstantMessage im)
313 {
314 //m_log.DebugFormat("[XXX] Hook SendInstantMessage {0}", im.message);
315 UUID agentID = new UUID(im.toAgentID);
316 return SendIMToScene(im, agentID);
317 }
318 #endregion
319  
320  
321 }
322 }