opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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.Communications;
39 using OpenSim.Framework.Capabilities;
40 using OpenSim.Region.Framework.Interfaces;
41 using OpenSim.Services.Interfaces;
42 using OSD = OpenMetaverse.StructuredData.OSD;
43 using GridRegion = OpenSim.Services.Interfaces.GridRegion;
44  
45 namespace OpenSim.Region.Framework.Scenes
46 {
47 public delegate void RemoveKnownRegionsFromAvatarList(UUID avatarID, List<ulong> regionlst);
48  
49 /// <summary>
50 /// Class that Region communications runs through
51 /// </summary>
52 public class SceneCommunicationService //one instance per region
53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55  
56 protected RegionInfo m_regionInfo;
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  
73 /// <summary>
74 /// Asynchronous call to information neighbouring regions that this region is up
75 /// </summary>
76 /// <param name="region"></param>
77 /// <param name="regionhandle"></param>
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(
88 "[SCENE COMMUNICATION SERVICE]: No neighbour service provided for region {0} to inform neigbhours of status",
89 m_scene.Name);
90  
91 if (neighbour != null)
92 {
93 m_log.DebugFormat(
94 "[SCENE COMMUNICATION SERVICE]: Region {0} successfully informed neighbour {1} at {2}-{3} that it is up",
95 m_scene.Name, neighbour.RegionName, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y));
96  
97 m_scene.EventManager.TriggerOnRegionUp(neighbour);
98 }
99 else
100 {
101 m_log.WarnFormat(
102 "[SCENE COMMUNICATION SERVICE]: Region {0} failed to inform neighbour at {1}-{2} that it is up.",
103 m_scene.Name, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y));
104 }
105 }
106  
107 public void InformNeighborsThatRegionisUp(INeighbourService neighbourService, RegionInfo region)
108 {
109 //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
110  
111 List<GridRegion> neighbours
112 = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID);
113  
114 m_log.DebugFormat(
115 "[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that region {1} is up",
116 neighbours.Count, m_scene.Name);
117  
118 foreach (GridRegion n in neighbours)
119 {
120 InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync;
121 d.BeginInvoke(neighbourService, region, n.RegionHandle,
122 InformNeighborsThatRegionisUpCompleted,
123 d);
124 }
125 }
126  
127 public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, GridRegion dest);
128  
129 /// <summary>
130 /// This informs all neighboring regions about the settings of it's child agent.
131 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
132 ///
133 /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc.
134 ///
135 /// </summary>
136 private void SendChildAgentDataUpdateAsync(AgentPosition cAgentData, UUID scopeID, GridRegion dest)
137 {
138 //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName);
139 try
140 {
141 m_scene.SimulationService.UpdateAgent(dest, cAgentData);
142 }
143 catch
144 {
145 // Ignore; we did our best
146 }
147 }
148  
149 private void SendChildAgentDataUpdateCompleted(IAsyncResult iar)
150 {
151 SendChildAgentDataUpdateDelegate icon = (SendChildAgentDataUpdateDelegate) iar.AsyncState;
152 icon.EndInvoke(iar);
153 }
154  
155 public void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence)
156 {
157 // This assumes that we know what our neighbors are.
158 try
159 {
160 uint x = 0, y = 0;
161 List<string> simulatorList = new List<string>();
162 foreach (ulong regionHandle in presence.KnownRegionHandles)
163 {
164 if (regionHandle != m_regionInfo.RegionHandle)
165 {
166 // we only want to send one update to each simulator; the simulator will
167 // hand it off to the regions where a child agent exists, this does assume
168 // that the region position is cached or performance will degrade
169 Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
170 GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
171 if (dest == null)
172 continue;
173  
174 if (!simulatorList.Contains(dest.ServerURI))
175 {
176 // we havent seen this simulator before, add it to the list
177 // and send it an update
178 simulatorList.Add(dest.ServerURI);
179 // Let move this to sync. Mono definitely does not like async networking.
180 m_scene.SimulationService.UpdateAgent(dest, cAgentData);
181  
182 // Leaving this here as a reminder that we tried, and it sucks.
183 //SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
184 //d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
185 // SendChildAgentDataUpdateCompleted,
186 // d);
187 }
188 }
189 }
190 }
191 catch (InvalidOperationException)
192 {
193 // We're ignoring a collection was modified error because this data gets old and outdated fast.
194 }
195 }
196  
197 /// <summary>
198 /// Closes a child agent on a given region
199 /// </summary>
200 protected void SendCloseChildAgent(UUID agentID, ulong regionHandle, string auth_token)
201 {
202 // let's do our best, but there's not much we can do if the neighbour doesn't accept.
203  
204 //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
205 uint x = 0, y = 0;
206 Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
207  
208 GridRegion destination = m_scene.GridService.GetRegionByPosition(m_regionInfo.ScopeID, (int)x, (int)y);
209  
210 m_log.DebugFormat(
211 "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName);
212  
213 m_scene.SimulationService.CloseAgent(destination, agentID, auth_token);
214 }
215  
216 /// <summary>
217 /// Closes a child agents in a collection of regions. Does so asynchronously
218 /// so that the caller doesn't wait.
219 /// </summary>
220 /// <param name="agentID"></param>
221 /// <param name="regionslst"></param>
222 public void SendCloseChildAgentConnections(UUID agentID, string auth_code, List<ulong> regionslst)
223 {
224 foreach (ulong handle in regionslst)
225 {
226 // We must take a copy here since handle is acts like a reference when used in an iterator.
227 // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region.
228 ulong handleCopy = handle;
229 Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); });
230 }
231 }
232  
233 public List<GridRegion> RequestNamedRegions(string name, int maxNumber)
234 {
235 return m_scene.GridService.GetRegionsByName(UUID.Zero, name, maxNumber);
236 }
237 }
238 }