OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
SceneCommunicationService.cs
Go to the documentation of this file.
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.Generic;
30 using System.Net;
31 using System.Reflection;
32 using System.Threading;
33 using OpenMetaverse;
34 using OpenMetaverse.StructuredData;
35 using log4net;
36 using OpenSim.Framework;
37 using OpenSim.Framework.Client;
38 using OpenSim.Framework.Capabilities;
39 using OpenSim.Region.Framework.Interfaces;
40 using OpenSim.Services.Interfaces;
43 
44 namespace OpenSim.Region.Framework.Scenes
45 {
46  public delegate void RemoveKnownRegionsFromAvatarList(UUID avatarID, List<ulong> regionlst);
47 
51  public class SceneCommunicationService //one instance per region
52  {
53  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54  private static string LogHeader = "[SCENE COMMUNICATION SERVICE]";
55 
57  protected Scene m_scene;
58 
59  public void SetScene(Scene s)
60  {
61  m_scene = s;
62  m_regionInfo = s.RegionInfo;
63  }
64 
65  public delegate void InformNeighbourThatRegionUpDelegate(INeighbourService nService, RegionInfo region, ulong regionhandle);
66 
67  private void InformNeighborsThatRegionisUpCompleted(IAsyncResult iar)
68  {
69  InformNeighbourThatRegionUpDelegate icon = (InformNeighbourThatRegionUpDelegate)iar.AsyncState;
70  icon.EndInvoke(iar);
71  }
72 
78  private void InformNeighboursThatRegionIsUpAsync(INeighbourService neighbourService, RegionInfo region, ulong regionhandle)
79  {
80  uint x = 0, y = 0;
81  Utils.LongToUInts(regionhandle, out x, out y);
82 
83  GridRegion neighbour = null;
84  if (neighbourService != null)
85  neighbour = neighbourService.HelloNeighbour(regionhandle, region);
86  else
87  m_log.DebugFormat("{0} neighbour service provided for region {0} to inform neigbhours of status", LogHeader, m_scene.Name);
88 
89  if (neighbour != null)
90  {
91  m_log.DebugFormat("{0} Region {1} successfully informed neighbour {2} at {3}-{4} that it is up",
92  LogHeader, m_scene.Name, neighbour.RegionName, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y));
93 
94  m_scene.EventManager.TriggerOnRegionUp(neighbour);
95  }
96  else
97  {
98  m_log.WarnFormat(
99  "[SCENE COMMUNICATION SERVICE]: Region {0} failed to inform neighbour at {1}-{2} that it is up.",
100  m_scene.Name, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y));
101  }
102  }
103 
104  public void InformNeighborsThatRegionisUp(INeighbourService neighbourService, RegionInfo region)
105  {
106  //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
107 
108  List<GridRegion> neighbours
109  = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID);
110 
111  List<GridRegion> onlineNeighbours = new List<GridRegion>();
112 
113  foreach (GridRegion n in neighbours)
114  {
116 
117  // m_log.DebugFormat(
118  // "{0}: Region flags for {1} as seen by {2} are {3}",
119  // LogHeader, n.RegionName, m_scene.Name, regionFlags != null ? regionFlags.ToString() : "not present");
120 
121  // Robust services before 2015-01-14 do not return the regionFlags information. In this case, we could
122  // make a separate RegionFlags call but this would involve a network call for each neighbour.
123  if (regionFlags != null)
124  {
125  if ((regionFlags & OpenSim.Framework.RegionFlags.RegionOnline) != 0)
126  onlineNeighbours.Add(n);
127  }
128  else
129  {
130  onlineNeighbours.Add(n);
131  }
132  }
133 
134  m_log.DebugFormat(
135  "{0} Informing {1} neighbours that region {2} is up",
136  LogHeader, onlineNeighbours.Count, m_scene.Name);
137 
138  foreach (GridRegion n in onlineNeighbours)
139  {
140  InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync;
141  d.BeginInvoke(neighbourService, region, n.RegionHandle,
142  InformNeighborsThatRegionisUpCompleted,
143  d);
144  }
145  }
146 
147  public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, GridRegion dest);
148 
156  private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, GridRegion dest)
157  {
158  //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName);
159  try
160  {
161  m_scene.SimulationService.UpdateAgent(dest, cAgentData);
162  }
163  catch
164  {
165  // Ignore; we did our best
166  }
167  }
168 
169  private void SendChildAgentDataUpdateCompleted(IAsyncResult iar)
170  {
171  SendChildAgentDataUpdateDelegate icon = (SendChildAgentDataUpdateDelegate)iar.AsyncState;
172  icon.EndInvoke(iar);
173  }
174 
175  public void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence)
176  {
177  // m_log.DebugFormat(
178  // "[SCENE COMMUNICATION SERVICE]: Sending child agent position updates for {0} in {1}",
179  // presence.Name, m_scene.Name);
180 
181  // This assumes that we know what our neighbors are.
182  try
183  {
184  uint x = 0, y = 0;
185  List<string> simulatorList = new List<string>();
186  foreach (ulong regionHandle in presence.KnownRegionHandles)
187  {
188  if (regionHandle != m_regionInfo.RegionHandle)
189  {
190  // we only want to send one update to each simulator; the simulator will
191  // hand it off to the regions where a child agent exists, this does assume
192  // that the region position is cached or performance will degrade
193  Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
194  GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
195  if (dest == null)
196  continue;
197 
198  if (!simulatorList.Contains(dest.ServerURI))
199  {
200  // we havent seen this simulator before, add it to the list
201  // and send it an update
202  simulatorList.Add(dest.ServerURI);
203  // Let move this to sync. Mono definitely does not like async networking.
204  m_scene.SimulationService.UpdateAgent(dest, cAgentData);
205 
206  // Leaving this here as a reminder that we tried, and it sucks.
207  //SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
208  //d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
209  // SendChildAgentDataUpdateCompleted,
210  // d);
211  }
212  }
213  }
214  }
215  catch (InvalidOperationException)
216  {
217  // We're ignoring a collection was modified error because this data gets old and outdated fast.
218  }
219  }
220 
221  public delegate void SendCloseChildAgentDelegate(UUID agentID, ulong regionHandle);
222 
227  protected void SendCloseChildAgent(UUID agentID, ulong regionHandle, string auth_token)
228  {
229  // let's do our best, but there's not much we can do if the neighbour doesn't accept.
230 
231  //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
232  uint x = 0, y = 0;
233  Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
234 
235  GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y);
236 
237  if (destination == null)
238  {
239  m_log.DebugFormat(
240  "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} FAIL, region with handle {1} not found", agentID, regionHandle);
241  return;
242  }
243 
244  m_log.DebugFormat(
245  "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName);
246 
247  m_scene.SimulationService.CloseAgent(destination, agentID, auth_token);
248  }
249 
256  public void SendCloseChildAgentConnections(UUID agentID, string auth_code, List<ulong> regionslst)
257  {
258  if (regionslst.Count == 0)
259  return;
260 
261  // use a single thread job for all
262  Util.FireAndForget(o =>
263  {
264  foreach (ulong handle in regionslst)
265  {
266  SendCloseChildAgent(agentID, handle, auth_code);
267  }
268  }, null, "SceneCommunicationService.SendCloseChildAgentConnections");
269  }
270 
271  public List<GridRegion> RequestNamedRegions(string name, int maxNumber)
272  {
273  return m_scene.GridService.GetRegionsByName(UUID.Zero, name, maxNumber);
274  }
275  }
276 }
delegate void RemoveKnownRegionsFromAvatarList(UUID avatarID, List< ulong > regionlst)
OpenSim.Framework.RegionInfo RegionInfo
RegionFlags
Region flags used internally by OpenSimulator to store installation specific information about region...
Definition: RegionFlags.cs:40
void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence)
void InformNeighborsThatRegionisUp(INeighbourService neighbourService, RegionInfo region)
OpenMetaverse.StructuredData.OSD OSD
Replacement for ChildAgentDataUpdate. Used over RESTComms and LocalComms.
void SendCloseChildAgentConnections(UUID agentID, string auth_code, List< ulong > regionslst)
Closes a child agents in a collection of regions. Does so asynchronously so that the caller doesn't w...
Interactive OpenSim region server
Definition: OpenSim.cs:55
List< GridRegion > RequestNamedRegions(string name, int maxNumber)
OpenMetaverse.StructuredData.OSD OSD
OpenSim.Services.Interfaces.GridRegion GridRegion
void SendCloseChildAgent(UUID agentID, ulong regionHandle, string auth_token)
This Closes child agents on neighboring regions Calls an asynchronous method to do so...