OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
LocalSimulationConnector.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 using System;
28 using System.Collections.Generic;
29 using System.Linq;
30 using System.Reflection;
31 using log4net;
32 using Mono.Addins;
33 using Nini.Config;
34 using OpenMetaverse;
35 using OpenSim.Framework;
36 using OpenSim.Region.Framework.Interfaces;
37 using OpenSim.Region.Framework.Scenes;
38 using OpenSim.Services.Interfaces;
40 
41 namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
42 {
43  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalSimulationConnectorModule")]
45  {
46  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 
51  private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
52 
56  private bool m_ModuleEnabled = false;
57 
58  #region Region Module interface
59 
60  public void Initialise(IConfigSource configSource)
61  {
62  IConfig moduleConfig = configSource.Configs["Modules"];
63  if (moduleConfig != null)
64  {
65  string name = moduleConfig.GetString("SimulationServices", "");
66  if (name == Name)
67  {
68  InitialiseService(configSource);
69 
70  m_ModuleEnabled = true;
71 
72  m_log.Info("[LOCAL SIMULATION CONNECTOR]: Local simulation enabled.");
73  }
74  }
75  }
76 
77  public void InitialiseService(IConfigSource configSource)
78  {
79  }
80 
81  public void PostInitialise()
82  {
83  }
84 
85  public void AddRegion(Scene scene)
86  {
87  if (!m_ModuleEnabled)
88  return;
89 
90  Init(scene);
91  scene.RegisterModuleInterface<ISimulationService>(this);
92  }
93 
94  public void RemoveRegion(Scene scene)
95  {
96  if (!m_ModuleEnabled)
97  return;
98 
99  RemoveScene(scene);
100  scene.UnregisterModuleInterface<ISimulationService>(this);
101  }
102 
103  public void RegionLoaded(Scene scene)
104  {
105  }
106 
107  public void Close()
108  {
109  }
110 
111  public Type ReplaceableInterface
112  {
113  get { return null; }
114  }
115 
116  public string Name
117  {
118  get { return "LocalSimulationConnectorModule"; }
119  }
120 
125  public void RemoveScene(Scene scene)
126  {
127  lock (m_scenes)
128  {
129  if (m_scenes.ContainsKey(scene.RegionInfo.RegionID))
130  m_scenes.Remove(scene.RegionInfo.RegionID);
131  else
132  m_log.WarnFormat(
133  "[LOCAL SIMULATION CONNECTOR]: Tried to remove region {0} but it was not present",
134  scene.RegionInfo.RegionName);
135  }
136  }
137 
142  public void Init(Scene scene)
143  {
144  lock (m_scenes)
145  {
146  if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID))
147  m_scenes[scene.RegionInfo.RegionID] = scene;
148  else
149  m_log.WarnFormat(
150  "[LOCAL SIMULATION CONNECTOR]: Tried to add region {0} but it is already present",
151  scene.RegionInfo.RegionName);
152  }
153  }
154 
155  #endregion
156 
157  #region ISimulationService
158 
159  public IScene GetScene(UUID regionId)
160  {
161  if (m_scenes.ContainsKey(regionId))
162  {
163  return m_scenes[regionId];
164  }
165  else
166  {
167  // FIXME: This was pre-existing behaviour but possibly not a good idea, since it hides an error rather
168  // than making it obvious and fixable. Need to see if the error message comes up in practice.
169  Scene s = m_scenes.Values.ToArray()[0];
170 
171  m_log.ErrorFormat(
172  "[LOCAL SIMULATION CONNECTOR]: Region with id {0} not found. Returning {1} {2} instead",
173  regionId, s.RegionInfo.RegionName, s.RegionInfo.RegionID);
174 
175  return s;
176  }
177  }
178 
180  {
181  return this;
182  }
183 
188  public bool CreateAgent(GridRegion source, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason)
189  {
190  if (destination == null)
191  {
192  reason = "Given destination was null";
193  m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: CreateAgent was given a null destination");
194  return false;
195  }
196 
197  if (m_scenes.ContainsKey(destination.RegionID))
198  {
199 // m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName);
200  return m_scenes[destination.RegionID].NewUserConnection(aCircuit, teleportFlags, source, out reason);
201  }
202 
203  reason = "Did not find region " + destination.RegionName;
204  return false;
205  }
206 
207  public bool UpdateAgent(GridRegion destination, AgentData cAgentData, EntityTransferContext ctx)
208  {
209  if (destination == null)
210  return false;
211 
212  if (m_scenes.ContainsKey(destination.RegionID))
213  {
214 // m_log.DebugFormat(
215 // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
216 // destination.RegionName, destination.RegionID);
217 
218  return m_scenes[destination.RegionID].IncomingUpdateChildAgent(cAgentData);
219  }
220 
221 // m_log.DebugFormat(
222 // "[LOCAL COMMS]: Did not find region {0} {1} for ChildAgentUpdate",
223 // destination.RegionName, destination.RegionID);
224 
225  return false;
226  }
227 
228  public bool UpdateAgent(GridRegion destination, AgentPosition agentPosition)
229  {
230  if (destination == null)
231  return false;
232 
233  // We limit the number of messages sent for a position change to just one per
234  // simulator so when we receive the update we need to hand it to each of the
235  // scenes; scenes each check to see if the is a scene presence for the avatar
236  // note that we really don't need the GridRegion for this call
237  foreach (Scene s in m_scenes.Values)
238  {
239 // m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
240  s.IncomingUpdateChildAgent(agentPosition);
241  }
242 
243  //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
244  return true;
245  }
246 
247  public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> features, EntityTransferContext ctx, out string reason)
248  {
249  reason = "Communications failure";
250  if (destination == null)
251  return false;
252 
253  if (m_scenes.ContainsKey(destination.RegionID))
254  {
255 // m_log.DebugFormat(
256 // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
257 // s.RegionInfo.RegionName, destination.RegionHandle);
258  uint sizeX = m_scenes[destination.RegionID].RegionInfo.RegionSizeX;
259  uint sizeY = m_scenes[destination.RegionID].RegionInfo.RegionSizeY;
260 
261  // Var regions here, and the requesting simulator is in an older version.
262  // We will forbide this, because it crashes the viewers
263  if (ctx.OutboundVersion < 0.3f && (sizeX != 256 || sizeY != 256))
264  {
265  reason = "Destination is a variable-sized region, and source is an old simulator. Consider upgrading.";
266  m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Request to access this variable-sized region from older simulator was denied");
267  return false;
268 
269  }
270 
271 
272  return m_scenes[destination.RegionID].QueryAccess(agentID, agentHomeURI, viaTeleport, position, features, out reason);
273  }
274 
275  //m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess");
276  return false;
277  }
278 
279  public bool ReleaseAgent(UUID originId, UUID agentId, string uri)
280  {
281  if (m_scenes.ContainsKey(originId))
282  {
283 // m_log.DebugFormat(
284 // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
285 // s.RegionInfo.RegionName, destination.RegionHandle);
286 
287  m_scenes[originId].EntityTransferModule.AgentArrivedAtDestination(agentId);
288  return true;
289  }
290 
291  //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin);
292  return false;
293  }
294 
295  public bool CloseAgent(GridRegion destination, UUID id, string auth_token)
296  {
297  if (destination == null)
298  return false;
299 
300  if (m_scenes.ContainsKey(destination.RegionID))
301  {
302 // m_log.DebugFormat(
303 // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
304 // s.RegionInfo.RegionName, destination.RegionHandle);
305 
306  m_scenes[destination.RegionID].CloseAgent(id, false, auth_token);
307  return true;
308  }
309  //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
310  return false;
311  }
312 
317  public bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall)
318  {
319  if (destination == null)
320  return false;
321 
322  if (m_scenes.ContainsKey(destination.RegionID))
323  {
324 // m_log.DebugFormat(
325 // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
326 // s.RegionInfo.RegionName, destination.RegionHandle);
327 
328  Scene s = m_scenes[destination.RegionID];
329 
330  if (isLocalCall)
331  {
332  // We need to make a local copy of the object
333  ISceneObject sogClone = sog.CloneForNewScene();
334  sogClone.SetState(sog.GetStateSnapshot(), s);
335  return s.IncomingCreateObject(newPosition, sogClone);
336  }
337  else
338  {
339  // Use the object as it came through the wire
340  return s.IncomingCreateObject(newPosition, sog);
341  }
342  }
343 
344  return false;
345  }
346 
347  #endregion
348 
349  #region Misc
350 
351  public bool IsLocalRegion(ulong regionhandle)
352  {
353  foreach (Scene s in m_scenes.Values)
354  if (s.RegionInfo.RegionHandle == regionhandle)
355  return true;
356 
357  return false;
358  }
359 
360  public bool IsLocalRegion(UUID id)
361  {
362  return m_scenes.ContainsKey(id);
363  }
364 
365  #endregion
366  }
367 }
OpenSim.Services.Interfaces.GridRegion GridRegion
bool ReleaseAgent(UUID originId, UUID agentId, string uri)
Message from receiving region to departing region, telling it got contacted by the client...
bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List< UUID > features, EntityTransferContext ctx, out string reason)
Returns whether a propspective user is allowed to visit the region.
IScene GetScene(UUID regionId)
Retrieve the scene with the given region ID.
bool UpdateAgent(GridRegion destination, AgentData cAgentData, EntityTransferContext ctx)
Full child agent update.
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...
void Initialise(IConfigSource configSource)
This is called to initialize the region module. For shared modules, this is called exactly once...
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
bool CreateAgent(GridRegion source, GridRegion destination, AgentCircuitData aCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason)
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
Circuit data for an agent. Connection information shared between regions that accept UDP connections ...
bool CloseAgent(GridRegion destination, UUID id, string auth_token)
Close agent.
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
Replacement for ChildAgentDataUpdate. Used over RESTComms and LocalComms.
Interactive OpenSim region server
Definition: OpenSim.cs:55
bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall)
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
bool UpdateAgent(GridRegion destination, AgentPosition agentPosition)
Short child agent update, mostly for position.