aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs958
1 files changed, 490 insertions, 468 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ab0d397..d5d1825 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics;
30using System.Drawing; 31using System.Drawing;
31using System.Drawing.Imaging; 32using System.Drawing.Imaging;
32using System.IO; 33using System.IO;
@@ -41,8 +42,7 @@ using OpenMetaverse.Imaging;
41using OpenSim.Framework; 42using OpenSim.Framework;
42using OpenSim.Services.Interfaces; 43using OpenSim.Services.Interfaces;
43using OpenSim.Framework.Communications; 44using OpenSim.Framework.Communications;
44using OpenSim.Framework.Communications.Cache; 45
45using OpenSim.Framework.Communications.Clients;
46using OpenSim.Framework.Console; 46using OpenSim.Framework.Console;
47using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes.Scripting; 48using OpenSim.Region.Framework.Scenes.Scripting;
@@ -141,7 +141,6 @@ namespace OpenSim.Region.Framework.Scenes
141 protected ModuleLoader m_moduleLoader; 141 protected ModuleLoader m_moduleLoader;
142 protected StorageManager m_storageManager; 142 protected StorageManager m_storageManager;
143 protected AgentCircuitManager m_authenticateHandler; 143 protected AgentCircuitManager m_authenticateHandler;
144 public CommunicationsManager CommsManager;
145 144
146 protected SceneCommunicationService m_sceneGridService; 145 protected SceneCommunicationService m_sceneGridService;
147 public bool LoginsDisabled = true; 146 public bool LoginsDisabled = true;
@@ -189,11 +188,11 @@ namespace OpenSim.Region.Framework.Scenes
189 { 188 {
190 m_AuthorizationService = RequestModuleInterface<IAuthorizationService>(); 189 m_AuthorizationService = RequestModuleInterface<IAuthorizationService>();
191 190
192 if (m_AuthorizationService == null) 191 //if (m_AuthorizationService == null)
193 { 192 //{
194 // don't throw an exception if no authorization service is set for the time being 193 // // don't throw an exception if no authorization service is set for the time being
195 m_log.InfoFormat("[SCENE]: No Authorization service is configured"); 194 // m_log.InfoFormat("[SCENE]: No Authorization service is configured");
196 } 195 //}
197 } 196 }
198 197
199 return m_AuthorizationService; 198 return m_AuthorizationService;
@@ -240,8 +239,76 @@ namespace OpenSim.Region.Framework.Scenes
240 } 239 }
241 } 240 }
242 241
242 protected ILibraryService m_LibraryService;
243
244 public ILibraryService LibraryService
245 {
246 get
247 {
248 if (m_LibraryService == null)
249 m_LibraryService = RequestModuleInterface<ILibraryService>();
250
251 return m_LibraryService;
252 }
253 }
254
255 protected ISimulationService m_simulationService;
256 public ISimulationService SimulationService
257 {
258 get
259 {
260 if (m_simulationService == null)
261 m_simulationService = RequestModuleInterface<ISimulationService>();
262 return m_simulationService;
263 }
264 }
265
266 protected IAuthenticationService m_AuthenticationService;
267 public IAuthenticationService AuthenticationService
268 {
269 get
270 {
271 if (m_AuthenticationService == null)
272 m_AuthenticationService = RequestModuleInterface<IAuthenticationService>();
273 return m_AuthenticationService;
274 }
275 }
276
277 protected IPresenceService m_PresenceService;
278 public IPresenceService PresenceService
279 {
280 get
281 {
282 if (m_PresenceService == null)
283 m_PresenceService = RequestModuleInterface<IPresenceService>();
284 return m_PresenceService;
285 }
286 }
287 protected IUserAccountService m_UserAccountService;
288 public IUserAccountService UserAccountService
289 {
290 get
291 {
292 if (m_UserAccountService == null)
293 m_UserAccountService = RequestModuleInterface<IUserAccountService>();
294 return m_UserAccountService;
295 }
296 }
297
298 protected OpenSim.Services.Interfaces.IAvatarService m_AvatarService;
299 public OpenSim.Services.Interfaces.IAvatarService AvatarService
300 {
301 get
302 {
303 if (m_AvatarService == null)
304 m_AvatarService = RequestModuleInterface<IAvatarService>();
305 return m_AvatarService;
306 }
307 }
308
243 protected IXMLRPC m_xmlrpcModule; 309 protected IXMLRPC m_xmlrpcModule;
244 protected IWorldComm m_worldCommModule; 310 protected IWorldComm m_worldCommModule;
311 public IAttachmentsModule AttachmentsModule { get; set; }
245 protected IAvatarFactory m_AvatarFactory; 312 protected IAvatarFactory m_AvatarFactory;
246 public IAvatarFactory AvatarFactory 313 public IAvatarFactory AvatarFactory
247 { 314 {
@@ -249,10 +316,8 @@ namespace OpenSim.Region.Framework.Scenes
249 } 316 }
250 protected IConfigSource m_config; 317 protected IConfigSource m_config;
251 protected IRegionSerialiserModule m_serialiser; 318 protected IRegionSerialiserModule m_serialiser;
252 protected IInterregionCommsOut m_interregionCommsOut;
253 protected IInterregionCommsIn m_interregionCommsIn;
254 protected IDialogModule m_dialogModule; 319 protected IDialogModule m_dialogModule;
255 protected ITeleportModule m_teleportModule; 320 protected IEntityTransferModule m_teleportModule;
256 321
257 protected ICapabilitiesModule m_capsModule; 322 protected ICapabilitiesModule m_capsModule;
258 public ICapabilitiesModule CapsModule 323 public ICapabilitiesModule CapsModule
@@ -483,7 +548,7 @@ namespace OpenSim.Region.Framework.Scenes
483 #region Constructors 548 #region Constructors
484 549
485 public Scene(RegionInfo regInfo, AgentCircuitManager authen, 550 public Scene(RegionInfo regInfo, AgentCircuitManager authen,
486 CommunicationsManager commsMan, SceneCommunicationService sceneGridService, 551 SceneCommunicationService sceneGridService,
487 StorageManager storeManager, 552 StorageManager storeManager,
488 ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim, 553 ModuleLoader moduleLoader, bool dumpAssetsToFile, bool physicalPrim,
489 bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion) 554 bool SeeIntoRegionFromNeighbor, IConfigSource config, string simulatorVersion)
@@ -519,7 +584,6 @@ namespace OpenSim.Region.Framework.Scenes
519 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4); 584 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4);
520 m_moduleLoader = moduleLoader; 585 m_moduleLoader = moduleLoader;
521 m_authenticateHandler = authen; 586 m_authenticateHandler = authen;
522 CommsManager = commsMan;
523 m_sceneGridService = sceneGridService; 587 m_sceneGridService = sceneGridService;
524 m_storageManager = storeManager; 588 m_storageManager = storeManager;
525 m_regInfo = regInfo; 589 m_regInfo = regInfo;
@@ -778,6 +842,36 @@ namespace OpenSim.Region.Framework.Scenes
778 return m_simulatorVersion; 842 return m_simulatorVersion;
779 } 843 }
780 844
845 public string[] GetUserNames(UUID uuid)
846 {
847 string[] returnstring = new string[0];
848
849 UserAccount account = UserAccountService.GetUserAccount(RegionInfo.ScopeID, uuid);
850
851 if (account != null)
852 {
853 returnstring = new string[2];
854 returnstring[0] = account.FirstName;
855 returnstring[1] = account.LastName;
856 }
857
858 return returnstring;
859 }
860
861 public string GetUserName(UUID uuid)
862 {
863 string[] names = GetUserNames(uuid);
864 if (names.Length == 2)
865 {
866 string firstname = names[0];
867 string lastname = names[1];
868
869 return firstname + " " + lastname;
870
871 }
872 return "(hippos)";
873 }
874
781 /// <summary> 875 /// <summary>
782 /// Another region is up. 876 /// Another region is up.
783 /// 877 ///
@@ -811,7 +905,7 @@ namespace OpenSim.Region.Framework.Scenes
811 regInfo.RegionName = otherRegion.RegionName; 905 regInfo.RegionName = otherRegion.RegionName;
812 regInfo.ScopeID = otherRegion.ScopeID; 906 regInfo.ScopeID = otherRegion.ScopeID;
813 regInfo.ExternalHostName = otherRegion.ExternalHostName; 907 regInfo.ExternalHostName = otherRegion.ExternalHostName;
814 908 GridRegion r = new GridRegion(regInfo);
815 try 909 try
816 { 910 {
817 ForEachScenePresence(delegate(ScenePresence agent) 911 ForEachScenePresence(delegate(ScenePresence agent)
@@ -825,7 +919,8 @@ namespace OpenSim.Region.Framework.Scenes
825 List<ulong> old = new List<ulong>(); 919 List<ulong> old = new List<ulong>();
826 old.Add(otherRegion.RegionHandle); 920 old.Add(otherRegion.RegionHandle);
827 agent.DropOldNeighbours(old); 921 agent.DropOldNeighbours(old);
828 InformClientOfNeighbor(agent, regInfo); 922 if (m_teleportModule != null)
923 m_teleportModule.EnableChildAgent(agent, r);
829 } 924 }
830 } 925 }
831 ); 926 );
@@ -985,6 +1080,7 @@ namespace OpenSim.Region.Framework.Scenes
985 { 1080 {
986 foreach (RegionInfo region in m_regionRestartNotifyList) 1081 foreach (RegionInfo region in m_regionRestartNotifyList)
987 { 1082 {
1083 GridRegion r = new GridRegion(region);
988 try 1084 try
989 { 1085 {
990 ForEachScenePresence(delegate(ScenePresence agent) 1086 ForEachScenePresence(delegate(ScenePresence agent)
@@ -992,9 +1088,8 @@ namespace OpenSim.Region.Framework.Scenes
992 // If agent is a root agent. 1088 // If agent is a root agent.
993 if (!agent.IsChildAgent) 1089 if (!agent.IsChildAgent)
994 { 1090 {
995 //agent.ControllingClient.new 1091 if (m_teleportModule != null)
996 //this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo()); 1092 m_teleportModule.EnableChildAgent(agent, r);
997 InformClientOfNeighbor(agent, region);
998 } 1093 }
999 } 1094 }
1000 ); 1095 );
@@ -1053,10 +1148,7 @@ namespace OpenSim.Region.Framework.Scenes
1053 1148
1054 public int GetInaccurateNeighborCount() 1149 public int GetInaccurateNeighborCount()
1055 { 1150 {
1056 lock (m_neighbours) 1151 return m_neighbours.Count;
1057 {
1058 return m_neighbours.Count;
1059 }
1060 } 1152 }
1061 1153
1062 // This is the method that shuts down the scene. 1154 // This is the method that shuts down the scene.
@@ -1136,12 +1228,11 @@ namespace OpenSim.Region.Framework.Scenes
1136 m_worldCommModule = RequestModuleInterface<IWorldComm>(); 1228 m_worldCommModule = RequestModuleInterface<IWorldComm>();
1137 XferManager = RequestModuleInterface<IXfer>(); 1229 XferManager = RequestModuleInterface<IXfer>();
1138 m_AvatarFactory = RequestModuleInterface<IAvatarFactory>(); 1230 m_AvatarFactory = RequestModuleInterface<IAvatarFactory>();
1231 AttachmentsModule = RequestModuleInterface<IAttachmentsModule>();
1139 m_serialiser = RequestModuleInterface<IRegionSerialiserModule>(); 1232 m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
1140 m_interregionCommsOut = RequestModuleInterface<IInterregionCommsOut>();
1141 m_interregionCommsIn = RequestModuleInterface<IInterregionCommsIn>();
1142 m_dialogModule = RequestModuleInterface<IDialogModule>(); 1233 m_dialogModule = RequestModuleInterface<IDialogModule>();
1143 m_capsModule = RequestModuleInterface<ICapabilitiesModule>(); 1234 m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
1144 m_teleportModule = RequestModuleInterface<ITeleportModule>(); 1235 m_teleportModule = RequestModuleInterface<IEntityTransferModule>();
1145 } 1236 }
1146 1237
1147 #endregion 1238 #endregion
@@ -1591,7 +1682,9 @@ namespace OpenSim.Region.Framework.Scenes
1591 GridRegion region = new GridRegion(RegionInfo); 1682 GridRegion region = new GridRegion(RegionInfo);
1592 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); 1683 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region);
1593 if (error != String.Empty) 1684 if (error != String.Empty)
1685 {
1594 throw new Exception(error); 1686 throw new Exception(error);
1687 }
1595 1688
1596 m_sceneGridService.SetScene(this); 1689 m_sceneGridService.SetScene(this);
1597 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo); 1690 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
@@ -1840,14 +1933,22 @@ namespace OpenSim.Region.Framework.Scenes
1840 //m_log.DebugFormat( 1933 //m_log.DebugFormat(
1841 // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName); 1934 // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName);
1842 1935
1936 SceneObjectGroup sceneObject = null;
1937
1843 // If an entity creator has been registered for this prim type then use that 1938 // If an entity creator has been registered for this prim type then use that
1844 if (m_entityCreators.ContainsKey((PCode)shape.PCode)) 1939 if (m_entityCreators.ContainsKey((PCode)shape.PCode))
1845 return m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape); 1940 {
1941 sceneObject = m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape);
1942 }
1943 else
1944 {
1945 // Otherwise, use this default creation code;
1946 sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
1947 AddNewSceneObject(sceneObject, true);
1948 sceneObject.SetGroup(groupID, null);
1949 }
1846 1950
1847 // Otherwise, use this default creation code; 1951 sceneObject.ScheduleGroupForFullUpdate();
1848 SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
1849 AddNewSceneObject(sceneObject, true);
1850 sceneObject.SetGroup(groupID, null);
1851 1952
1852 return sceneObject; 1953 return sceneObject;
1853 } 1954 }
@@ -1875,7 +1976,7 @@ namespace OpenSim.Region.Framework.Scenes
1875 } 1976 }
1876 1977
1877 /// <summary> 1978 /// <summary>
1878 /// Add a newly created object to the scene 1979 /// Add a newly created object to the scene. Updates are also sent to viewers.
1879 /// </summary> 1980 /// </summary>
1880 /// <param name="sceneObject"></param> 1981 /// <param name="sceneObject"></param>
1881 /// <param name="attachToBackup"> 1982 /// <param name="attachToBackup">
@@ -1884,8 +1985,25 @@ namespace OpenSim.Region.Framework.Scenes
1884 /// </param> 1985 /// </param>
1885 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) 1986 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
1886 { 1987 {
1887 return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup); 1988 return AddNewSceneObject(sceneObject, attachToBackup, true);
1888 } 1989 }
1990
1991 /// <summary>
1992 /// Add a newly created object to the scene
1993 /// </summary>
1994 /// <param name="sceneObject"></param>
1995 /// <param name="attachToBackup">
1996 /// If true, the object is made persistent into the scene.
1997 /// If false, the object will not persist over server restarts
1998 /// </param>
1999 /// <param name="sendClientUpdates">
2000 /// If true, updates for the new scene object are sent to all viewers in range.
2001 /// If false, it is left to the caller to schedule the update
2002 /// </param>
2003 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
2004 {
2005 return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates);
2006 }
1889 2007
1890 /// <summary> 2008 /// <summary>
1891 /// Delete every object from the scene 2009 /// Delete every object from the scene
@@ -1978,7 +2096,6 @@ namespace OpenSim.Region.Framework.Scenes
1978 /// Move the given scene object into a new region depending on which region its absolute position has moved 2096 /// Move the given scene object into a new region depending on which region its absolute position has moved
1979 /// into. 2097 /// into.
1980 /// 2098 ///
1981 /// This method locates the new region handle and offsets the prim position for the new region
1982 /// </summary> 2099 /// </summary>
1983 /// <param name="attemptedPosition">the attempted out of region position of the scene object</param> 2100 /// <param name="attemptedPosition">the attempted out of region position of the scene object</param>
1984 /// <param name="grp">the scene object that we're crossing</param> 2101 /// <param name="grp">the scene object that we're crossing</param>
@@ -2020,191 +2137,8 @@ namespace OpenSim.Region.Framework.Scenes
2020 return; 2137 return;
2021 } 2138 }
2022 2139
2023 int thisx = (int)RegionInfo.RegionLocX; 2140 if (m_teleportModule != null)
2024 int thisy = (int)RegionInfo.RegionLocY; 2141 m_teleportModule.Cross(grp, attemptedPosition, silent);
2025 Vector3 EastCross = new Vector3(0.1f,0,0);
2026 Vector3 WestCross = new Vector3(-0.1f, 0, 0);
2027 Vector3 NorthCross = new Vector3(0, 0.1f, 0);
2028 Vector3 SouthCross = new Vector3(0, -0.1f, 0);
2029
2030
2031 // use this if no borders were crossed!
2032 ulong newRegionHandle
2033 = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize),
2034 (uint)((thisy) * Constants.RegionSize));
2035
2036 Vector3 pos = attemptedPosition;
2037
2038 int changeX = 1;
2039 int changeY = 1;
2040
2041 if (TestBorderCross(attemptedPosition + WestCross, Cardinals.W))
2042 {
2043 if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2044 {
2045
2046 Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2047
2048 if (crossedBorderx.BorderLine.Z > 0)
2049 {
2050 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2051 changeX = (int)(crossedBorderx.BorderLine.Z /(int) Constants.RegionSize);
2052 }
2053 else
2054 pos.X = ((pos.X + Constants.RegionSize));
2055
2056 Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2057 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2058
2059 if (crossedBordery.BorderLine.Z > 0)
2060 {
2061 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2062 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2063 }
2064 else
2065 pos.Y = ((pos.Y + Constants.RegionSize));
2066
2067
2068
2069 newRegionHandle
2070 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
2071 (uint)((thisy - changeY) * Constants.RegionSize));
2072 // x - 1
2073 // y - 1
2074 }
2075 else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2076 {
2077 Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2078
2079 if (crossedBorderx.BorderLine.Z > 0)
2080 {
2081 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2082 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2083 }
2084 else
2085 pos.X = ((pos.X + Constants.RegionSize));
2086
2087
2088 Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2089 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2090
2091 try
2092 {
2093 if (crossedBordery.BorderLine.Z > 0)
2094 {
2095 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2096 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2097 }
2098 else
2099 pos.Y = ((pos.Y + Constants.RegionSize));
2100
2101 newRegionHandle
2102 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
2103 (uint)((thisy + changeY) * Constants.RegionSize));
2104 // x - 1
2105 // y + 1
2106 }
2107 catch (Exception ex)
2108 {
2109 }
2110 }
2111 else
2112 {
2113 Border crossedBorderx = GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W);
2114
2115 if (crossedBorderx.BorderLine.Z > 0)
2116 {
2117 pos.X = ((pos.X + crossedBorderx.BorderLine.Z));
2118 changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize);
2119 }
2120 else
2121 pos.X = ((pos.X + Constants.RegionSize));
2122
2123 newRegionHandle
2124 = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize),
2125 (uint) (thisy*Constants.RegionSize));
2126 // x - 1
2127 }
2128 }
2129 else if (TestBorderCross(attemptedPosition + EastCross, Cardinals.E))
2130 {
2131 if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2132 {
2133
2134 pos.X = ((pos.X - Constants.RegionSize));
2135 Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2136 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2137
2138 if (crossedBordery.BorderLine.Z > 0)
2139 {
2140 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2141 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2142 }
2143 else
2144 pos.Y = ((pos.Y + Constants.RegionSize));
2145
2146
2147 newRegionHandle
2148 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2149 (uint)((thisy - changeY) * Constants.RegionSize));
2150 // x + 1
2151 // y - 1
2152 }
2153 else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2154 {
2155 pos.X = ((pos.X - Constants.RegionSize));
2156 pos.Y = ((pos.Y - Constants.RegionSize));
2157 newRegionHandle
2158 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2159 (uint)((thisy + changeY) * Constants.RegionSize));
2160 // x + 1
2161 // y + 1
2162 }
2163 else
2164 {
2165 pos.X = ((pos.X - Constants.RegionSize));
2166 newRegionHandle
2167 = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize),
2168 (uint) (thisy*Constants.RegionSize));
2169 // x + 1
2170 }
2171 }
2172 else if (TestBorderCross(attemptedPosition + SouthCross, Cardinals.S))
2173 {
2174 Border crossedBordery = GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S);
2175 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
2176
2177 if (crossedBordery.BorderLine.Z > 0)
2178 {
2179 pos.Y = ((pos.Y + crossedBordery.BorderLine.Z));
2180 changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize);
2181 }
2182 else
2183 pos.Y = ((pos.Y + Constants.RegionSize));
2184
2185 newRegionHandle
2186 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize));
2187 // y - 1
2188 }
2189 else if (TestBorderCross(attemptedPosition + NorthCross, Cardinals.N))
2190 {
2191
2192 pos.Y = ((pos.Y - Constants.RegionSize));
2193 newRegionHandle
2194 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize));
2195 // y + 1
2196 }
2197
2198 // Offset the positions for the new region across the border
2199 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2200 grp.OffsetForNewRegion(pos);
2201
2202 // If we fail to cross the border, then reset the position of the scene object on that border.
2203 if (!CrossPrimGroupIntoNewRegion(newRegionHandle, grp, silent))
2204 {
2205 grp.OffsetForNewRegion(oldGroupPosition);
2206 grp.ScheduleGroupForFullUpdate();
2207 }
2208 } 2142 }
2209 2143
2210 public Border GetCrossedBorder(Vector3 position, Cardinals gridline) 2144 public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
@@ -2388,75 +2322,6 @@ namespace OpenSim.Region.Framework.Scenes
2388 2322
2389 2323
2390 /// <summary> 2324 /// <summary>
2391 /// Move the given scene object into a new region
2392 /// </summary>
2393 /// <param name="newRegionHandle"></param>
2394 /// <param name="grp">Scene Object Group that we're crossing</param>
2395 /// <returns>
2396 /// true if the crossing itself was successful, false on failure
2397 /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
2398 /// </returns>
2399 public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp, bool silent)
2400 {
2401 //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
2402
2403 bool successYN = false;
2404 grp.RootPart.UpdateFlag = 0;
2405 //int primcrossingXMLmethod = 0;
2406
2407 if (newRegionHandle != 0)
2408 {
2409 //string objectState = grp.GetStateSnapshot();
2410
2411 //successYN
2412 // = m_sceneGridService.PrimCrossToNeighboringRegion(
2413 // newRegionHandle, grp.UUID, m_serialiser.SaveGroupToXml2(grp), primcrossingXMLmethod);
2414 //if (successYN && (objectState != "") && m_allowScriptCrossings)
2415 //{
2416 // successYN = m_sceneGridService.PrimCrossToNeighboringRegion(
2417 // newRegionHandle, grp.UUID, objectState, 100);
2418 //}
2419
2420 // And the new channel...
2421 if (m_interregionCommsOut != null)
2422 successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true);
2423
2424 if (successYN)
2425 {
2426 // We remove the object here
2427 try
2428 {
2429 DeleteSceneObject(grp, silent);
2430 }
2431 catch (Exception e)
2432 {
2433 m_log.ErrorFormat(
2434 "[INTERREGION]: Exception deleting the old object left behind on a border crossing for {0}, {1}",
2435 grp, e);
2436 }
2437 }
2438 else
2439 {
2440 if (!grp.IsDeleted)
2441 {
2442 if (grp.RootPart.PhysActor != null)
2443 {
2444 grp.RootPart.PhysActor.CrossingFailure();
2445 }
2446 }
2447
2448 m_log.ErrorFormat("[INTERREGION]: Prim crossing failed for {0}", grp);
2449 }
2450 }
2451 else
2452 {
2453 m_log.Error("[INTERREGION]: region handle was unexpectedly 0 in Scene.CrossPrimGroupIntoNewRegion()");
2454 }
2455
2456 return successYN;
2457 }
2458
2459 /// <summary>
2460 /// Called when objects or attachments cross the border between regions. 2325 /// Called when objects or attachments cross the border between regions.
2461 /// </summary> 2326 /// </summary>
2462 /// <param name="sog"></param> 2327 /// <param name="sog"></param>
@@ -2528,6 +2393,9 @@ namespace OpenSim.Region.Framework.Scenes
2528 2393
2529 return false; 2394 return false;
2530 } 2395 }
2396
2397 sceneObject.SetScene(this);
2398
2531 // Force allocation of new LocalId 2399 // Force allocation of new LocalId
2532 // 2400 //
2533 foreach (SceneObjectPart p in sceneObject.Children.Values) 2401 foreach (SceneObjectPart p in sceneObject.Children.Values)
@@ -2564,9 +2432,11 @@ namespace OpenSim.Region.Framework.Scenes
2564 //grp.SetFromAssetID(grp.RootPart.LastOwnerID); 2432 //grp.SetFromAssetID(grp.RootPart.LastOwnerID);
2565 m_log.DebugFormat( 2433 m_log.DebugFormat(
2566 "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); 2434 "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
2435
2436 if (AttachmentsModule != null)
2437 AttachmentsModule.AttachObject(
2438 sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false);
2567 2439
2568 AttachObject(
2569 sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false);
2570 RootPrim.RemFlag(PrimFlags.TemporaryOnRez); 2440 RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
2571 grp.SendGroupFullUpdate(); 2441 grp.SendGroupFullUpdate();
2572 } 2442 }
@@ -2606,6 +2476,8 @@ namespace OpenSim.Region.Framework.Scenes
2606 /// <param name="client"></param> 2476 /// <param name="client"></param>
2607 public override void AddNewClient(IClientAPI client) 2477 public override void AddNewClient(IClientAPI client)
2608 { 2478 {
2479 bool vialogin = false;
2480
2609 m_clientManager.Add(client); 2481 m_clientManager.Add(client);
2610 2482
2611 CheckHeartbeat(); 2483 CheckHeartbeat();
@@ -2640,23 +2512,48 @@ namespace OpenSim.Region.Framework.Scenes
2640 { 2512 {
2641 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2513 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2642 2514
2643 m_log.Debug("[Scene] Adding new agent " + client.Name + " to scene " + RegionInfo.RegionName); 2515 // Do the verification here
2644 /* 2516 System.Net.EndPoint ep = client.GetClientEP();
2645 string logMsg = string.Format("[SCENE]: Adding new {0} agent for {1} in {2}", 2517 if (aCircuit != null)
2646 ((aCircuit.child == true) ? "child" : "root"), client.Name, 2518 {
2647 RegionInfo.RegionName); 2519 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0)
2648 2520 {
2649 m_log.Debug(logMsg); 2521 m_log.DebugFormat("[Scene]: Incoming client {0} {1} in region {2} via Login", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName);
2650 */ 2522 vialogin = true;
2523 IUserAgentVerificationModule userVerification = RequestModuleInterface<IUserAgentVerificationModule>();
2524 if (userVerification != null && ep != null)
2525 {
2526 if (!userVerification.VerifyClient(aCircuit, ep.ToString()))
2527 {
2528 // uh-oh, this is fishy
2529 m_log.WarnFormat("[Scene]: Agent {0} with session {1} connecting with unidentified end point {2}. Refusing service.",
2530 client.AgentId, client.SessionId, ep.ToString());
2531 try
2532 {
2533 client.Close();
2534 }
2535 catch (Exception e)
2536 {
2537 m_log.DebugFormat("[Scene]: Exception while closing aborted client: {0}", e.StackTrace);
2538 }
2539 return;
2540 }
2541 else
2542 m_log.DebugFormat("[Scene]: User Client Verification for {0} {1} returned true", aCircuit.firstname, aCircuit.lastname);
2543 }
2544 }
2545 }
2651 2546
2652 CommsManager.UserProfileCacheService.AddNewUser(client.AgentId); 2547 m_log.Debug("[Scene] Adding new agent " + client.Name + " to scene " + RegionInfo.RegionName);
2653 2548
2654 ScenePresence sp = CreateAndAddScenePresence(client); 2549 ScenePresence sp = CreateAndAddScenePresence(client);
2550 if (aCircuit != null)
2551 sp.Appearance = aCircuit.Appearance;
2655 2552
2656 // HERE!!! Do the initial attachments right here 2553 // HERE!!! Do the initial attachments right here
2657 // first agent upon login is a root agent by design. 2554 // first agent upon login is a root agent by design.
2658 // All other AddNewClient calls find aCircuit.child to be true 2555 // All other AddNewClient calls find aCircuit.child to be true
2659 if (aCircuit == null || aCircuit.child == false) 2556 if (aCircuit == null || (aCircuit != null && aCircuit.child == false))
2660 { 2557 {
2661 sp.IsChildAgent = false; 2558 sp.IsChildAgent = false;
2662 Util.FireAndForget(delegate(object o) { sp.RezAttachments(); }); 2559 Util.FireAndForget(delegate(object o) { sp.RezAttachments(); });
@@ -2665,6 +2562,8 @@ namespace OpenSim.Region.Framework.Scenes
2665 2562
2666 m_LastLogin = Util.EnvironmentTickCount(); 2563 m_LastLogin = Util.EnvironmentTickCount();
2667 EventManager.TriggerOnNewClient(client); 2564 EventManager.TriggerOnNewClient(client);
2565 if (vialogin)
2566 EventManager.TriggerOnClientLogin(client);
2668 } 2567 }
2669 2568
2670 2569
@@ -2772,17 +2671,18 @@ namespace OpenSim.Region.Framework.Scenes
2772 public virtual void SubscribeToClientAttachmentEvents(IClientAPI client) 2671 public virtual void SubscribeToClientAttachmentEvents(IClientAPI client)
2773 { 2672 {
2774 client.OnRezSingleAttachmentFromInv += RezSingleAttachment; 2673 client.OnRezSingleAttachmentFromInv += RezSingleAttachment;
2775 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; 2674 client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments;
2776 client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv;
2777 client.OnObjectAttach += m_sceneGraph.AttachObject; 2675 client.OnObjectAttach += m_sceneGraph.AttachObject;
2778 client.OnObjectDetach += m_sceneGraph.DetachObject; 2676 client.OnObjectDetach += m_sceneGraph.DetachObject;
2677
2678 if (AttachmentsModule != null)
2679 client.OnDetachAttachmentIntoInv += AttachmentsModule.ShowDetachInUserInventory;
2779 } 2680 }
2780 2681
2781 public virtual void SubscribeToClientTeleportEvents(IClientAPI client) 2682 public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
2782 { 2683 {
2783 client.OnTeleportLocationRequest += RequestTeleportLocation; 2684 client.OnTeleportLocationRequest += RequestTeleportLocation;
2784 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 2685 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
2785 client.OnTeleportHomeRequest += TeleportClientHome;
2786 } 2686 }
2787 2687
2788 public virtual void SubscribeToClientScriptEvents(IClientAPI client) 2688 public virtual void SubscribeToClientScriptEvents(IClientAPI client)
@@ -2802,7 +2702,7 @@ namespace OpenSim.Region.Framework.Scenes
2802 2702
2803 public virtual void SubscribeToClientGridEvents(IClientAPI client) 2703 public virtual void SubscribeToClientGridEvents(IClientAPI client)
2804 { 2704 {
2805 client.OnNameFromUUIDRequest += CommsManager.HandleUUIDNameRequest; 2705 client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
2806 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; 2706 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
2807 client.OnAvatarPickerRequest += ProcessAvatarPickerRequest; 2707 client.OnAvatarPickerRequest += ProcessAvatarPickerRequest;
2808 client.OnSetStartLocationRequest += SetHomeRezPoint; 2708 client.OnSetStartLocationRequest += SetHomeRezPoint;
@@ -2823,8 +2723,7 @@ namespace OpenSim.Region.Framework.Scenes
2823 } 2723 }
2824 2724
2825 protected virtual void UnsubscribeToClientEvents(IClientAPI client) 2725 protected virtual void UnsubscribeToClientEvents(IClientAPI client)
2826 { 2726 {
2827
2828 } 2727 }
2829 2728
2830 /// <summary> 2729 /// <summary>
@@ -2846,7 +2745,6 @@ namespace OpenSim.Region.Framework.Scenes
2846 2745
2847 UnSubscribeToClientNetworkEvents(client); 2746 UnSubscribeToClientNetworkEvents(client);
2848 2747
2849
2850 // EventManager.TriggerOnNewClient(client); 2748 // EventManager.TriggerOnNewClient(client);
2851 } 2749 }
2852 2750
@@ -2926,19 +2824,21 @@ namespace OpenSim.Region.Framework.Scenes
2926 } 2824 }
2927 2825
2928 public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client) 2826 public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client)
2929 { 2827 {
2930 client.OnRezSingleAttachmentFromInv -= RezSingleAttachment;
2931 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments; 2828 client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments;
2932 client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv; 2829 client.OnRezSingleAttachmentFromInv -= RezSingleAttachment;
2933 client.OnObjectAttach -= m_sceneGraph.AttachObject; 2830 client.OnObjectAttach -= m_sceneGraph.AttachObject;
2934 client.OnObjectDetach -= m_sceneGraph.DetachObject; 2831 client.OnObjectDetach -= m_sceneGraph.DetachObject;
2832
2833 if (AttachmentsModule != null)
2834 client.OnDetachAttachmentIntoInv -= AttachmentsModule.ShowDetachInUserInventory;
2935 } 2835 }
2936 2836
2937 public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client) 2837 public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
2938 { 2838 {
2939 client.OnTeleportLocationRequest -= RequestTeleportLocation; 2839 client.OnTeleportLocationRequest -= RequestTeleportLocation;
2940 client.OnTeleportLandmarkRequest -= RequestTeleportLandmark; 2840 client.OnTeleportLandmarkRequest -= RequestTeleportLandmark;
2941 client.OnTeleportHomeRequest -= TeleportClientHome; 2841 //client.OnTeleportHomeRequest -= TeleportClientHome;
2942 } 2842 }
2943 2843
2944 public virtual void UnSubscribeToClientScriptEvents(IClientAPI client) 2844 public virtual void UnSubscribeToClientScriptEvents(IClientAPI client)
@@ -2958,7 +2858,7 @@ namespace OpenSim.Region.Framework.Scenes
2958 2858
2959 public virtual void UnSubscribeToClientGridEvents(IClientAPI client) 2859 public virtual void UnSubscribeToClientGridEvents(IClientAPI client)
2960 { 2860 {
2961 client.OnNameFromUUIDRequest -= CommsManager.HandleUUIDNameRequest; 2861 client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
2962 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; 2862 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
2963 client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest; 2863 client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest;
2964 client.OnSetStartLocationRequest -= SetHomeRezPoint; 2864 client.OnSetStartLocationRequest -= SetHomeRezPoint;
@@ -2985,30 +2885,12 @@ namespace OpenSim.Region.Framework.Scenes
2985 /// <param name="client">The IClientAPI for the client</param> 2885 /// <param name="client">The IClientAPI for the client</param>
2986 public virtual void TeleportClientHome(UUID agentId, IClientAPI client) 2886 public virtual void TeleportClientHome(UUID agentId, IClientAPI client)
2987 { 2887 {
2988 UserProfileData UserProfile = CommsManager.UserService.GetUserProfile(agentId); 2888 if (m_teleportModule != null)
2989 if (UserProfile != null) 2889 m_teleportModule.TeleportHome(agentId, client);
2890 else
2990 { 2891 {
2991 GridRegion regionInfo = GridService.GetRegionByUUID(UUID.Zero, UserProfile.HomeRegionID); 2892 m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active");
2992 if (regionInfo == null) 2893 client.SendTeleportFailed("Unable to perform teleports on this simulator.");
2993 {
2994 uint x = 0, y = 0;
2995 Utils.LongToUInts(UserProfile.HomeRegion, out x, out y);
2996 regionInfo = GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
2997 if (regionInfo != null) // home region can be away temporarily, too
2998 {
2999 UserProfile.HomeRegionID = regionInfo.RegionID;
3000 CommsManager.UserService.UpdateUserProfile(UserProfile);
3001 }
3002 }
3003 if (regionInfo == null)
3004 {
3005 // can't find the Home region: Tell viewer and abort
3006 client.SendTeleportFailed("Your home-region could not be found.");
3007 return;
3008 }
3009 RequestTeleportLocation(
3010 client, regionInfo.RegionHandle, UserProfile.HomeLocation, UserProfile.HomeLookAt,
3011 (uint)(TPFlags.SetLastToTarget | TPFlags.ViaHome));
3012 } 2894 }
3013 } 2895 }
3014 2896
@@ -3099,7 +2981,7 @@ namespace OpenSim.Region.Framework.Scenes
3099 } 2981 }
3100 2982
3101 /// <summary> 2983 /// <summary>
3102 /// Sets the Home Point. The GridService uses this to know where to put a user when they log-in 2984 /// Sets the Home Point. The LoginService uses this to know where to put a user when they log-in
3103 /// </summary> 2985 /// </summary>
3104 /// <param name="remoteClient"></param> 2986 /// <param name="remoteClient"></param>
3105 /// <param name="regionHandle"></param> 2987 /// <param name="regionHandle"></param>
@@ -3108,27 +2990,11 @@ namespace OpenSim.Region.Framework.Scenes
3108 /// <param name="flags"></param> 2990 /// <param name="flags"></param>
3109 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) 2991 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3110 { 2992 {
3111 UserProfileData UserProfile = CommsManager.UserService.GetUserProfile(remoteClient.AgentId); 2993 if (PresenceService.SetHomeLocation(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3112 if (UserProfile != null)
3113 {
3114 // I know I'm ignoring the regionHandle provided by the teleport location request.
3115 // reusing the TeleportLocationRequest delegate, so regionHandle isn't valid
3116 UserProfile.HomeRegionID = RegionInfo.RegionID;
3117 // TODO: The next line can be removed, as soon as only homeRegionID based UserServers are around.
3118 // TODO: The HomeRegion property can be removed then, too
3119 UserProfile.HomeRegion = RegionInfo.RegionHandle;
3120
3121 UserProfile.HomeLocation = position;
3122 UserProfile.HomeLookAt = lookAt;
3123 CommsManager.UserService.UpdateUserProfile(UserProfile);
3124
3125 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. 2994 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3126 m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); 2995 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
3127 }
3128 else 2996 else
3129 {
3130 m_dialogModule.SendAlertToUser(remoteClient, "Set Home request Failed."); 2997 m_dialogModule.SendAlertToUser(remoteClient, "Set Home request Failed.");
3131 }
3132 } 2998 }
3133 2999
3134 /// <summary> 3000 /// <summary>
@@ -3201,14 +3067,12 @@ namespace OpenSim.Region.Framework.Scenes
3201 m_sceneGraph.removeUserCount(!childagentYN); 3067 m_sceneGraph.removeUserCount(!childagentYN);
3202 CapsModule.RemoveCapsHandler(agentID); 3068 CapsModule.RemoveCapsHandler(agentID);
3203 3069
3204 if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) 3070 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3205 { 3071 // this method is doing is HORRIBLE!!!
3206 CommsManager.UserProfileCacheService.RemoveUser(agentID); 3072 avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3207 }
3208 3073
3209 if (!avatar.IsChildAgent) 3074 if (!avatar.IsChildAgent)
3210 { 3075 {
3211 m_sceneGridService.LogOffUser(agentID, RegionInfo.RegionID, RegionInfo.RegionHandle, avatar.AbsolutePosition, avatar.Lookat);
3212 //List<ulong> childknownRegions = new List<ulong>(); 3076 //List<ulong> childknownRegions = new List<ulong>();
3213 //List<ulong> ckn = avatar.KnownChildRegionHandles; 3077 //List<ulong> ckn = avatar.KnownChildRegionHandles;
3214 //for (int i = 0; i < ckn.Count; i++) 3078 //for (int i = 0; i < ckn.Count; i++)
@@ -3263,12 +3127,6 @@ namespace OpenSim.Region.Framework.Scenes
3263 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); 3127 m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString());
3264 } 3128 }
3265 3129
3266 // Remove client agent from profile, so new logins will work
3267 if (!childagentYN)
3268 {
3269 m_sceneGridService.ClearUserAgent(agentID);
3270 }
3271
3272 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); 3130 m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode);
3273 3131
3274 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 3132 //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false));
@@ -3341,15 +3199,6 @@ namespace OpenSim.Region.Framework.Scenes
3341 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; 3199 m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid;
3342 m_sceneGridService.KiPrimitive += SendKillObject; 3200 m_sceneGridService.KiPrimitive += SendKillObject;
3343 m_sceneGridService.OnGetLandData += GetLandData; 3201 m_sceneGridService.OnGetLandData += GetLandData;
3344
3345 if (m_interregionCommsIn != null)
3346 {
3347 m_log.Debug("[SCENE]: Registering with InterregionCommsIn");
3348 m_interregionCommsIn.OnChildAgentUpdate += IncomingChildAgentDataUpdate;
3349 }
3350 else
3351 m_log.Debug("[SCENE]: Unable to register with InterregionCommsIn");
3352
3353 } 3202 }
3354 3203
3355 /// <summary> 3204 /// <summary>
@@ -3367,9 +3216,6 @@ namespace OpenSim.Region.Framework.Scenes
3367 m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent; 3216 m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent;
3368 m_sceneGridService.OnGetLandData -= GetLandData; 3217 m_sceneGridService.OnGetLandData -= GetLandData;
3369 3218
3370 if (m_interregionCommsIn != null)
3371 m_interregionCommsIn.OnChildAgentUpdate -= IncomingChildAgentDataUpdate;
3372
3373 // this does nothing; should be removed 3219 // this does nothing; should be removed
3374 m_sceneGridService.Close(); 3220 m_sceneGridService.Close();
3375 3221
@@ -3406,6 +3252,7 @@ namespace OpenSim.Region.Framework.Scenes
3406 /// also return a reason.</returns> 3252 /// also return a reason.</returns>
3407 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason) 3253 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason)
3408 { 3254 {
3255 TeleportFlags tp = (TeleportFlags)teleportFlags;
3409 //Teleport flags: 3256 //Teleport flags:
3410 // 3257 //
3411 // TeleportFlags.ViaGodlikeLure - Border Crossing 3258 // TeleportFlags.ViaGodlikeLure - Border Crossing
@@ -3426,7 +3273,7 @@ namespace OpenSim.Region.Framework.Scenes
3426 agent.AgentID, agent.circuitcode, teleportFlags); 3273 agent.AgentID, agent.circuitcode, teleportFlags);
3427 3274
3428 reason = String.Empty; 3275 reason = String.Empty;
3429 if (!AuthenticateUser(agent, out reason)) 3276 if (!VerifyUserPresence(agent, out reason))
3430 return false; 3277 return false;
3431 3278
3432 if (!AuthorizeUser(agent, out reason)) 3279 if (!AuthorizeUser(agent, out reason))
@@ -3439,6 +3286,17 @@ namespace OpenSim.Region.Framework.Scenes
3439 3286
3440 CapsModule.NewUserConnection(agent); 3287 CapsModule.NewUserConnection(agent);
3441 3288
3289 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
3290
3291 //On login or border crossing test land permisions
3292 if (tp != TeleportFlags.Default)
3293 {
3294 if (land != null && !TestLandRestrictions(agent, land, out reason))
3295 {
3296 return false;
3297 }
3298 }
3299
3442 ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID); 3300 ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID);
3443 if (sp != null) 3301 if (sp != null)
3444 { 3302 {
@@ -3526,40 +3384,73 @@ namespace OpenSim.Region.Framework.Scenes
3526 */// This is now handled properly in ScenePresence.MakeRootAgent 3384 */// This is now handled properly in ScenePresence.MakeRootAgent
3527 } 3385 }
3528 3386
3387 agent.teleportFlags = teleportFlags;
3529 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 3388 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
3530 3389
3531 // rewrite session_id 3390 return true;
3532 CachedUserInfo userinfo = CommsManager.UserProfileCacheService.GetUserDetails(agent.AgentID); 3391 }
3533 if (userinfo != null) 3392
3534 { 3393 private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason)
3535 userinfo.SessionID = agent.SessionID; 3394 {
3536 } 3395
3537 else 3396 bool banned = land.IsBannedFromLand(agent.AgentID);
3397 bool restricted = land.IsRestrictedFromLand(agent.AgentID);
3398
3399 if (banned || restricted)
3538 { 3400 {
3539 m_log.WarnFormat( 3401 ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y);
3540 "[CONNECTION BEGIN]: We couldn't find a User Info record for {0}. This is usually an indication that the UUID we're looking up is invalid", agent.AgentID); 3402 if (nearestParcel != null)
3403 {
3404 //Move agent to nearest allowed
3405 Vector3 newPosition = GetParcelCenterAtGround(nearestParcel);
3406 agent.startpos.X = newPosition.X;
3407 agent.startpos.Y = newPosition.Y;
3408 }
3409 else
3410 {
3411 if (banned)
3412 {
3413 reason = "Cannot regioncross into banned parcel.";
3414 }
3415 else
3416 {
3417 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
3418 RegionInfo.RegionName);
3419 }
3420 return false;
3421 }
3541 } 3422 }
3542 3423 reason = "";
3543 return true; 3424 return true;
3544 } 3425 }
3545 3426
3546 /// <summary> 3427 /// <summary>
3547 /// Verifies that the user has a session on the Grid 3428 /// Verifies that the user has a presence on the Grid
3548 /// </summary> 3429 /// </summary>
3549 /// <param name="agent">Circuit Data of the Agent we're verifying</param> 3430 /// <param name="agent">Circuit Data of the Agent we're verifying</param>
3550 /// <param name="reason">Outputs the reason for the false response on this string</param> 3431 /// <param name="reason">Outputs the reason for the false response on this string</param>
3551 /// <returns>True if the user has a session on the grid. False if it does not. False will 3432 /// <returns>True if the user has a session on the grid. False if it does not. False will
3552 /// also return a reason.</returns> 3433 /// also return a reason.</returns>
3553 public virtual bool AuthenticateUser(AgentCircuitData agent, out string reason) 3434 public virtual bool VerifyUserPresence(AgentCircuitData agent, out string reason)
3554 { 3435 {
3555 reason = String.Empty; 3436 reason = String.Empty;
3556 3437
3557 bool result = CommsManager.UserService.VerifySession(agent.AgentID, agent.SessionID); 3438 IPresenceService presence = RequestModuleInterface<IPresenceService>();
3558 m_log.Debug("[CONNECTION BEGIN]: User authentication returned " + result); 3439 if (presence == null)
3559 if (!result) 3440 {
3560 reason = String.Format("Failed to authenticate user {0} {1}, access denied.", agent.firstname, agent.lastname); 3441 reason = String.Format("Failed to verify user {0} {1} in region {2}. Presence service does not exist.", agent.firstname, agent.lastname, RegionInfo.RegionName);
3442 return false;
3443 }
3444
3445 OpenSim.Services.Interfaces.PresenceInfo pinfo = presence.GetAgent(agent.SessionID);
3446
3447 if (pinfo == null || (pinfo != null && pinfo.Online == false))
3448 {
3449 reason = String.Format("Failed to verify user {0} {1}, access denied to region {2}.", agent.firstname, agent.lastname, RegionInfo.RegionName);
3450 return false;
3451 }
3561 3452
3562 return result; 3453 return true;
3563 } 3454 }
3564 3455
3565 /// <summary> 3456 /// <summary>
@@ -3664,6 +3555,18 @@ namespace OpenSim.Region.Framework.Scenes
3664 return true; 3555 return true;
3665 } 3556 }
3666 3557
3558 private ILandObject GetParcelAtPoint(float x, float y)
3559 {
3560 foreach (var parcel in AllParcels())
3561 {
3562 if( parcel.ContainsPoint((int)x,(int)y))
3563 {
3564 return parcel;
3565 }
3566 }
3567 return null;
3568 }
3569
3667 /// <summary> 3570 /// <summary>
3668 /// Update an AgentCircuitData object with new information 3571 /// Update an AgentCircuitData object with new information
3669 /// </summary> 3572 /// </summary>
@@ -3760,8 +3663,8 @@ namespace OpenSim.Region.Framework.Scenes
3760 /// <returns>true if we handled it.</returns> 3663 /// <returns>true if we handled it.</returns>
3761 public virtual bool IncomingChildAgentDataUpdate(AgentData cAgentData) 3664 public virtual bool IncomingChildAgentDataUpdate(AgentData cAgentData)
3762 { 3665 {
3763// m_log.DebugFormat( 3666 m_log.DebugFormat(
3764// "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); 3667 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
3765 3668
3766 // We have to wait until the viewer contacts this region after receiving EAC. 3669 // We have to wait until the viewer contacts this region after receiving EAC.
3767 // That calls AddNewClient, which finally creates the ScenePresence 3670 // That calls AddNewClient, which finally creates the ScenePresence
@@ -3830,16 +3733,6 @@ namespace OpenSim.Region.Framework.Scenes
3830 return false; 3733 return false;
3831 } 3734 }
3832 3735
3833 public virtual bool IncomingReleaseAgent(UUID id)
3834 {
3835 return m_sceneGridService.ReleaseAgent(id);
3836 }
3837
3838 public void SendReleaseAgent(ulong regionHandle, UUID id, string uri)
3839 {
3840 m_interregionCommsOut.SendReleaseAgent(regionHandle, id, uri);
3841 }
3842
3843 /// <summary> 3736 /// <summary>
3844 /// Tell a single agent to disconnect from the region. 3737 /// Tell a single agent to disconnect from the region.
3845 /// </summary> 3738 /// </summary>
@@ -3884,30 +3777,6 @@ namespace OpenSim.Region.Framework.Scenes
3884 } 3777 }
3885 3778
3886 /// <summary> 3779 /// <summary>
3887 /// Tell neighboring regions about this agent
3888 /// When the regions respond with a true value,
3889 /// tell the agents about the region.
3890 ///
3891 /// We have to tell the regions about the agents first otherwise it'll deny them access
3892 ///
3893 /// </summary>
3894 /// <param name="presence"></param>
3895 public void InformClientOfNeighbours(ScenePresence presence)
3896 {
3897 m_sceneGridService.EnableNeighbourChildAgents(presence, m_neighbours);
3898 }
3899
3900 /// <summary>
3901 /// Tell a neighboring region about this agent
3902 /// </summary>
3903 /// <param name="presence"></param>
3904 /// <param name="region"></param>
3905 public void InformClientOfNeighbor(ScenePresence presence, RegionInfo region)
3906 {
3907 m_sceneGridService.EnableNeighbourChildAgents(presence, m_neighbours);
3908 }
3909
3910 /// <summary>
3911 /// Tries to teleport agent to other region. 3780 /// Tries to teleport agent to other region.
3912 /// </summary> 3781 /// </summary>
3913 /// <param name="remoteClient"></param> 3782 /// <param name="remoteClient"></param>
@@ -3982,16 +3851,12 @@ namespace OpenSim.Region.Framework.Scenes
3982 } 3851 }
3983 3852
3984 if (m_teleportModule != null) 3853 if (m_teleportModule != null)
3985 { 3854 m_teleportModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags);
3986 m_teleportModule.RequestTeleportToLocation(sp, regionHandle,
3987 position, lookAt, teleportFlags);
3988 }
3989 else 3855 else
3990 { 3856 {
3991 m_sceneGridService.RequestTeleportToLocation(sp, regionHandle, 3857 m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active");
3992 position, lookAt, teleportFlags); 3858 sp.ControllingClient.SendTeleportFailed("Unable to perform teleports on this simulator.");
3993 } 3859 }
3994
3995 } 3860 }
3996 } 3861 }
3997 3862
@@ -4017,7 +3882,12 @@ namespace OpenSim.Region.Framework.Scenes
4017 3882
4018 public void CrossAgentToNewRegion(ScenePresence agent, bool isFlying) 3883 public void CrossAgentToNewRegion(ScenePresence agent, bool isFlying)
4019 { 3884 {
4020 m_sceneGridService.CrossAgentToNewRegion(this, agent, isFlying); 3885 if (m_teleportModule != null)
3886 m_teleportModule.Cross(agent, isFlying);
3887 else
3888 {
3889 m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule");
3890 }
4021 } 3891 }
4022 3892
4023 public void SendOutChildAgentUpdates(AgentPosition cadu, ScenePresence presence) 3893 public void SendOutChildAgentUpdates(AgentPosition cadu, ScenePresence presence)
@@ -4043,35 +3913,6 @@ namespace OpenSim.Region.Framework.Scenes
4043 objectCapacity = objects; 3913 objectCapacity = objects;
4044 } 3914 }
4045 3915
4046 public List<FriendListItem> GetFriendList(string id)
4047 {
4048 UUID avatarID;
4049 if (!UUID.TryParse(id, out avatarID))
4050 return new List<FriendListItem>();
4051
4052 return CommsManager.GetUserFriendList(avatarID);
4053 }
4054
4055 public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos(List<UUID> uuids)
4056 {
4057 return CommsManager.GetFriendRegionInfos(uuids);
4058 }
4059
4060 public virtual void StoreAddFriendship(UUID ownerID, UUID friendID, uint perms)
4061 {
4062 m_sceneGridService.AddNewUserFriend(ownerID, friendID, perms);
4063 }
4064
4065 public virtual void StoreUpdateFriendship(UUID ownerID, UUID friendID, uint perms)
4066 {
4067 m_sceneGridService.UpdateUserFriendPerms(ownerID, friendID, perms);
4068 }
4069
4070 public virtual void StoreRemoveFriendship(UUID ownerID, UUID ExfriendID)
4071 {
4072 m_sceneGridService.RemoveUserFriend(ownerID, ExfriendID);
4073 }
4074
4075 #endregion 3916 #endregion
4076 3917
4077 public void HandleObjectPermissionsUpdate(IClientAPI controller, UUID agentID, UUID sessionID, byte field, uint localId, uint mask, byte set) 3918 public void HandleObjectPermissionsUpdate(IClientAPI controller, UUID agentID, UUID sessionID, byte field, uint localId, uint mask, byte set)
@@ -4466,7 +4307,7 @@ namespace OpenSim.Region.Framework.Scenes
4466 return m_sceneGraph.GetGroupByPrim(localID); 4307 return m_sceneGraph.GetGroupByPrim(localID);
4467 } 4308 }
4468 4309
4469 public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) 4310 public override bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
4470 { 4311 {
4471 return m_sceneGraph.TryGetAvatar(avatarId, out avatar); 4312 return m_sceneGraph.TryGetAvatar(avatarId, out avatar);
4472 } 4313 }
@@ -4663,7 +4504,8 @@ namespace OpenSim.Region.Framework.Scenes
4663 group.GetPartName(localID), 4504 group.GetPartName(localID),
4664 group.GetPartDescription(localID), 4505 group.GetPartDescription(localID),
4665 (sbyte)AssetType.Object, 4506 (sbyte)AssetType.Object,
4666 Utils.StringToBytes(sceneObjectXml)); 4507 Utils.StringToBytes(sceneObjectXml),
4508 group.OwnerID);
4667 AssetService.Store(asset); 4509 AssetService.Store(asset);
4668 4510
4669 InventoryItemBase item = new InventoryItemBase(); 4511 InventoryItemBase item = new InventoryItemBase();
@@ -4987,5 +4829,185 @@ namespace OpenSim.Region.Framework.Scenes
4987 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) 4829 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000)
4988 StartTimer(); 4830 StartTimer();
4989 } 4831 }
4832
4833 public override ISceneObject DeserializeObject(string representation)
4834 {
4835 return SceneObjectSerializer.FromXml2Format(representation);
4836 }
4837
4838 public override bool AllowScriptCrossings
4839 {
4840 get { return m_allowScriptCrossings; }
4841 }
4842
4843 public Vector3? GetNearestAllowedPosition(ScenePresence avatar)
4844 {
4845 //simulate to make sure we have pretty up to date positions
4846 PhysicsScene.Simulate(0);
4847
4848 ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
4849
4850 if (nearestParcel != null)
4851 {
4852 Vector3 dir = Vector3.Normalize(Vector3.Multiply(avatar.Velocity, -1));
4853 //Try to get a location that feels like where they came from
4854 Vector3? nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel);
4855 if (nearestPoint != null)
4856 {
4857 Debug.WriteLine("Found a sane previous position based on velocity, sending them to: " + nearestPoint.ToString());
4858 return nearestPoint.Value;
4859 }
4860
4861 //Sometimes velocity might be zero (local teleport), so try finding point along path from avatar to center of nearest parcel
4862 Vector3 directionToParcelCenter = Vector3.Subtract(GetParcelCenterAtGround(nearestParcel), avatar.AbsolutePosition);
4863 dir = Vector3.Normalize(directionToParcelCenter);
4864 nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel);
4865 if (nearestPoint != null)
4866 {
4867 Debug.WriteLine("They had a zero velocity, sending them to: " + nearestPoint.ToString());
4868 return nearestPoint.Value;
4869 }
4870
4871 //Ultimate backup if we have no idea where they are
4872 Debug.WriteLine("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString());
4873 return avatar.lastKnownAllowedPosition;
4874
4875 }
4876
4877 //Go to the edge, this happens in teleporting to a region with no available parcels
4878 Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar);
4879 //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString());
4880 return nearestRegionEdgePoint;
4881 return null;
4882 }
4883
4884 private Vector3 GetParcelCenterAtGround(ILandObject parcel)
4885 {
4886 Vector2 center = GetParcelCenter(parcel);
4887 return GetPositionAtGround(center.X, center.Y);
4888 }
4889
4890 private Vector3? GetNearestPointInParcelAlongDirectionFromPoint(Vector3 pos, Vector3 direction, ILandObject parcel)
4891 {
4892 Vector3 unitDirection = Vector3.Normalize(direction);
4893 //Making distance to search go through some sane limit of distance
4894 for (float distance = 0; distance < Constants.RegionSize * 2; distance += .5f)
4895 {
4896 Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance));
4897 if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y))
4898 {
4899 return testPos;
4900 }
4901 }
4902 return null;
4903 }
4904
4905 public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y)
4906 {
4907 List<ILandObject> all = AllParcels();
4908 float minParcelDistance = float.MaxValue;
4909 ILandObject nearestParcel = null;
4910
4911 foreach (var parcel in all)
4912 {
4913 if (!parcel.IsEitherBannedOrRestricted(avatarId))
4914 {
4915 float parcelDistance = GetParcelDistancefromPoint(parcel, x, y);
4916 if (parcelDistance < minParcelDistance)
4917 {
4918 minParcelDistance = parcelDistance;
4919 nearestParcel = parcel;
4920 }
4921 }
4922 }
4923
4924 return nearestParcel;
4925 }
4926
4927 private List<ILandObject> AllParcels()
4928 {
4929 return LandChannel.AllParcels();
4930 }
4931
4932 private float GetParcelDistancefromPoint(ILandObject parcel, float x, float y)
4933 {
4934 return Vector2.Distance(new Vector2(x, y), GetParcelCenter(parcel));
4935 }
4936
4937 //calculate the average center point of a parcel
4938 private Vector2 GetParcelCenter(ILandObject parcel)
4939 {
4940 int count = 0;
4941 int avgx = 0;
4942 int avgy = 0;
4943 for (int x = 0; x < Constants.RegionSize; x++)
4944 {
4945 for (int y = 0; y < Constants.RegionSize; y++)
4946 {
4947 //Just keep a running average as we check if all the points are inside or not
4948 if (parcel.ContainsPoint(x, y))
4949 {
4950 if (count == 0)
4951 {
4952 avgx = x;
4953 avgy = y;
4954 }
4955 else
4956 {
4957 avgx = (avgx * count + x) / (count + 1);
4958 avgy = (avgy * count + y) / (count + 1);
4959 }
4960 count += 1;
4961 }
4962 }
4963 }
4964 return new Vector2(avgx, avgy);
4965 }
4966
4967 private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar)
4968 {
4969 float xdistance = avatar.AbsolutePosition.X < Constants.RegionSize / 2 ? avatar.AbsolutePosition.X : Constants.RegionSize - avatar.AbsolutePosition.X;
4970 float ydistance = avatar.AbsolutePosition.Y < Constants.RegionSize / 2 ? avatar.AbsolutePosition.Y : Constants.RegionSize - avatar.AbsolutePosition.Y;
4971
4972 //find out what vertical edge to go to
4973 if (xdistance < ydistance)
4974 {
4975 if (avatar.AbsolutePosition.X < Constants.RegionSize / 2)
4976 {
4977 return GetPositionAtAvatarHeightOrGroundHeight(avatar, 0.0f, avatar.AbsolutePosition.Y);
4978 }
4979 else
4980 {
4981 return GetPositionAtAvatarHeightOrGroundHeight(avatar, Constants.RegionSize, avatar.AbsolutePosition.Y);
4982 }
4983 }
4984 //find out what horizontal edge to go to
4985 else
4986 {
4987 if (avatar.AbsolutePosition.Y < Constants.RegionSize / 2)
4988 {
4989 return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, 0.0f);
4990 }
4991 else
4992 {
4993 return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, Constants.RegionSize);
4994 }
4995 }
4996 }
4997
4998 private Vector3 GetPositionAtAvatarHeightOrGroundHeight(ScenePresence avatar, float x, float y)
4999 {
5000 Vector3 ground = GetPositionAtGround(x, y);
5001 if( avatar.AbsolutePosition.Z > ground.Z)
5002 {
5003 ground.Z = avatar.AbsolutePosition.Z;
5004 }
5005 return ground;
5006 }
5007
5008 private Vector3 GetPositionAtGround(float x, float y)
5009 {
5010 return new Vector3(x, y, GetGroundHeight(x, y));
5011 }
4990 } 5012 }
4991} 5013}