/// <summary> /// This is called by a timer and makes a SimStats class of the current stats that we have in this simulator. /// It then sends the packet to the client and triggers the events to tell followers about the updated stats /// and updates the LastSet* values for monitors. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void statsHeartBeat(object sender, EventArgs e) { if (m_currentScene.PhysicsScene == null) { return; } m_report.Stop(); if (rb == null) { buildInitialRegionBlock(); } // Know what's not thread safe in Mono... modifying timers. lock (m_report) { ISimFrameMonitor simFrameMonitor = GetMonitor <ISimFrameMonitor>(); ITimeDilationMonitor timeDilationMonitor = GetMonitor <ITimeDilationMonitor>(); ITotalFrameTimeMonitor totalFrameMonitor = GetMonitor <ITotalFrameTimeMonitor>(); ISleepFrameMonitor sleepFrameMonitor = GetMonitor <ISleepFrameMonitor>(); IOtherFrameMonitor otherFrameMonitor = GetMonitor <IOtherFrameMonitor>(); IPhysicsFrameMonitor physicsFrameMonitor = GetMonitor <IPhysicsFrameMonitor>(); IPhysicsSyncFrameMonitor physicsSyncFrameMonitor = GetMonitor <IPhysicsSyncFrameMonitor>(); IPhysicsUpdateFrameMonitor physicsTimeFrameMonitor = GetMonitor <IPhysicsUpdateFrameMonitor>(); IAgentUpdateMonitor agentUpdateFrameMonitor = GetMonitor <IAgentUpdateMonitor>(); INetworkMonitor networkMonitor = GetMonitor <INetworkMonitor>(); IImageFrameTimeMonitor imagesMonitor = GetMonitor <IImageFrameTimeMonitor>(); IScriptFrameTimeMonitor scriptMonitor = GetMonitor <IScriptFrameTimeMonitor>(); IScriptCountMonitor totalScriptMonitor = GetMonitor <IScriptCountMonitor>(); #region various statistic googly moogly float simfps = simFrameMonitor.SimFPS / statsUpdateFactor; // save the reported value so there is something available for llGetRegionFPS simFrameMonitor.LastReportedSimFPS = simfps; float physfps = physicsFrameMonitor.PhysicsFPS / statsUpdateFactor; physicsFrameMonitor.LastReportedPhysicsFPS = physfps; //Update the time dilation with the newest physicsFPS timeDilationMonitor.SetPhysicsFPS(physfps); #endregion #region Add the stats packets //Some info on this packet http://wiki.secondlife.com/wiki/Statistics_Bar_Guide sb[0].StatID = (uint)Stats.TimeDilation; sb[0].StatValue = (float)timeDilationMonitor.GetValue(); sb[1].StatID = (uint)Stats.FPS; sb[1].StatValue = simfps; float realsimfps = simfps * 2; sb[2].StatID = (uint)Stats.PhysFPS; sb[2].StatValue = physfps; sb[3].StatID = (uint)Stats.AgentUpdates; sb[3].StatValue = (agentUpdateFrameMonitor.AgentUpdates / realsimfps); sb[4].StatID = (uint)Stats.FrameMS; float TotalFrames = (float)(totalFrameMonitor.GetValue() / realsimfps); sb[4].StatValue = TotalFrames; sb[5].StatID = (uint)Stats.NetMS; sb[5].StatValue = 0; //TODO: Implement this sb[6].StatID = (uint)Stats.SimOtherMS; float otherMS = (float)(otherFrameMonitor.GetValue() / realsimfps); sb[6].StatValue = otherMS; sb[7].StatID = (uint)Stats.SimPhysicsMS; float PhysicsMS = (float)(physicsTimeFrameMonitor.GetValue() / realsimfps); sb[7].StatValue = PhysicsMS; sb[8].StatID = (uint)Stats.AgentMS; sb[8].StatValue = (agentUpdateFrameMonitor.AgentFrameTime / realsimfps); sb[9].StatID = (uint)Stats.ImagesMS; float imageMS = (float)(imagesMonitor.GetValue() / realsimfps); sb[9].StatValue = imageMS; sb[10].StatID = (uint)Stats.ScriptMS; float ScriptMS = (float)(scriptMonitor.GetValue() / realsimfps); sb[10].StatValue = ScriptMS; sb[11].StatID = (uint)Stats.TotalObjects; sb[12].StatID = (uint)Stats.ActiveObjects; sb[13].StatID = (uint)Stats.NumAgentMain; sb[14].StatID = (uint)Stats.NumAgentChild; IEntityCountModule entityCountModule = m_currentScene.RequestModuleInterface <IEntityCountModule>(); if (entityCountModule != null) { sb[11].StatValue = entityCountModule.Objects; sb[12].StatValue = entityCountModule.ActiveObjects; sb[13].StatValue = entityCountModule.RootAgents; sb[14].StatValue = entityCountModule.ChildAgents; } sb[15].StatID = (uint)Stats.NumScriptActive; sb[15].StatValue = totalScriptMonitor.ActiveScripts; sb[16].StatID = (uint)Stats.LSLIPS; sb[16].StatValue = 0; //This isn't used anymore, and has been superseeded by LSLEPS sb[17].StatID = (uint)Stats.InPPS; sb[17].StatValue = (networkMonitor.InPacketsPerSecond / statsUpdateFactor); sb[18].StatID = (uint)Stats.OutPPS; sb[18].StatValue = (networkMonitor.OutPacketsPerSecond / statsUpdateFactor); sb[19].StatID = (uint)Stats.PendingDownloads; sb[19].StatValue = (networkMonitor.PendingDownloads); sb[20].StatID = (uint)Stats.PendingUploads; sb[20].StatValue = (networkMonitor.PendingUploads); //21 and 22 are forced to the GC memory as they WILL make memory usage go up rapidly otherwise! sb[21].StatID = (uint)Stats.VirtualSizeKB; sb[21].StatValue = GC.GetTotalMemory(false) / 1024; // System.Diagnostics.Process.GetCurrentProcess().WorkingSet64 / (1024); sb[22].StatID = (uint)Stats.ResidentSizeKB; sb[22].StatValue = GC.GetTotalMemory(false) / 1024; //(float)System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64 / (1024); sb[23].StatID = (uint)Stats.PendingLocalUploads; sb[23].StatValue = (networkMonitor.PendingUploads / statsUpdateFactor); sb[24].StatID = (uint)Stats.TotalUnackedBytes; sb[24].StatValue = (networkMonitor.UnackedBytes); sb[25].StatID = (uint)Stats.PhysicsPinnedTasks; sb[25].StatValue = 0; sb[26].StatID = (uint)Stats.PhysicsLODTasks; sb[26].StatValue = 0; sb[27].StatID = (uint)Stats.SimPhysicsStepMS; sb[27].StatValue = m_currentScene.PhysicsScene.StepTime; sb[28].StatID = (uint)Stats.SimPhysicsShape; sb[28].StatValue = 0; sb[29].StatID = (uint)Stats.SimPhysicsOtherMS; sb[29].StatValue = (float)(physicsSyncFrameMonitor.GetValue() / realsimfps); sb[30].StatID = (uint)Stats.SimPhysicsMemory; sb[30].StatValue = 0; sb[31].StatID = (uint)Stats.ScriptEPS; sb[31].StatValue = totalScriptMonitor.ScriptEPS / statsUpdateFactor; sb[32].StatID = (uint)Stats.SimSpareTime; //Spare time is the total time minus the stats that are in the same category in the client // It is the sleep time, physics step, update physics shape, physics other, and pumpI0. // Note: take out agent Update and script time for now, as they are not a part of the heartbeat right now and will mess this calc up float SpareTime = TotalFrames - ( /*NetMS + */ PhysicsMS + otherMS + imageMS); // + /*(agentUpdateFrameMonitor.AgentFrameTime / statsUpdateFactor) +*/ // (imagesMonitor.GetValue() / statsUpdateFactor) /* + ScriptMS*/)); sb[32].StatValue = SpareTime; sb[33].StatID = (uint)Stats.SimSleepTime; sb[33].StatValue = (float)(sleepFrameMonitor.GetValue() / realsimfps); sb[34].StatID = (uint)Stats.IOPumpTime; sb[34].StatValue = 0; //TODO: implement this #endregion for (int i = 0; i < sb.Length; i++) { if (float.IsInfinity(sb[i].StatValue) || float.IsNaN(sb[i].StatValue)) { sb[i].StatValue = 0; //Don't send huge values } lastReportedSimStats[i] = sb[i].StatValue; } SimStats simStats = new SimStats(rb, sb, m_currentScene.RegionInfo.RegionID); //Fire the event and tell followers about the new stats m_module.SendStatsResults(simStats); //Tell all the scene presences about the new stats foreach (IScenePresence agent in m_currentScene.GetScenePresences().Where(agent => !agent.IsChildAgent)) { agent.ControllingClient.SendSimStats(simStats); } //Now fix any values that require reseting ResetValues(); } m_report.Start(); }
private bool OnAllowedIncomingAgent(IScene scene, AgentCircuitData agent, bool isRootAgent, out string reason) { #region Incoming Agent Checks UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.AllScopeIDs, agent.AgentID); if (account == null) { reason = "No account exists"; return(false); } IScenePresence Sp = scene.GetScenePresence(agent.AgentID); if (LoginsDisabled) { reason = "Logins Disabled"; return(false); } //Check how long its been since the last TP if (m_enabledBlockTeleportSeconds && Sp != null && !Sp.IsChildAgent) { if (TimeSinceLastTeleport.ContainsKey(Sp.Scene.RegionInfo.RegionID)) { if (TimeSinceLastTeleport[Sp.Scene.RegionInfo.RegionID] > Util.UnixTimeSinceEpoch()) { reason = "Too many teleports. Please try again soon."; return(false); // Too soon since the last TP } } TimeSinceLastTeleport[Sp.Scene.RegionInfo.RegionID] = Util.UnixTimeSinceEpoch() + ((int)(SecondsBeforeNextTeleport)); } //Gods tp freely if ((Sp != null && Sp.GodLevel != 0) || (account != null && account.UserLevel != 0)) { reason = ""; return(true); } //Check whether they fit any ban criteria if (Sp != null) { foreach (string banstr in BanCriteria) { if (Sp.Name.Contains(banstr)) { reason = "You have been banned from this region."; return(false); } else if (((IPEndPoint)Sp.ControllingClient.GetClientEP()).Address.ToString().Contains(banstr)) { reason = "You have been banned from this region."; return(false); } } //Make sure they exist in the grid right now IAgentInfoService presence = scene.RequestModuleInterface <IAgentInfoService>(); if (presence == null) { reason = String.Format( "Failed to verify user presence in the grid for {0} in region {1}. Presence service does not exist.", account.Name, scene.RegionInfo.RegionName); return(false); } UserInfo pinfo = presence.GetUserInfo(agent.AgentID.ToString()); if (pinfo == null || (!pinfo.IsOnline && ((agent.TeleportFlags & (uint)TeleportFlags.ViaLogin) == 0))) { reason = String.Format( "Failed to verify user presence in the grid for {0}, access denied to region {1}.", account.Name, scene.RegionInfo.RegionName); return(false); } } EstateSettings ES = scene.RegionInfo.EstateSettings; IEntityCountModule entityCountModule = scene.RequestModuleInterface <IEntityCountModule>(); if (entityCountModule != null && scene.RegionInfo.RegionSettings.AgentLimit < entityCountModule.RootAgents + 1 && scene.RegionInfo.RegionSettings.AgentLimit > 0) { reason = "Too many agents at this time. Please come back later."; return(false); } List <EstateBan> EstateBans = new List <EstateBan>(ES.EstateBans); int i = 0; //Check bans foreach (EstateBan ban in EstateBans) { if (ban.BannedUserID == agent.AgentID) { if (Sp != null) { string banIP = ((IPEndPoint)Sp.ControllingClient.GetClientEP()).Address.ToString(); if (ban.BannedHostIPMask != banIP) //If it changed, ban them again { //Add the ban with the new hostname ES.AddBan(new EstateBan { BannedHostIPMask = banIP, BannedUserID = ban.BannedUserID, EstateID = ban.EstateID, BannedHostAddress = ban.BannedHostAddress, BannedHostNameMask = ban.BannedHostNameMask }); //Update the database ES.Save(); } } reason = "Banned from this region."; return(false); } if (Sp != null) { IPAddress end = Sp.ControllingClient.EndPoint; IPHostEntry rDNS = null; try { rDNS = Dns.GetHostEntry(end); } catch (SocketException) { MainConsole.Instance.WarnFormat("[IPBAN] IP address \"{0}\" cannot be resolved via DNS", end); rDNS = null; } if (ban.BannedHostIPMask == agent.IPAddress || (rDNS != null && rDNS.HostName.Contains(ban.BannedHostIPMask)) || end.ToString().StartsWith(ban.BannedHostIPMask)) { //Ban the new user ES.AddBan(new EstateBan { EstateID = ES.EstateID, BannedHostIPMask = agent.IPAddress, BannedUserID = agent.AgentID, BannedHostAddress = agent.IPAddress, BannedHostNameMask = agent.IPAddress }); ES.Save(); reason = "Banned from this region."; return(false); } } i++; } //Estate owners/managers/access list people/access groups tp freely as well if (ES.EstateOwner == agent.AgentID || new List <UUID>(ES.EstateManagers).Contains(agent.AgentID) || new List <UUID>(ES.EstateAccess).Contains(agent.AgentID) || CheckEstateGroups(ES, agent)) { reason = ""; return(true); } if (ES.DenyAnonymous && ((account.UserFlags & (int)IUserProfileInfo.ProfileFlags.NoPaymentInfoOnFile) == (int)IUserProfileInfo.ProfileFlags.NoPaymentInfoOnFile)) { reason = "You may not enter this region."; return(false); } if (ES.DenyIdentified && ((account.UserFlags & (int)IUserProfileInfo.ProfileFlags.PaymentInfoOnFile) == (int)IUserProfileInfo.ProfileFlags.PaymentInfoOnFile)) { reason = "You may not enter this region."; return(false); } if (ES.DenyTransacted && ((account.UserFlags & (int)IUserProfileInfo.ProfileFlags.PaymentInfoInUse) == (int)IUserProfileInfo.ProfileFlags.PaymentInfoInUse)) { reason = "You may not enter this region."; return(false); } const long m_Day = 25 * 60 * 60; //Find out day length in seconds if (scene.RegionInfo.RegionSettings.MinimumAge != 0 && (account.Created - Util.UnixTimeSinceEpoch()) < (scene.RegionInfo.RegionSettings.MinimumAge * m_Day)) { reason = "You may not enter this region."; return(false); } if (!ES.PublicAccess) { reason = "You may not enter this region, Public access has been turned off."; return(false); } IAgentConnector AgentConnector = Framework.Utilities.DataManager.RequestPlugin <IAgentConnector>(); IAgentInfo agentInfo = null; if (AgentConnector != null) { agentInfo = AgentConnector.GetAgent(agent.AgentID); if (agentInfo == null) { AgentConnector.CreateNewAgent(agent.AgentID); agentInfo = AgentConnector.GetAgent(agent.AgentID); } } if (m_checkMaturityLevel) { if (agentInfo != null && scene.RegionInfo.AccessLevel > Util.ConvertMaturityToAccessLevel((uint)agentInfo.MaturityRating)) { reason = "The region has too high of a maturity level. Blocking teleport."; return(false); } if (agentInfo != null && ES.DenyMinors && (agentInfo.Flags & IAgentFlags.Minor) == IAgentFlags.Minor) { reason = "The region has too high of a maturity level. Blocking teleport."; return(false); } } #endregion reason = ""; return(true); }
private List <SensedEntity> doAgentSensor(SenseRepeatClass ts) { List <SensedEntity> sensedEntities = new List <SensedEntity>(); // If nobody about quit fast IEntityCountModule entityCountModule = ts.host.ParentEntity.Scene.RequestModuleInterface <IEntityCountModule>(); if (entityCountModule != null && entityCountModule.RootAgents == 0) { return(sensedEntities); } ISceneChildEntity SensePoint = ts.host; Vector3 fromRegionPos = SensePoint.AbsolutePosition; Quaternion q = SensePoint.GetRotationOffset(); LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); bool attached = (SensePoint.AttachmentPoint != 0); Vector3 toRegionPos; double dis; Action <IScenePresence> senseEntity = delegate(IScenePresence presence) { if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) { return; } // if the object the script is in is attached and the avatar is the owner // then this one is not wanted if (attached && presence.UUID == SensePoint.OwnerID) { return; } toRegionPos = presence.AbsolutePosition; dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); // are they in range if (dis <= ts.range) { // Are they in the required angle of view if (ts.arc < Math.PI) { // not omni-directional. Can you see it ? // vec forward_dir = llRot2Fwd(llGetRot()) // vec obj_dir = toRegionPos-fromRegionPos // dot=dot(forward_dir,obj_dir) // mag_fwd = mag(forward_dir) // mag_obj = mag(obj_dir) // ang = acos(dot /(mag_fwd*mag_obj)) double ang_obj = 0; try { Vector3 diff = toRegionPos - fromRegionPos; LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); double mag_obj = LSL_Types.Vector3.Mag(obj_dir); ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); } catch { } if (ang_obj <= ts.arc) { sensedEntities.Add(new SensedEntity(dis, presence.UUID)); } } else { sensedEntities.Add(new SensedEntity(dis, presence.UUID)); } } }; // If this is an avatar sense by key try to get them directly // rather than getting a list to scan through if (ts.keyID != UUID.Zero) { IScenePresence sp; // Try direct lookup by UUID if (!ts.host.ParentEntity.Scene.TryGetScenePresence(ts.keyID, out sp)) { return(sensedEntities); } senseEntity(sp); } else if (!string.IsNullOrEmpty(ts.name)) { IScenePresence sp; // Try lookup by name will return if/when found if (!ts.host.ParentEntity.Scene.TryGetAvatarByName(ts.name, out sp)) { return(sensedEntities); } if (((ts.type & AGENT) != 0) && ts.host.ParentEntity.Scene.TryGetAvatarByName(ts.name, out sp)) { senseEntity(sp); } if ((ts.type & AGENT_BY_USERNAME) != 0) { ts.host.ParentEntity.Scene.ForEachScenePresence( delegate(IScenePresence ssp) { if (ssp.Name.Replace(" ", ".").ToLower() == ts.name) { senseEntity(ssp); } } ); } } else { ts.host.ParentEntity.Scene.ForEachScenePresence(senseEntity); } return(sensedEntities); }
public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { lock (m_rootAgents) { if (!m_rootAgents.Contains(remoteClient.AgentId)) { return; } } uint xstart = 0; uint ystart = 0; OpenMetaverse.Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out xstart, out ystart); List <mapItemReply> mapitems = new List <mapItemReply>(); int tc = Environment.TickCount; if (itemtype == (int)OpenMetaverse.GridItemType.AgentLocations) { //If its local, just let it do it on its own. if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) { //Only one person here, send a zero person response mapItemReply mapitem = new mapItemReply(); IEntityCountModule entityCountModule = m_scene.RequestModuleInterface <IEntityCountModule>(); if (entityCountModule != null && entityCountModule.RootAgents <= 1) { mapitem = new mapItemReply(); mapitem.x = (uint)(xstart + 1); mapitem.y = (uint)(ystart + 1); mapitem.id = UUID.Zero; mapitem.name = Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()); mapitem.Extra = 0; mapitem.Extra2 = 0; mapitems.Add(mapitem); remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); return; } m_scene.ForEachScenePresence(delegate(IScenePresence sp) { // Don't send a green dot for yourself if (!sp.IsChildAgent && sp.UUID != remoteClient.AgentId) { mapitem = new mapItemReply(); mapitem.x = (uint)(xstart + sp.AbsolutePosition.X); mapitem.y = (uint)(ystart + sp.AbsolutePosition.Y); mapitem.id = UUID.Zero; mapitem.name = Util.Md5Hash(m_scene.RegionInfo.RegionName + tc.ToString()); mapitem.Extra = 1; mapitem.Extra2 = 0; mapitems.Add(mapitem); } }); remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); } else { List <mapItemReply> reply; if (!m_mapItemCache.TryGetValue(regionhandle, out reply)) { m_itemsToRequest.Add(new MapItemRequester() { flags = flags, itemtype = itemtype, regionhandle = regionhandle, remoteClient = remoteClient }); if (!itemRequesterIsRunning) { threadpool.QueueEvent(GetMapItems, 3); } } else { remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, 0); } } } }