public bool Cross(ScenePresence agent, bool isFlying) { Scene scene = agent.Scene; Vector3 pos = agent.AbsolutePosition; Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); uint neighbourx; uint neighboury; const float boundaryDistance = 1.7f; // assuming that the need for crossing was verified by callers int x, y; if (scene.RegionInfo.CombinedRegionHandle != 0) // we are a slave region send to main region { Utils.LongToUInts(scene.RegionInfo.CombinedRegionHandle, out neighbourx, out neighboury); agent.IsInTransit = true; Vector3 newposition = pos; newposition.X += ((int)scene.RegionInfo.RegionLocX * Constants.RegionSize - (int)neighbourx); newposition.Y += ((int)scene.RegionInfo.RegionLocY * Constants.RegionSize - (int)neighboury); agent.ControllingClient.SendAgentAlertMessage( String.Format("Relocating you in root region"), false); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); return true; } if (pos.X - boundaryDistance < 0) // going W { x = -1; newpos.X = Constants.RegionSize + pos.X - boundaryDistance; } else // assume we are going E { x = ((int)(pos.X + boundaryDistance) / (int)Constants.RegionSize); newpos.X = pos.X - x * (int)Constants.RegionSize; } x += (int)scene.RegionInfo.RegionLocX; neighbourx = (uint)x; x *= (int)Constants.RegionSize; if (pos.Y - boundaryDistance < 0) // going S SW or SE { y = -1; newpos.Y = Constants.RegionSize + pos.Y - boundaryDistance; } else // assume we are going N NW or NE { y = ((int)(pos.Y + boundaryDistance) / (int)Constants.RegionSize); newpos.Y = pos.Y - y * (int)Constants.RegionSize; } y += (int)scene.RegionInfo.RegionLocY; neighboury = (uint)y; y *= (int)Constants.RegionSize; // int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y); ExpiringCache<ulong, DateTime> r; DateTime banUntil; if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) { if (r.TryGetValue(neighbourHandle, out banUntil)) { if (DateTime.Now < banUntil) return false; r.Remove(neighbourHandle); } } else { r = null; } GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, x, y); if (neighbourRegion == null) return false; string reason; string version; if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason)) { agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); if (r == null) { r = new ExpiringCache<ulong, DateTime>(); r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); } else { r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); } return false; } agent.IsInTransit = true; CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); return true; }
public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client) { if (!(client.Scene is Scene)) { return; } Scene scene = (Scene)(client.Scene); ScenePresence presence = scene.GetScenePresence(client.AgentId); message += "@" + m_ThisGridURL; m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message); UUID sessionID = UUID.Random(); GridInstantMessage m = new GridInstantMessage(scene, client.AgentId, client.FirstName + " " + client.LastName, targetid, (byte)InstantMessageDialog.RequestTeleport, false, message, sessionID, false, presence.AbsolutePosition, new Byte[0], true); m.RegionID = client.Scene.RegionInfo.RegionID.Guid; m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message); m_PendingLures.Add(sessionID, m, 7200); // 2 hours if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(m, delegate(bool success) { }); } }
public UUID CreateCapability(CapsRequestCallback localHandler, bool clientCertRequired, object state, double ttlSeconds) { UUID id = UUID.Random(); CapsRedirector redirector = new CapsRedirector(localHandler, null, clientCertRequired, state); lock (syncRoot) expiringCaps.Add(id, redirector, DateTime.Now + TimeSpan.FromSeconds(ttlSeconds)); return(id); }
public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client) { IScenePresence presence = client.Scene.GetScenePresence(client.AgentId); UUID dest = Util.BuildFakeParcelID( client.Scene.RegionInfo.RegionHandle, (uint)presence.AbsolutePosition.X, (uint)presence.AbsolutePosition.Y, (uint)presence.AbsolutePosition.Z); string mainGridURL = GetMainGridURL(); message += "@" + mainGridURL;//Add it to the message GridInstantMessage m; if (m_allowGodTeleports && client.Scene.Permissions.IsGod(client.AgentId) && presence.GodLevel > 0) //if we are an admin and are in god mode { if (client.Scene.Permissions.IsGod(targetid)) //if they are an admin { //Gods do not tp other gods m = new GridInstantMessage(client.Scene, client.AgentId, client.FirstName + " " + client.LastName, targetid, (byte)InstantMessageDialog.RequestTeleport, false, message, dest, false, presence.AbsolutePosition, new Byte[0]); } else { //God tp them m = new GridInstantMessage(client.Scene, client.AgentId, client.FirstName + " " + client.LastName, targetid, (byte)InstantMessageDialog.GodLikeRequestTeleport, false, "", dest, false, presence.AbsolutePosition, new Byte[0]); } } else { //Not a god, so no god tp m = new GridInstantMessage(client.Scene, client.AgentId, client.FirstName + " " + client.LastName, targetid, (byte)InstantMessageDialog.RequestTeleport, false, message, dest, false, presence.AbsolutePosition, new Byte[0]); } m_PendingLures.Add(m.imSessionID, m, 7200); // 2 hours if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(m); } }
public UUID CreateGroup(UUID RequestingAgentID, GroupRecordDelegate d) { //m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name); //reason = string.Empty; //ExtendedGroupRecord group = m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID, // membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason); ExtendedGroupRecord group = d(); if (group == null) { return(UUID.Zero); } if (group.GroupID != UUID.Zero) { lock (m_Cache) { m_Cache.Add("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT); if (m_Cache.Contains("memberships-" + RequestingAgentID.ToString())) { m_Cache.Remove("memberships-" + RequestingAgentID.ToString()); } } } return(group.GroupID); }
public bool HasGroupAccess(UUID avatar) { if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) { ScenePresence sp; if (!m_scene.TryGetScenePresence(avatar, out sp)) { bool isMember; if (m_groupMemberCache.TryGetValue(avatar, out isMember)) { m_groupMemberCache.Update(avatar, isMember, m_groupMemberCacheTimeout); return(isMember); } IGroupsModule groupsModule = m_scene.RequestModuleInterface <IGroupsModule>(); if (groupsModule == null) { return(false); } GroupMembershipData[] membership = groupsModule.GetMembershipData(avatar); if (membership == null || membership.Length == 0) { m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); return(false); } foreach (GroupMembershipData d in membership) { if (d.GroupID == LandData.GroupID) { m_groupMemberCache.Add(avatar, true, m_groupMemberCacheTimeout); return(true); } } m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); return(false); } return(sp.ControllingClient.IsGroupMember(LandData.GroupID)); } return(false); }
void OnIncomingInstantMessage(GridInstantMessage im) { if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) { UUID sessionID = new UUID(im.imSessionID); if (!m_PendingLures.Contains(sessionID)) { m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message); m_PendingLures.Add(sessionID, im, 7200); // 2 hours } // Forward. We do this, because the IM module explicitly rejects // IMs of this type if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); } } }
public void Cache(UUID userID, AssetType type, InventoryFolderBase folder) { lock (m_FolderTypes) { Dictionary <AssetType, InventoryFolderBase> ff = null; if (!m_FolderTypes.TryGetValue(userID, out ff)) { ff = new Dictionary <AssetType, InventoryFolderBase>(); m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); } if (!ff.ContainsKey(type)) { ff.Add(type, folder); } } }
public void Cache(UUID userID, AssetType type, InventoryFolderBase folder) { Dictionary <AssetType, InventoryFolderBase> ff = null; if (!m_FolderTypes.TryGetValue(userID, out ff)) { ff = new Dictionary <AssetType, InventoryFolderBase>(); m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); } // We need to lock here since two threads could potentially retrieve the same dictionary // and try to add a folder for that type simultaneously. Dictionary<>.Add() is not described as thread-safe in the SDK // even if the folders are identical. lock (ff) { if (!ff.ContainsKey(type)) { ff.Add(type, folder); } } }
public void SendMessageToGroup( GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition) { int requestStartTick = Environment.TickCount; UUID fromAgentID = new UUID(im.fromAgentID); // Unlike current XmlRpcGroups, Groups V2 can accept UUID.Zero when a perms check for the requesting agent // is not necessary. List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID); int groupMembersCount = groupMembers.Count; PresenceInfo[] onlineAgents = null; // In V2 we always only send to online members. // Sending to offline members is not an option. // We cache in order not to overwhelm the presence service on large grids with many groups. This does // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. // (assuming this is the same across all grid simulators). if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents)) { string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray(); onlineAgents = m_presenceService.GetAgents(t1); m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); } HashSet <string> onlineAgentsUuidSet = new HashSet <string>(); Array.ForEach <PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); // if (m_debugEnabled) // m_log.DebugFormat( // "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", // groupID, groupMembersCount, groupMembers.Count()); im.imSessionID = groupID.Guid; im.fromGroup = true; IClientAPI thisClient = GetActiveClient(fromAgentID); if (thisClient != null) { im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid; } if ((im.binaryBucket == null) || (im.binaryBucket.Length == 0) || ((im.binaryBucket.Length == 1 && im.binaryBucket[0] == 0))) { ExtendedGroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), groupID, null); if (groupInfo != null) { im.binaryBucket = Util.StringToBytes256(groupInfo.GroupName); } } // Send to self first of all im.toAgentID = im.fromAgentID; im.fromGroup = true; ProcessMessageFromGroupSession(im); List <UUID> regions = new List <UUID>(); List <UUID> clientsAlreadySent = new List <UUID>(); // Then send to everybody else foreach (GroupMembersData member in groupMembers) { if (member.AgentID.Guid == im.fromAgentID) { continue; } if (clientsAlreadySent.Contains(member.AgentID)) { continue; } clientsAlreadySent.Add(member.AgentID); if (sendCondition != null) { if (!sendCondition(member)) { if (m_debugEnabled) { m_log.DebugFormat( "[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition", member.AgentID); } continue; } } else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) { // Don't deliver messages to people who have dropped this session if (m_debugEnabled) { m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID); } continue; } im.toAgentID = member.AgentID.Guid; IClientAPI client = GetActiveClient(member.AgentID); if (client == null) { // If they're not local, forward across the grid // BUT do it only once per region, please! Sim would be even better! if (m_debugEnabled) { m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID); } bool reallySend = true; if (onlineAgents != null) { PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString()); if (regions.Contains(presence.RegionID)) { reallySend = false; } else { regions.Add(presence.RegionID); } } if (reallySend) { // We have to create a new IM structure because the transfer module // uses async send GridInstantMessage msg = new GridInstantMessage(im, true); m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); } } else { // Deliver locally, directly if (m_debugEnabled) { m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); } ProcessMessageFromGroupSession(im); } } if (m_debugEnabled) { m_log.DebugFormat( "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); } }
public bool Cross(ScenePresence agent, bool isFlying) { Scene scene = agent.Scene; Vector3 pos = agent.AbsolutePosition; Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); uint neighbourx = scene.RegionInfo.RegionLocX; uint neighboury = scene.RegionInfo.RegionLocY; const float boundaryDistance = 1.7f; Vector3 northCross = new Vector3(0, boundaryDistance, 0); Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0); Vector3 eastCross = new Vector3(boundaryDistance, 0, 0); Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0); // distance to edge that will trigger crossing // distance into new region to place avatar const float enterDistance = 0.5f; if (scene.TestBorderCross(pos + westCross, Cardinals.W)) { if (scene.TestBorderCross(pos + northCross, Cardinals.N)) { Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); } else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) { neighboury--; newpos.Y = Constants.RegionSize - enterDistance; } else { agent.IsInTransit = true; neighboury = b.TriggerRegionY; neighbourx = b.TriggerRegionX; Vector3 newposition = pos; newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); return true; } } Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W); if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) { neighbourx--; newpos.X = Constants.RegionSize - enterDistance; } else { agent.IsInTransit = true; neighboury = ba.TriggerRegionY; neighbourx = ba.TriggerRegionX; Vector3 newposition = pos; newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); return true; } } else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) { Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E); neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); newpos.X = enterDistance; if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) { neighboury--; newpos.Y = Constants.RegionSize - enterDistance; } else { agent.IsInTransit = true; neighboury = ba.TriggerRegionY; neighbourx = ba.TriggerRegionX; Vector3 newposition = pos; newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); return true; } } else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) { Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N); neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); newpos.Y = enterDistance; } } else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) { neighboury--; newpos.Y = Constants.RegionSize - enterDistance; } else { agent.IsInTransit = true; neighboury = b.TriggerRegionY; neighbourx = b.TriggerRegionX; Vector3 newposition = pos; newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; agent.ControllingClient.SendAgentAlertMessage( String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); return true; } } else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) { Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); newpos.Y = enterDistance; } /* if (pos.X < boundaryDistance) //West { neighbourx--; newpos.X = Constants.RegionSize - enterDistance; } else if (pos.X > Constants.RegionSize - boundaryDistance) // East { neighbourx++; newpos.X = enterDistance; } if (pos.Y < boundaryDistance) // South { neighboury--; newpos.Y = Constants.RegionSize - enterDistance; } else if (pos.Y > Constants.RegionSize - boundaryDistance) // North { neighboury++; newpos.Y = enterDistance; } */ ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); ExpiringCache<ulong, DateTime> r; DateTime banUntil; if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) { if (r.TryGetValue(neighbourHandle, out banUntil)) { if (DateTime.Now < banUntil) return false; r.Remove(neighbourHandle); } } else { r = null; } GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); string reason; string version; if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason)) { agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); if (r == null) { r = new ExpiringCache<ulong, DateTime>(); r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); } else { r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); } return false; } agent.IsInTransit = true; CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); return true; }
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) { version = String.Empty; newpos = new Vector3(pos.X, pos.Y, pos.Z); // m_log.DebugFormat( // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); uint neighbourx = scene.RegionInfo.RegionLocX; uint neighboury = scene.RegionInfo.RegionLocY; const float boundaryDistance = 1.7f; Vector3 northCross = new Vector3(0, boundaryDistance, 0); Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0); Vector3 eastCross = new Vector3(boundaryDistance, 0, 0); Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0); // distance into new region to place avatar const float enterDistance = 0.5f; if (scene.TestBorderCross(pos + westCross, Cardinals.W)) { if (scene.TestBorderCross(pos + northCross, Cardinals.N)) { Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); } else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { neighboury--; newpos.Y = Constants.RegionSize - enterDistance; } neighbourx--; newpos.X = Constants.RegionSize - enterDistance; } else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) { Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E); neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); newpos.X = enterDistance; if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { neighboury--; newpos.Y = Constants.RegionSize - enterDistance; } else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) { Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N); neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); newpos.Y = enterDistance; } } else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); neighboury--; newpos.Y = Constants.RegionSize - enterDistance; } else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) { Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); newpos.Y = enterDistance; } /* if (pos.X < boundaryDistance) //West { neighbourx--; newpos.X = Constants.RegionSize - enterDistance; } else if (pos.X > Constants.RegionSize - boundaryDistance) // East { neighbourx++; newpos.X = enterDistance; } if (pos.Y < boundaryDistance) // South { neighboury--; newpos.Y = Constants.RegionSize - enterDistance; } else if (pos.Y > Constants.RegionSize - boundaryDistance) // North { neighboury++; newpos.Y = enterDistance; } */ xDest = neighbourx; yDest = neighboury; int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y); ExpiringCache<ulong, DateTime> r; DateTime banUntil; if (m_bannedRegions.TryGetValue(agentID, out r)) { if (r.TryGetValue(neighbourHandle, out banUntil)) { if (DateTime.Now < banUntil) return null; r.Remove(neighbourHandle); } } else { r = null; } GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); string reason; if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) { if (r == null) { r = new ExpiringCache<ulong, DateTime>(); r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); } else { r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); } return null; } return neighbourRegion; }
public void SendMessageToGroup( GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition) { int requestStartTick = Environment.TickCount; List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, groupID); int groupMembersCount = groupMembers.Count; HashSet <string> attemptDeliveryUuidSet = null; if (m_messageOnlineAgentsOnly) { string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray(); // We cache in order not to overwhlem the presence service on large grids with many groups. This does // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. // (assuming this is the same across all grid simulators). PresenceInfo[] onlineAgents; if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents)) { onlineAgents = m_presenceService.GetAgents(t1); m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); } attemptDeliveryUuidSet = new HashSet <string>(Array.ConvertAll <PresenceInfo, string>(onlineAgents, pi => pi.UserID)); } else { attemptDeliveryUuidSet = new HashSet <string>(groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString())); if (m_debugEnabled) { m_log.DebugFormat( "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", groupID, groupMembers.Count); } } foreach (GroupMembersData member in groupMembers) { if (sendCondition != null) { if (!sendCondition(member)) { if (m_debugEnabled) { m_log.DebugFormat( "[GROUPS-MESSAGING]: Not sending to {0} as they do not fulfill send condition", member.AgentID); } continue; } } else if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) { // Don't deliver messages to people who have dropped this session if (m_debugEnabled) { m_log.DebugFormat( "[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); } continue; } // Copy Message GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = im.imSessionID; msg.fromAgentName = im.fromAgentName; msg.message = im.message; msg.dialog = im.dialog; msg.offline = im.offline; msg.ParentEstateID = im.ParentEstateID; msg.Position = im.Position; msg.RegionID = im.RegionID; msg.binaryBucket = im.binaryBucket; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentID = im.fromAgentID; msg.fromGroup = true; msg.toAgentID = member.AgentID.Guid; if (attemptDeliveryUuidSet.Contains(member.AgentID.ToString())) { IClientAPI client = GetActiveClient(member.AgentID); if (client == null) { int startTick = Environment.TickCount; // If they're not local, forward across the grid m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); if (m_debugEnabled) { m_log.DebugFormat( "[GROUPS-MESSAGING]: Delivering to {0} via grid took {1} ms", member.AgentID, Environment.TickCount - startTick); } } else { int startTick = Environment.TickCount; ProcessMessageFromGroupSession(msg, client); // Deliver locally, directly if (m_debugEnabled) { m_log.DebugFormat( "[GROUPS-MESSAGING]: Delivering to {0} locally took {1} ms", member.AgentID, Environment.TickCount - startTick); } } } else if (im.dialog != (byte)InstantMessageDialog.SessionAdd && im.dialog != (byte)InstantMessageDialog.SessionDrop) { int startTick = Environment.TickCount; m_msgTransferModule.HandleUndeliverableMessage(msg, delegate(bool success) { }); if (m_debugEnabled) { m_log.DebugFormat( "[GROUPS-MESSAGING]: Handling undeliverable message for {0} took {1} ms", member.AgentID, Environment.TickCount - startTick); } } } if (m_debugEnabled) { m_log.DebugFormat( "[GROUPS-MESSAGING]: Total SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3} ms", groupID, groupMembersCount, attemptDeliveryUuidSet.Count(), Environment.TickCount - requestStartTick); } }
public bool TryGetSessionInfo(Request request, out SessionInfo sinfo) { bool success = false; sinfo = new SessionInfo(); if (request.Query.ContainsKey("sid")) { string sid = request.Query["sid"].ToString(); if (m_Sessions.Contains(sid)) { SessionInfo session; if (m_Sessions.TryGetValue(sid, out session) && session.IpAddress == request.IPEndPoint.Address.ToString()) { sinfo = session; m_Sessions.AddOrUpdate(sid, session, m_WebApp.SessionTimeout); success = true; } } else { UUID sessionid = UUID.Zero; if (UUID.TryParse(request.Query["sid"].ToString(), out sessionid)) { PresenceInfo pinfo = m_PresenceService.GetAgent(sessionid); if (pinfo != null) { m_log.DebugFormat("[Wifi]: User is present in the grid"); success = true; UserAccount account = null; if (request.Query.ContainsKey("uid")) { UUID userID = UUID.Zero; if (UUID.TryParse(request.Query["uid"].ToString(), out userID)) { account = m_UserAccountService.GetUserAccount(UUID.Zero, userID); } } else { m_log.DebugFormat("[Wifi]: No uid in Query"); } sinfo.IpAddress = request.IPEndPoint.Address.ToString(); sinfo.Sid = request.Query["sid"].ToString(); sinfo.Account = account; sinfo.Notify = new NotificationData(); m_Sessions.Add(sinfo.Sid, sinfo, m_WebApp.SessionTimeout); } else { m_log.DebugFormat("[Wifi]: User is not present in the grid"); } } else { m_log.DebugFormat("[Wifi]: Unable o parse sid {0}", request.Query["sid"].ToString()); } } } //else // m_log.DebugFormat("[Wifi]: no sid in Query"); return(success); }
public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); int groupMembersCount = groupMembers.Count; if (m_messageOnlineAgentsOnly) { string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray(); // We cache in order not to overwhlem the presence service on large grids with many groups. This does // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. // (assuming this is the same across all grid simulators). PresenceInfo[] onlineAgents; if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents)) { onlineAgents = m_presenceService.GetAgents(t1); m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); } HashSet <string> onlineAgentsUuidSet = new HashSet <string>(); Array.ForEach <PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); // if (m_debugEnabled) // m_log.DebugFormat( // "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", // groupID, groupMembersCount, groupMembers.Count()); } else { if (m_debugEnabled) { m_log.DebugFormat( "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", groupID, groupMembers.Count); } } int requestStartTick = Environment.TickCount; foreach (GroupMembersData member in groupMembers) { if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) { // Don't deliver messages to people who have dropped this session if (m_debugEnabled) { m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); } continue; } // Copy Message GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = groupID.Guid; msg.fromAgentName = im.fromAgentName; msg.message = im.message; msg.dialog = im.dialog; msg.offline = im.offline; msg.ParentEstateID = im.ParentEstateID; msg.Position = im.Position; msg.RegionID = im.RegionID; msg.binaryBucket = im.binaryBucket; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentID = im.fromAgentID; msg.fromGroup = true; msg.toAgentID = member.AgentID.Guid; IClientAPI client = GetActiveClient(member.AgentID); if (client == null) { // If they're not local, forward across the grid if (m_debugEnabled) { m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); } m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); } else { // Deliver locally, directly if (m_debugEnabled) { m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); } ProcessMessageFromGroupSession(msg); } } // Temporary for assessing how long it still takes to send messages to large online groups. if (m_messageOnlineAgentsOnly) { m_log.DebugFormat( "[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); } }
public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) { ulong regionHandle = Util.UIntsToLong((uint)x, (uint)y); if (m_regionCache.Contains(regionHandle)) { return((GridRegion)m_regionCache[regionHandle]); } Dictionary <string, object> sendData = new Dictionary <string, object>(); sendData["SCOPEID"] = scopeID.ToString(); sendData["X"] = x.ToString(); sendData["Y"] = y.ToString(); sendData["METHOD"] = "get_region_by_position"; string reply = string.Empty; string uri = m_ServerURI + "/grid"; try { reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData), m_Auth); } catch (Exception e) { m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); return(null); } GridRegion rinfo = null; if (reply != string.Empty) { Dictionary <string, object> replyData = ServerUtils.ParseXmlResponse(reply); if ((replyData != null) && (replyData["result"] != null)) { if (replyData["result"] is Dictionary <string, object> ) { rinfo = new GridRegion((Dictionary <string, object>)replyData["result"]); } //else // m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received no region", // scopeID, x, y); } else { m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition {0}, {1}-{2} received null response", scopeID, x, y); } } else { m_log.DebugFormat("[GRID CONNECTOR]: GetRegionByPosition received null reply"); } m_regionCache.Add(regionHandle, rinfo, TimeSpan.FromSeconds(600)); return(rinfo); }