aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs307
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs31
2 files changed, 180 insertions, 158 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 62dea07..5387910 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1158,177 +1158,182 @@ namespace OpenSim.Region.Framework.Scenes
1158 1158
1159 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1159 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
1160 1160
1161/* this is now done by groups module on TriggerOnMakeRootAgent(this) below
1162 at least XmlIRpcGroups
1161 UUID groupUUID = UUID.Zero; 1163 UUID groupUUID = UUID.Zero;
1162 string GroupName = string.Empty; 1164 string GroupName = string.Empty;
1163 ulong groupPowers = 0; 1165 ulong groupPowers = 0;
1164 1166
1165 // ----------------------------------
1166 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1167 try
1168 {
1169
1170 if (gm != null)
1171 {
1172 groupUUID = ControllingClient.ActiveGroupId;
1173 GroupRecord record = gm.GetGroupRecord(groupUUID);
1174 if (record != null)
1175 GroupName = record.GroupName;
1176 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1177 if (groupMembershipData != null)
1178 groupPowers = groupMembershipData.GroupPowers;
1179 }
1180 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1181 Grouptitle);
1182 }
1183 catch (Exception e)
1184 {
1185 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
1186 }
1187 // ------------------------------------
1188 1167
1189 if (ParentID == 0)
1190 {
1191 // Moved this from SendInitialData to ensure that Appearance is initialized
1192 // before the inventory is processed in MakeRootAgent. This fixes a race condition
1193 // related to the handling of attachments
1194
1195 if (m_scene.TestBorderCross(pos, Cardinals.E))
1196 {
1197 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1198 pos.X = crossedBorder.BorderLine.Z - 1;
1199 }
1200 1168
1201 if (m_scene.TestBorderCross(pos, Cardinals.N))
1202 {
1203 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
1204 pos.Y = crossedBorder.BorderLine.Z - 1;
1205 }
1206 1169
1207 CheckAndAdjustLandingPoint(ref pos); 1170 // ----------------------------------
1171 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1172 try
1173 {
1174
1175 if (gm != null)
1176 {
1177 groupUUID = ControllingClient.ActiveGroupId;
1178 GroupRecord record = gm.GetGroupRecord(groupUUID);
1179 if (record != null)
1180 GroupName = record.GroupName;
1181 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1182 if (groupMembershipData != null)
1183 groupPowers = groupMembershipData.GroupPowers;
1184 }
1185 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
1186 Grouptitle);
1187 }
1188 catch (Exception e)
1189 {
1190 m_log.Debug("[AGENTUPDATE]: " + e.ToString());
1191 }
1192 // ------------------------------------
1193*/
1194 if (ParentID == 0)
1195 {
1196 // Moved this from SendInitialData to ensure that Appearance is initialized
1197 // before the inventory is processed in MakeRootAgent. This fixes a race condition
1198 // related to the handling of attachments
1208 1199
1209 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 1200 if (m_scene.TestBorderCross(pos, Cardinals.E))
1210 { 1201 {
1211 m_log.WarnFormat( 1202 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
1212 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 1203 pos.X = crossedBorder.BorderLine.Z - 1;
1213 pos, Name, UUID); 1204 }
1214 1205
1215 if (pos.X < 0f) pos.X = 0f; 1206 if (m_scene.TestBorderCross(pos, Cardinals.N))
1216 if (pos.Y < 0f) pos.Y = 0f; 1207 {
1217 if (pos.Z < 0f) pos.Z = 0f; 1208 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
1218 } 1209 pos.Y = crossedBorder.BorderLine.Z - 1;
1210 }
1219 1211
1220 float localAVHeight = 1.56f; 1212 CheckAndAdjustLandingPoint(ref pos);
1221 if (Appearance.AvatarHeight > 0)
1222 localAVHeight = Appearance.AvatarHeight;
1223 1213
1224 float posZLimit = 0; 1214 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
1215 {
1216 m_log.WarnFormat(
1217 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
1218 pos, Name, UUID);
1225 1219
1226 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 1220 if (pos.X < 0f) pos.X = 0f;
1227 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 1221 if (pos.Y < 0f) pos.Y = 0f;
1228 1222 if (pos.Z < 0f) pos.Z = 0f;
1229 float newPosZ = posZLimit + localAVHeight / 2; 1223 }
1230 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
1231 {
1232 pos.Z = newPosZ;
1233 }
1234 AbsolutePosition = pos;
1235 1224
1236 if (m_teleportFlags == TeleportFlags.Default) 1225 float localAVHeight = 1.56f;
1237 { 1226 if (Appearance.AvatarHeight > 0)
1238 Vector3 vel = Velocity; 1227 localAVHeight = Appearance.AvatarHeight;
1239 AddToPhysicalScene(isFlying);
1240 if (PhysicsActor != null)
1241 PhysicsActor.SetMomentum(vel);
1242 }
1243 else
1244 AddToPhysicalScene(isFlying);
1245 1228
1246 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a 1229 float posZLimit = 0;
1247 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1248 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1249 // the value to a negative position which does not trigger the border cross.
1250 // This may not be the best location for this.
1251 CheckForBorderCrossing();
1252 1230
1253 if (ForceFly) 1231 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
1254 { 1232 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
1255 Flying = true; 1233
1256 } 1234 float newPosZ = posZLimit + localAVHeight / 2;
1257 else if (FlyDisabled) 1235 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
1258 { 1236 {
1259 Flying = false; 1237 pos.Z = newPosZ;
1260 } 1238 }
1261 } 1239 AbsolutePosition = pos;
1262 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
1263 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1264 // elsewhere anyway
1265 // Animator.SendAnimPack();
1266
1267 m_scene.SwapRootAgentCount(false);
1268
1269 // The initial login scene presence is already root when it gets here
1270 // and it has already rezzed the attachments and started their scripts.
1271 // We do the following only for non-login agents, because their scripts
1272 // haven't started yet.
1273/* moved down
1274 if (PresenceType == PresenceType.Npc || (TeleportFlags & TeleportFlags.ViaLogin) != 0)
1275 {
1276 // Viewers which have a current outfit folder will actually rez their own attachments. However,
1277 // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
1278 if (Scene.AttachmentsModule != null)
1279 Util.FireAndForget(
1280 o =>
1281 {
1282// if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None)
1283// System.Threading.Thread.Sleep(7000);
1284 1240
1285 Scene.AttachmentsModule.RezAttachments(this); 1241 if (m_teleportFlags == TeleportFlags.Default)
1286 }); 1242 {
1287 } 1243 Vector3 vel = Velocity;
1288 else 1244 AddToPhysicalScene(isFlying);
1245 if (PhysicsActor != null)
1246 PhysicsActor.SetMomentum(vel);
1247 }
1248 else
1249 AddToPhysicalScene(isFlying);
1289 1250
1290 { 1251 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1291 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT 1252 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1292 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently 1253 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1293 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are 1254 // the value to a negative position which does not trigger the border cross.
1294 // not transporting the required data. 1255 // This may not be the best location for this.
1295 // 1256 CheckForBorderCrossing();
1296 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
1297 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1298 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1299 // not transporting the required data.
1300 //
1301 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1302 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1303 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1304 //
1305 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1306 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1307 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1308 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1309 //
1310 // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
1311 // be locked, allowing race conditions if other code changes the attachments list.
1312 1257
1313 List<SceneObjectGroup> attachments = GetAttachments(); 1258 if (ForceFly)
1259 {
1260 Flying = true;
1261 }
1262 else if (FlyDisabled)
1263 {
1264 Flying = false;
1265 }
1266 }
1267 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
1268 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1269 // elsewhere anyway
1270 // Animator.SendAnimPack();
1271
1272 m_scene.SwapRootAgentCount(false);
1273
1274 // The initial login scene presence is already root when it gets here
1275 // and it has already rezzed the attachments and started their scripts.
1276 // We do the following only for non-login agents, because their scripts
1277 // haven't started yet.
1278 /* moved down
1279 if (PresenceType == PresenceType.Npc || (TeleportFlags & TeleportFlags.ViaLogin) != 0)
1280 {
1281 // Viewers which have a current outfit folder will actually rez their own attachments. However,
1282 // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
1283 if (Scene.AttachmentsModule != null)
1284 Util.FireAndForget(
1285 o =>
1286 {
1287 // if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None)
1288 // System.Threading.Thread.Sleep(7000);
1289
1290 Scene.AttachmentsModule.RezAttachments(this);
1291 });
1292 }
1293 else
1314 1294
1315 if (attachments.Count > 0) 1295 {
1316 { 1296 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
1317 m_log.DebugFormat( 1297 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1318 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); 1298 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1299 // not transporting the required data.
1300 //
1301 // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
1302 // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
1303 // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
1304 // not transporting the required data.
1305 //
1306 // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
1307 // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
1308 // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
1309 //
1310 // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
1311 // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
1312 // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
1313 // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
1314 //
1315 // One cannot simply iterate over attachments in a fire and forget thread because this would no longer
1316 // be locked, allowing race conditions if other code changes the attachments list.
1317
1318 List<SceneObjectGroup> attachments = GetAttachments();
1319
1320 if (attachments.Count > 0)
1321 {
1322 m_log.DebugFormat(
1323 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
1319 1324
1320 // Resume scripts this possible should also be moved down after sending the avatar to viewer ? 1325 // Resume scripts this possible should also be moved down after sending the avatar to viewer ?
1321 foreach (SceneObjectGroup sog in attachments) 1326 foreach (SceneObjectGroup sog in attachments)
1322 { 1327 {
1323// sending attachments before the avatar ? 1328 // sending attachments before the avatar ?
1324// moved to completemovement where it already was 1329 // moved to completemovement where it already was
1325// sog.ScheduleGroupForFullUpdate(); 1330 // sog.ScheduleGroupForFullUpdate();
1326 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 1331 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
1327 sog.ResumeScripts(); 1332 sog.ResumeScripts();
1328 } 1333 }
1329 } 1334 }
1330 } 1335 }
1331*/ 1336 */
1332/* 1337/*
1333 SendAvatarDataToAllAgents(); 1338 SendAvatarDataToAllAgents();
1334 1339
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index d2a6828..2764465 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -195,6 +195,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
195 } 195 }
196 196
197 scene.EventManager.OnNewClient += OnNewClient; 197 scene.EventManager.OnNewClient += OnNewClient;
198 scene.EventManager.OnMakeRootAgent += OnMakeRoot;
199 scene.EventManager.OnMakeChildAgent += OnMakeChild;
198 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 200 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
199 // The InstantMessageModule itself doesn't do this, 201 // The InstantMessageModule itself doesn't do this,
200 // so lets see if things explode if we don't do it 202 // so lets see if things explode if we don't do it
@@ -245,19 +247,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
245 #endregion 247 #endregion
246 248
247 #region EventHandlers 249 #region EventHandlers
250
251 private void OnMakeRoot(ScenePresence sp)
252 {
253 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
254
255 sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
256 // Used for Notices and Group Invites/Accept/Reject
257 sp.ControllingClient.OnInstantMessage += OnInstantMessage;
258 // Send client their groups information.
259// SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID);
260 // only send data viwer will ask rest later
261 OnAgentDataUpdateRequest(sp.ControllingClient, sp.UUID, sp.UUID);
262 }
263
264 private void OnMakeChild(ScenePresence sp)
265 {
266 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
267
268 sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
269 sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
270 }
271
248 private void OnNewClient(IClientAPI client) 272 private void OnNewClient(IClientAPI client)
249 { 273 {
250 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 274 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
251 275
252 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
253 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 276 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
254 client.OnRequestAvatarProperties += OnRequestAvatarProperties; 277 client.OnRequestAvatarProperties += OnRequestAvatarProperties;
255
256 // Used for Notices and Group Invites/Accept/Reject
257 client.OnInstantMessage += OnInstantMessage;
258
259 // Send client their groups information.
260 SendAgentGroupDataUpdate(client, client.AgentId);
261 } 278 }
262 279
263 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 280 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)